Changeset 228856 in webkit


Ignore:
Timestamp:
Feb 20, 2018 8:13:42 PM (6 years ago)
Author:
BJ Burg
Message:

Web Automation: combine session commands to resize and move top-level browsing contexts
https://bugs.webkit.org/show_bug.cgi?id=182749
<rdar://problem/37515170>

Reviewed by Andy Estes.

Source/WebDriver:

The new command can take either size or origin. Just have one session command for use by endpoints.

  • Session.cpp:

(WebDriver::Session::setWindowRect):
(WebDriver::Session::moveToplevelBrowsingContextWindow): Deleted.
(WebDriver::Session::resizeToplevelBrowsingContextWindow): Deleted.

  • Session.h:

Source/WebKit:

Since moving and resizing the window are both accomplished by setting the window frame,
and the W3C WebDriver specification has a Get/Set Window Rect command, it's time to
deduplicate these two methods which basically do the same thing.

Adopt modern JSON::Value getters that return std::optional<float>. I have been trying
to move the protocol over to this style wholesale, but it is probably easier to do
this conversion in smaller pieces. And so, I have started to do so.

This change is covered by existing WebDriver tests.

  • UIProcess/Automation/Automation.json: Add new command.
  • UIProcess/Automation/WebAutomationSession.cpp:

(WebKit::WebAutomationSession::setWindowFrameOfBrowsingContext): Added.
(WebKit::WebAutomationSession::resizeWindowOfBrowsingContext): Deleted.
(WebKit::WebAutomationSession::moveWindowOfBrowsingContext): Deleted.

  • UIProcess/Automation/WebAutomationSession.h:

Source/WTF:

  • wtf/JSONValues.h: add a getDouble() implementation that returns a std::optional<T>

