Changeset 220794 in webkit


Ignore:
Timestamp:
Aug 16, 2017 4:38:22 AM (7 years ago)
Author:
Carlos Garcia Campos
Message:

WebDriver: fix return value of close window command
https://bugs.webkit.org/show_bug.cgi?id=174861

Reviewed by Brian Burg.

We are currently returning null, but we should return the list of window handles, and try to close the session
if there aren't more window handles.

10.2 Close Window
https://w3c.github.io/webdriver/webdriver-spec.html#close-window

  1. If there are no more open top-level browsing contexts, then try to close the session.
  2. Return the result of running the remote end steps for the Get Window Handles command.
  • Session.cpp:

(WebDriver::Session::closeAllToplevelBrowsingContexts): Helper function to close the given toplevel browsing
context and the next one if there are more.
(WebDriver::Session::close): Call closeAllToplevelBrowsingContexts() to delete all toplevel browsing contexts of
the session.
(WebDriver::Session::closeTopLevelBrowsingContext): Close the given toplevel browsing context and call
getWindowHandles() when done.
(WebDriver::Session::closeWindow): Call closeTopLevelBrowsingContext() passing the current toplevel browsing context.
(WebDriver::Session::getWindowHandles): Remove the early return, this command doesn't depend on a current
toplevel browsing context.

  • Session.h:
  • SessionHost.h:
  • WebDriverService.cpp:

(WebDriver::WebDriverService::run): Disconnect the server when main loop quits.
(WebDriver::WebDriverService::deleteSession): Do not fail if the given session is not active.
(WebDriver::WebDriverService::closeWindow): Remove the session if the closed window was the last one.

  • WebDriverService.h: Remove unused quit() method.
  • glib/SessionHostGlib.cpp:

(WebDriver::SessionHost::isConnected): Return whether host is connected to a browser instance.
(WebDriver::SessionHost::dbusConnectionClosedCallback): Delete m_browser.