rather than using an out-parameter. I'd like to move more code to this style.

Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r228853 r228856  
     12018-02-14  Brian Burg  <bburg@apple.com>
     2
     3        Web Automation: combine session commands to resize and move top-level browsing contexts
     4        https://bugs.webkit.org/show_bug.cgi?id=182749
     5        <rdar://problem/37515170>
     6
     7        Reviewed by Andy Estes.
     8
     9        * wtf/JSONValues.h: add a getDouble() implementation that returns a std::optional<T>
     10        rather than using an out-parameter. I'd like to move more code to this style.
     11
    1122018-02-20  Tim Horton  <timothy_horton@apple.com>
    213
  • trunk/Source/WTF/wtf/JSONValues.h

    r225425 r228856  
    218218    }
    219219
     220    template<class T> std::optional<T> getNumber(const String& name) const
     221    {
     222        RefPtr<Value> value;
     223        if (!getValue(name, value))
     224            return std::nullopt;
     225
     226        T result;
     227        if (!value->asDouble(result))
     228            return std::nullopt;
     229
     230        return result;
     231    }
     232
    220233    bool getString(const String& name, String& output) const;
    221234    bool getObject(const String& name, RefPtr<Object>&) const;
     
    261274    using ObjectBase::getInteger;
    262275    using ObjectBase::getDouble;
     276    using ObjectBase::getNumber;
    263277    using ObjectBase::getString;
    264278    using ObjectBase::getObject;
     
    473487using namespace WTF::JSONImpl;
    474488}
     489
  • trunk/Source/WebDriver/ChangeLog

    r227845 r228856  
     12018-02-14  Brian Burg  <bburg@apple.com>
     2
     3        Web Automation: combine session commands to resize and move top-level browsing contexts
     4        https://bugs.webkit.org/show_bug.cgi?id=182749
     5        <rdar://problem/37515170>
     6
     7        Reviewed by Andy Estes.
     8
     9        The new command can take either size or origin. Just have one session command for use by endpoints.
     10
     11        * Session.cpp:
     12        (WebDriver::Session::setWindowRect):
     13        (WebDriver::Session::moveToplevelBrowsingContextWindow): Deleted.
     14        (WebDriver::Session::resizeToplevelBrowsingContextWindow): Deleted.
     15        * Session.h:
     16
    1172018-01-30  Don Olmstead  <don.olmstead@sony.com>
    218
  • trunk/Source/WebDriver/Session.cpp

    r227773 r228856  
    716716}
    717717
    718 void Session::moveToplevelBrowsingContextWindow(double x, double y, Function<void (CommandResult&&)>&& completionHandler)
    719 {
    720     RefPtr<JSON::Object> parameters = JSON::Object::create();
    721     parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
    722     RefPtr<JSON::Object> windowOrigin = JSON::Object::create();
    723     windowOrigin->setDouble("x", x);
    724     windowOrigin->setDouble("y", y);
    725     parameters->setObject(ASCIILiteral("origin"), WTFMove(windowOrigin));
    726     m_host->sendCommandToBackend(ASCIILiteral("moveWindowOfBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
    727         if (response.isError) {
    728             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
    729             return;
    730         }
    731         completionHandler(CommandResult::success());
    732     });
    733 }
    734 
    735 void Session::resizeToplevelBrowsingContextWindow(double width, double height, Function<void (CommandResult&&)>&& completionHandler)
    736 {
    737     RefPtr<JSON::Object> parameters = JSON::Object::create();
    738     parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
    739     RefPtr<JSON::Object> windowSize = JSON::Object::create();
    740     windowSize->setDouble("width", width);
    741     windowSize->setDouble("height", height);
    742     parameters->setObject(ASCIILiteral("size"), WTFMove(windowSize));
    743     m_host->sendCommandToBackend(ASCIILiteral("resizeWindowOfBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
    744         if (response.isError) {
    745             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
    746             return;
    747         }
    748         completionHandler(CommandResult::success());
    749     });
    750 }
    751 
    752718void Session::getWindowRect(Function<void (CommandResult&&)>&& completionHandler)
    753719{
     
    779745        }
    780746
    781         if (width && height)  {
    782             resizeToplevelBrowsingContextWindow(width.value(), height.value(), [this, x, y, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
    783                 if (result.isError()) {
    784                     completionHandler(WTFMove(result));
    785                     return;
    786                 }
    787                 if (!x || !y) {
    788                     getToplevelBrowsingContextRect(WTFMove(completionHandler));
    789                     return;
    790                 }
    791 
    792                 moveToplevelBrowsingContextWindow(x.value(), y.value(), [this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
    793                     if (result.isError()) {
    794                         completionHandler(WTFMove(result));
    795                         return;
    796                     }
    797                     getToplevelBrowsingContextRect(WTFMove(completionHandler));
    798                 });
    799             });
    800             return;
    801         }
    802 
     747        RefPtr<JSON::Object> parameters = JSON::Object::create();
     748        parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
    803749        if (x && y) {
    804             moveToplevelBrowsingContextWindow(x.value(), y.value(), [this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
    805                 if (result.isError()) {
    806                     completionHandler(WTFMove(result));
    807                     return;
    808                 }
    809                 getToplevelBrowsingContextRect(WTFMove(completionHandler));
    810             });
    811             return;
    812         }
    813 
    814         getToplevelBrowsingContextRect(WTFMove(completionHandler));
     750            RefPtr<JSON::Object> windowOrigin = JSON::Object::create();
     751            windowOrigin->setDouble("x", x.value());
     752            windowOrigin->setDouble("y", y.value());
     753            parameters->setObject(ASCIILiteral("origin"), WTFMove(windowOrigin));
     754        }
     755        if (width && height) {
     756            RefPtr<JSON::Object> windowSize = JSON::Object::create();
     757            windowSize->setDouble("width", width.value());
     758            windowSize->setDouble("height", height.value());
     759            parameters->setObject(ASCIILiteral("size"), WTFMove(windowSize));
     760        }
     761        m_host->sendCommandToBackend(ASCIILiteral("setWindowFrameOfBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (SessionHost::CommandResponse&& response) mutable {
     762            if (response.isError) {
     763                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
     764                return;
     765            }
     766            getToplevelBrowsingContextRect(WTFMove(completionHandler));
     767        });
    815768    });
    816769}
  • trunk/Source/WebDriver/Session.h

    r227674 r228856  
    122122
    123123    void getToplevelBrowsingContextRect(Function<void (CommandResult&&)>&&);
    124     void moveToplevelBrowsingContextWindow(double x, double y, Function<void (CommandResult&&)>&&);
    125     void resizeToplevelBrowsingContextWindow(double width, double height, Function<void (CommandResult&&)>&&);
    126124
    127125    std::optional<String> pageLoadStrategyString() const;
  • trunk/Source/WebKit/ChangeLog

    r228854 r228856  
     12018-02-14  Brian Burg  <bburg@apple.com>
     2
     3        Web Automation: combine session commands to resize and move top-level browsing contexts
     4        https://bugs.webkit.org/show_bug.cgi?id=182749
     5        <rdar://problem/37515170>
     6
     7        Reviewed by Andy Estes.
     8
     9        Since moving and resizing the window are both accomplished by setting the window frame,
     10        and the W3C WebDriver specification has a Get/Set Window Rect command, it's time to
     11        deduplicate these two methods which basically do the same thing.
     12
     13        Adopt modern JSON::Value getters that return std::optional<float>. I have been trying
     14        to move the protocol over to this style wholesale, but it is probably easier to do
     15        this conversion in smaller pieces. And so, I have started to do so.
     16
     17        This change is covered by existing WebDriver tests.
     18
     19        * UIProcess/Automation/Automation.json: Add new command.
     20        * UIProcess/Automation/WebAutomationSession.cpp:
     21        (WebKit::WebAutomationSession::setWindowFrameOfBrowsingContext): Added.
     22        (WebKit::WebAutomationSession::resizeWindowOfBrowsingContext): Deleted.
     23        (WebKit::WebAutomationSession::moveWindowOfBrowsingContext): Deleted.
     24        * UIProcess/Automation/WebAutomationSession.h:
     25
    1262018-02-20  Brian Burg  <bburg@apple.com>
    227
  • trunk/Source/WebKit/UIProcess/Automation/Automation.json

    r225501 r228856  
    290290        },
    291291        {
    292             "name": "resizeWindowOfBrowsingContext",
    293             "description": "Resizes the window of the specified browsing context to the specified size.",
     292            "name": "setWindowFrameOfBrowsingContext",
     293            "description": "Moves and/or resizes the window of the specified top-level browsing context to the specified size and origin. Both the size and origin may be omitted. Regardless of the arguments, this command will exit fullscreen and deminiaturize the window if applicable.",
    294294            "parameters": [
    295295                { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context to be resized." },
    296                 { "name": "size", "$ref": "Size", "description": "The new size for the browsing context's window." }
    297             ],
    298             "async": true
    299         },
    300         {
    301             "name": "moveWindowOfBrowsingContext",
    302             "description": "Moves the window of the specified browsing context to the specified position.",
    303             "parameters": [
    304                 { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context to be moved." },
    305                 { "name": "origin", "$ref": "Point", "description": "The new origin for the browsing context's window. The position is interpreted in screen coordinate space, relative to the upper left corner of the screen." }
     296                { "name": "origin", "$ref": "Point", "optional": true, "description": "The new origin for the browsing context's window. The position is interpreted in screen coordinate space, relative to the upper left corner of the screen." },
     297                { "name": "size", "$ref": "Size", "optional": true, "description": "The new size for the browsing context's window. The size is interpreted in screen pixels." }
    306298            ],
    307299            "async": true
  • trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp

    r228854 r228856  
    314314}
    315315
    316 void WebAutomationSession::resizeWindowOfBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const JSON::Object& sizeObject, Ref<ResizeWindowOfBrowsingContextCallback>&& callback)
     316void WebAutomationSession::setWindowFrameOfBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const JSON::Object* optionalOriginObject, const JSON::Object* optionalSizeObject, Ref<SetWindowFrameOfBrowsingContextCallback>&& callback)
    317317{
    318318#if PLATFORM(IOS)
    319319    FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
    320320#else
    321     float width;
    322     if (!sizeObject.getDouble(WTF::ASCIILiteral("width"), width))
    323         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'width' parameter was not found or invalid.");
    324 
    325     float height;
    326     if (!sizeObject.getDouble(WTF::ASCIILiteral("height"), height))
    327         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'height' parameter was not found or invalid.");
    328 
    329     if (width < 0)
    330         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'width' parameter had an invalid value.");
    331 
    332     if (height < 0)
    333         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'height' parameter had an invalid value.");
     321    std::optional<float> x;
     322    std::optional<float> y;
     323    if (optionalOriginObject) {
     324        if (!(x = optionalOriginObject->getNumber<float>(WTF::ASCIILiteral("x"))))
     325            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'x' parameter was not found or invalid.");
     326
     327        if (!(y = optionalOriginObject->getNumber<float>(WTF::ASCIILiteral("y"))))
     328            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'y' parameter was not found or invalid.");
     329
     330        if (x.value() < 0)
     331            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'x' parameter had an invalid value.");
     332
     333        if (y.value() < 0)
     334            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'y' parameter had an invalid value.");
     335    }
     336
     337    std::optional<float> width;
     338    std::optional<float> height;
     339    if (optionalSizeObject) {
     340        if (!(width = optionalSizeObject->getNumber<float>(WTF::ASCIILiteral("width"))))
     341            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'width' parameter was not found or invalid.");
     342
     343        if (!(height = optionalSizeObject->getNumber<float>(WTF::ASCIILiteral("height"))))
     344            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'height' parameter was not found or invalid.");
     345
     346        if (width.value() < 0)
     347            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'width' parameter had an invalid value.");
     348
     349        if (height.value() < 0)
     350            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'height' parameter had an invalid value.");
     351    }
    334352
    335353    WebPageProxy* page = webPageProxyForHandle(handle);
     
    337355        FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
    338356
    339     page->getWindowFrameWithCallback([callback = WTFMove(callback), page = makeRef(*page), width, height](WebCore::FloatRect originalFrame) mutable {
    340         WebCore::FloatRect newFrame = WebCore::FloatRect(originalFrame.location(), WebCore::FloatSize(width, height));
    341         if (newFrame == originalFrame)
    342             return callback->sendSuccess();
    343 
    344         page->setWindowFrame(newFrame);
    345         callback->sendSuccess();
    346     });
    347 #endif
    348 }
    349 
    350 void WebAutomationSession::moveWindowOfBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const JSON::Object& positionObject, Ref<MoveWindowOfBrowsingContextCallback>&& callback)
    351 {
    352 #if PLATFORM(IOS)
    353     FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
    354 #else
    355     float x;
    356     if (!positionObject.getDouble(WTF::ASCIILiteral("x"), x))
    357         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'x' parameter was not found or invalid.");
    358 
    359     float y;
    360     if (!positionObject.getDouble(WTF::ASCIILiteral("y"), y))
    361         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The 'y' parameter was not found or invalid.");
    362 
    363     if (x < 0)
    364         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'x' parameter had an invalid value.");
    365 
    366     if (y < 0)
    367         FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The 'y' parameter had an invalid value.");
    368 
    369     WebPageProxy* page = webPageProxyForHandle(handle);
    370     if (!page)
    371         FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
    372 
    373     WebCore::FloatRect originalFrame;
    374     page->getWindowFrameWithCallback([callback = WTFMove(callback), page = makeRef(*page), x, y](WebCore::FloatRect originalFrame) mutable {
    375 
    376         WebCore::FloatRect newFrame = WebCore::FloatRect(WebCore::FloatPoint(x, y), originalFrame.size());
     357    // FIXME (§10.7.2 Step 10): We need to exit fullscreen before setting the frame.
     358    // FIXME (§10.7.2 Step 11): We need to de-miniaturize the window before setting the frame.
     359
     360    page->getWindowFrameWithCallback([callback = WTFMove(callback), page = makeRef(*page), width, height, x, y](WebCore::FloatRect originalFrame) mutable {
     361        WebCore::FloatRect newFrame = WebCore::FloatRect(WebCore::FloatPoint(x.value_or(originalFrame.location().x()), y.value_or(originalFrame.location().y())), WebCore::FloatSize(width.value_or(originalFrame.size().width()), height.value_or(originalFrame.size().height())));
    377362        if (newFrame == originalFrame)
    378363            return callback->sendSuccess();
  • trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h

    r225501 r228856  
    123123    void closeBrowsingContext(Inspector::ErrorString&, const String&) override;
    124124    void switchToBrowsingContext(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle) override;
    125     void resizeWindowOfBrowsingContext(Inspector::ErrorString&, const String& handle, const JSON::Object& size, Ref<ResizeWindowOfBrowsingContextCallback>&&) final;
    126     void moveWindowOfBrowsingContext(Inspector::ErrorString&, const String& handle, const JSON::Object& position, Ref<MoveWindowOfBrowsingContextCallback>&&) final;
     125    void setWindowFrameOfBrowsingContext(Inspector::ErrorString&, const String& handle, const JSON::Object* origin, const JSON::Object* size, Ref<SetWindowFrameOfBrowsingContextCallback>&&) final;
    127126    void navigateBrowsingContext(Inspector::ErrorString&, const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&&) override;
    128127    void goBackInBrowsingContext(Inspector::ErrorString&, const String&, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&&) override;
Note: See TracChangeset for help on using the changeset viewer.