Location:
trunk/Source/WebDriver
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebDriver/ChangeLog

    r220740 r220794  
     12017-07-28  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        WebDriver: fix return value of close window command
     4        https://bugs.webkit.org/show_bug.cgi?id=174861
     5
     6        Reviewed by Brian Burg.
     7
     8        We are currently returning null, but we should return the list of window handles, and try to close the session
     9        if there aren't more window handles.
     10
     11        10.2 Close Window
     12        https://w3c.github.io/webdriver/webdriver-spec.html#close-window
     13
     14        3. If there are no more open top-level browsing contexts, then try to close the session.
     15        4. Return the result of running the remote end steps for the Get Window Handles command.
     16
     17        * Session.cpp:
     18        (WebDriver::Session::closeAllToplevelBrowsingContexts): Helper function to close the given toplevel browsing
     19        context and the next one if there are more.
     20        (WebDriver::Session::close): Call closeAllToplevelBrowsingContexts() to delete all toplevel browsing contexts of
     21        the session.
     22        (WebDriver::Session::closeTopLevelBrowsingContext): Close the given toplevel browsing context and call
     23        getWindowHandles() when done.
     24        (WebDriver::Session::closeWindow): Call closeTopLevelBrowsingContext() passing the current toplevel browsing context.
     25        (WebDriver::Session::getWindowHandles): Remove the early return, this command doesn't depend on a current
     26        toplevel browsing context.
     27        * Session.h:
     28        * SessionHost.h:
     29        * WebDriverService.cpp:
     30        (WebDriver::WebDriverService::run): Disconnect the server when main loop quits.
     31        (WebDriver::WebDriverService::deleteSession): Do not fail if the given session is not active.
     32        (WebDriver::WebDriverService::closeWindow): Remove the session if the closed window was the last one.
     33        * WebDriverService.h: Remove unused quit() method.
     34        * glib/SessionHostGlib.cpp:
     35        (WebDriver::SessionHost::isConnected): Return whether host is connected to a browser instance.
     36        (WebDriver::SessionHost::dbusConnectionClosedCallback): Delete m_browser.
     37
    1382017-08-14  Carlos Garcia Campos  <cgarcia@igalia.com>
    239
  • trunk/Source/WebDriver/Session.cpp

    r220740 r220794  
    5858}
    5959
     60void Session::closeAllToplevelBrowsingContexts(const String& toplevelBrowsingContext, Function<void (CommandResult&&)>&& completionHandler)
     61{
     62    closeTopLevelBrowsingContext(toplevelBrowsingContext, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
     63        if (result.isError()) {
     64            completionHandler(WTFMove(result));
     65            return;
     66        }
     67        RefPtr<InspectorArray> handles;
     68        if (result.result()->asArray(handles) && handles->length()) {
     69            auto handleValue = handles->get(0);
     70            String handle;
     71            if (handleValue->asString(handle)) {
     72                closeAllToplevelBrowsingContexts(handle, WTFMove(completionHandler));
     73                return;
     74            }
     75        }
     76        completionHandler(CommandResult::success());
     77    });
     78}
     79
    6080void Session::close(Function<void (CommandResult&&)>&& completionHandler)
    6181{
     
    6585    }
    6686
    67     RefPtr<InspectorObject> parameters = InspectorObject::create();
    68     parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
    69     m_host->sendCommandToBackend(ASCIILiteral("closeBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
    70         if (response.isError) {
    71             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
    72             return;
    73         }
    74         switchToTopLevelBrowsingContext(std::nullopt);
    75         completionHandler(CommandResult::success());
    76     });
     87    auto toplevelBrowsingContext = std::exchange(m_toplevelBrowsingContext, std::nullopt);
     88    closeAllToplevelBrowsingContexts(toplevelBrowsingContext.value(), WTFMove(completionHandler));
    7789}
    7890
     
    427439}
    428440
     441void Session::closeTopLevelBrowsingContext(const String& toplevelBrowsingContext, Function<void (CommandResult&&)>&& completionHandler)
     442{
     443    RefPtr<InspectorObject> parameters = InspectorObject::create();
     444    parameters->setString(ASCIILiteral("handle"), toplevelBrowsingContext);
     445    m_host->sendCommandToBackend(ASCIILiteral("closeBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
     446        if (!m_host->isConnected()) {
     447            // Closing the browsing context made the browser quit.
     448            completionHandler(CommandResult::success(InspectorArray::create()));
     449            return;
     450        }
     451        if (response.isError) {
     452            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
     453            return;
     454        }
     455
     456        getWindowHandles([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) {
     457            if (!m_host->isConnected()) {
     458                // Closing the browsing context made the browser quit.
     459                completionHandler(CommandResult::success(InspectorArray::create()));
     460                return;
     461            }
     462            completionHandler(WTFMove(result));
     463        });
     464    });
     465}
     466
    429467void Session::closeWindow(Function<void (CommandResult&&)>&& completionHandler)
    430468{
     
    439477            return;
    440478        }
    441         close(WTFMove(completionHandler));
     479        auto toplevelBrowsingContext = std::exchange(m_toplevelBrowsingContext, std::nullopt);
     480        closeTopLevelBrowsingContext(toplevelBrowsingContext.value(), WTFMove(completionHandler));
    442481    });
    443482}
     
    459498void Session::getWindowHandles(Function<void (CommandResult&&)>&& completionHandler)
    460499{
    461     if (!m_toplevelBrowsingContext) {
    462         completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
    463         return;
    464     }
    465 
    466500    m_host->sendCommandToBackend(ASCIILiteral("getBrowsingContexts"), InspectorObject::create(), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
    467501        if (response.isError || !response.responseObject) {
  • trunk/Source/WebDriver/Session.h

    r220740 r220794  
    105105    void switchToTopLevelBrowsingContext(std::optional<String>);
    106106    void switchToBrowsingContext(std::optional<String>);
     107    void closeTopLevelBrowsingContext(const String& toplevelBrowsingContext, Function<void (CommandResult&&)>&&);
     108    void closeAllToplevelBrowsingContexts(const String& toplevelBrowsingContext, Function<void (CommandResult&&)>&&);
    107109
    108110    std::optional<String> pageLoadStrategyString() const;
  • trunk/Source/WebDriver/SessionHost.cpp

    r219605 r220794  
    3636void SessionHost::inspectorDisconnected()
    3737{
    38     if (!m_closeMessageID)
    39         return;
    40 
    41     // Closing the browsing context made the browser quit.
    42     auto responseHandler = m_commandRequests.take(m_closeMessageID);
    43     m_closeMessageID = 0;
    44     responseHandler({ });
     38    // Browser closed or crashed, finish all pending commands with error.
     39    Vector<long> messages;
     40    copyKeysToVector(m_commandRequests, messages);
     41    for (auto messageID : messages) {
     42        auto responseHandler = m_commandRequests.take(messageID);
     43        responseHandler({ nullptr, true });
     44    }
    4545}
    4646
     
    5050    long sequenceID = ++lastSequenceID;
    5151    m_commandRequests.add(sequenceID, WTFMove(responseHandler));
    52     if (command == "closeBrowsingContext")
    53         m_closeMessageID = sequenceID;
    5452    StringBuilder messageBuilder;
    5553    messageBuilder.appendLiteral("{\"id\":");
     
    8280        return;
    8381
    84     if (m_closeMessageID == sequenceID)
    85         m_closeMessageID = 0;
    86 
    8782    auto responseHandler = m_commandRequests.take(sequenceID);
    8883    ASSERT(responseHandler);
  • trunk/Source/WebDriver/SessionHost.h

    r220329 r220794  
    5353    ~SessionHost();
    5454
     55    bool isConnected() const;
     56
    5557    const Capabilities& capabilities() const { return m_capabilities; }
    5658
     
    9395
    9496    HashMap<long, Function<void (CommandResponse&&)>> m_commandRequests;
    95     long m_closeMessageID { 0 };
    9697
    9798#if USE(GLIB)
  • trunk/Source/WebDriver/WebDriverService.cpp

    r220403 r220794  
    9696    RunLoop::run();
    9797
     98    m_server.disconnect();
     99
    98100    return EXIT_SUCCESS;
    99 }
    100 
    101 void WebDriverService::quit()
    102 {
    103     m_server.disconnect();
    104     RunLoop::main().stop();
    105101}
    106102
     
    638634    auto session = m_sessions.take(sessionID);
    639635    if (!session) {
    640         completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidSessionID));
    641         return;
    642     }
    643 
    644     if (m_activeSession == session.get())
    645         m_activeSession = nullptr;
    646 
    647     session->close(WTFMove(completionHandler));
     636        completionHandler(CommandResult::success());
     637        return;
     638    }
     639
     640    session->close([this, session, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
     641        if (m_activeSession == session.get())
     642            m_activeSession = nullptr;
     643        completionHandler(WTFMove(result));
     644    });
    648645}
    649646
     
    839836    // §10.2 Close Window.
    840837    // https://www.w3.org/TR/webdriver/#close-window
    841     if (auto session = findSessionOrCompleteWithError(*parameters, completionHandler))
    842         session->closeWindow(WTFMove(completionHandler));
     838    auto session = findSessionOrCompleteWithError(*parameters, completionHandler);
     839    if (!session)
     840        return;
     841
     842    session->closeWindow([this, session, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
     843        if (result.isError()) {
     844            completionHandler(WTFMove(result));
     845            return;
     846        }
     847
     848        RefPtr<InspectorArray> handles;
     849        if (result.result()->asArray(handles) && !handles->length()) {
     850            m_sessions.remove(session->id());
     851            if (m_activeSession == session.get())
     852                m_activeSession = nullptr;
     853        }
     854        completionHandler(WTFMove(result));
     855    });
    843856}
    844857
  • trunk/Source/WebDriver/WebDriverService.h

    r220584 r220794  
    4949
    5050    int run(int argc, char** argv);
    51     void quit();
    5251
    5352    static bool platformCompareBrowserVersions(const String&, const String&);
  • trunk/Source/WebDriver/glib/SessionHostGlib.cpp

    r220425 r220794  
    104104}
    105105
     106bool SessionHost::isConnected() const
     107{
     108    return !!m_browser;
     109}
     110
    106111struct ConnectToBrowserAsyncData {
    107112    ConnectToBrowserAsyncData(SessionHost* sessionHost, GUniquePtr<char>&& dbusAddress, GCancellable* cancellable, Function<void (SessionHost::Succeeded)>&& completionHandler)
     
    196201void SessionHost::dbusConnectionClosedCallback(SessionHost* sessionHost)
    197202{
     203    sessionHost->m_browser = nullptr;
    198204    sessionHost->inspectorDisconnected();
    199205}
Note: See TracChangeset for help on using the changeset viewer.