- Revision
- 225448
- Author
- [email protected]
- Date
- 2017-12-02 07:13:29 -0800 (Sat, 02 Dec 2017)
Log Message
WebDriver: handle user prompts shown while executing scripts
https://bugs.webkit.org/show_bug.cgi?id=179979
Reviewed by Brian Burg.
Source/WebDriver:
15.2 Executing Script
https://w3c.github.io/webdriver/webdriver-spec.html#executing-script
The rules to execute a function body are as follows. The algorithm will return success with the JSON
representation of the function’s return value, or an error if the evaluation of the function results in a
_javascript_ exception being thrown or at any point during its execution an unhandled user prompt appears.
If at any point during the algorithm a user prompt appears, the user prompt handler must be invoked. If its
return value is an error, it must immediately return with that error and abort all subsequent substeps of this
algorithm.
This will be covered by new WPT tests that will be available after the next upgrade.
* CommandResult.cpp:
(WebDriver::CommandResult::CommandResult): Handle UnexpectedAlertOpen internal error.
* Session.cpp:
(WebDriver::Session::handleUserPrompts): Move code to handleUnexpectedAlertOpen() and call it instead.
(WebDriver::Session::handleUnexpectedAlertOpen): Code moved here to be used also by executeScript().
(WebDriver::Session::executeScript): In case of UnexpectedAlertOpen error, call handleUnexpectedAlertOpen().
* Session.h:
Source/WebKit:
* UIProcess/Automation/Automation.json: Add UnexpectedAlertOpen error.
* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::willShowJavaScriptDialog): Finish pending evaluateJavaScriptFunction operations
with UnexpectedAlertOpen error.
Modified Paths
Diff
Modified: trunk/Source/WebDriver/ChangeLog (225447 => 225448)
--- trunk/Source/WebDriver/ChangeLog 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebDriver/ChangeLog 2017-12-02 15:13:29 UTC (rev 225448)
@@ -1,3 +1,31 @@
+2017-12-02 Carlos Garcia Campos <[email protected]>
+
+ WebDriver: handle user prompts shown while executing scripts
+ https://bugs.webkit.org/show_bug.cgi?id=179979
+
+ Reviewed by Brian Burg.
+
+ 15.2 Executing Script
+ https://w3c.github.io/webdriver/webdriver-spec.html#executing-script
+
+ The rules to execute a function body are as follows. The algorithm will return success with the JSON
+ representation of the function’s return value, or an error if the evaluation of the function results in a
+ _javascript_ exception being thrown or at any point during its execution an unhandled user prompt appears.
+
+ If at any point during the algorithm a user prompt appears, the user prompt handler must be invoked. If its
+ return value is an error, it must immediately return with that error and abort all subsequent substeps of this
+ algorithm.
+
+ This will be covered by new WPT tests that will be available after the next upgrade.
+
+ * CommandResult.cpp:
+ (WebDriver::CommandResult::CommandResult): Handle UnexpectedAlertOpen internal error.
+ * Session.cpp:
+ (WebDriver::Session::handleUserPrompts): Move code to handleUnexpectedAlertOpen() and call it instead.
+ (WebDriver::Session::handleUnexpectedAlertOpen): Code moved here to be used also by executeScript().
+ (WebDriver::Session::executeScript): In case of UnexpectedAlertOpen error, call handleUnexpectedAlertOpen().
+ * Session.h:
+
2017-12-01 Carlos Garcia Campos <[email protected]>
WebDriver: implement status command
Modified: trunk/Source/WebDriver/CommandResult.cpp (225447 => 225448)
--- trunk/Source/WebDriver/CommandResult.cpp 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebDriver/CommandResult.cpp 2017-12-02 15:13:29 UTC (rev 225448)
@@ -106,6 +106,8 @@
m_errorCode = ErrorCode::ElementNotSelectable;
else if (errorName == "ScreenshotError")
m_errorCode = ErrorCode::UnableToCaptureScreen;
+ else if (errorName == "UnexpectedAlertOpen")
+ m_errorCode = ErrorCode::UnexpectedAlertOpen;
break;
}
Modified: trunk/Source/WebDriver/Session.cpp (225447 => 225448)
--- trunk/Source/WebDriver/Session.cpp 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebDriver/Session.cpp 2017-12-02 15:13:29 UTC (rev 225448)
@@ -184,31 +184,36 @@
return;
}
- if (!capabilities().unhandledPromptBehavior) {
- reportUnexpectedAlertOpen([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
- dismissAlert([this, errorResult = WTFMove(result), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
- if (result.isError()) {
- completionHandler(WTFMove(result));
- return;
- }
- completionHandler(WTFMove(errorResult));
- });
+ handleUnexpectedAlertOpen(WTFMove(completionHandler));
+ });
+}
+
+void Session::handleUnexpectedAlertOpen(Function<void (CommandResult&&)>&& completionHandler)
+{
+ if (!capabilities().unhandledPromptBehavior) {
+ reportUnexpectedAlertOpen([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
+ dismissAlert([this, errorResult = WTFMove(result), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
+ if (result.isError()) {
+ completionHandler(WTFMove(result));
+ return;
+ }
+ completionHandler(WTFMove(errorResult));
});
- return;
- }
+ });
+ return;
+ }
- switch (capabilities().unhandledPromptBehavior.value()) {
- case UnhandledPromptBehavior::Dismiss:
- dismissAlert(WTFMove(completionHandler));
- break;
- case UnhandledPromptBehavior::Accept:
- acceptAlert(WTFMove(completionHandler));
- break;
- case UnhandledPromptBehavior::Ignore:
- reportUnexpectedAlertOpen(WTFMove(completionHandler));
- break;
- }
- });
+ switch (capabilities().unhandledPromptBehavior.value()) {
+ case UnhandledPromptBehavior::Dismiss:
+ dismissAlert(WTFMove(completionHandler));
+ break;
+ case UnhandledPromptBehavior::Accept:
+ acceptAlert(WTFMove(completionHandler));
+ break;
+ case UnhandledPromptBehavior::Ignore:
+ reportUnexpectedAlertOpen(WTFMove(completionHandler));
+ break;
+ }
}
void Session::reportUnexpectedAlertOpen(Function<void (CommandResult&&)>&& completionHandler)
@@ -1663,9 +1668,13 @@
if (m_timeouts.script)
parameters->setInteger(ASCIILiteral("callbackTimeout"), m_timeouts.script.value().millisecondsAs<int>());
}
- m_host->sendCommandToBackend(ASCIILiteral("evaluateJavaScriptFunction"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
+ m_host->sendCommandToBackend(ASCIILiteral("evaluateJavaScriptFunction"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
if (response.isError || !response.responseObject) {
- completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
+ auto result = CommandResult::fail(WTFMove(response.responseObject));
+ if (result.errorCode() == CommandResult::ErrorCode::UnexpectedAlertOpen)
+ handleUnexpectedAlertOpen(WTFMove(completionHandler));
+ else
+ completionHandler(WTFMove(result));
return;
}
String valueString;
Modified: trunk/Source/WebDriver/Session.h (225447 => 225448)
--- trunk/Source/WebDriver/Session.h 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebDriver/Session.h 2017-12-02 15:13:29 UTC (rev 225448)
@@ -122,6 +122,7 @@
std::optional<String> pageLoadStrategyString() const;
void handleUserPrompts(Function<void (CommandResult&&)>&&);
+ void handleUnexpectedAlertOpen(Function<void (CommandResult&&)>&&);
void reportUnexpectedAlertOpen(Function<void (CommandResult&&)>&&);
RefPtr<JSON::Object> createElement(RefPtr<JSON::Value>&&);
Modified: trunk/Source/WebKit/ChangeLog (225447 => 225448)
--- trunk/Source/WebKit/ChangeLog 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebKit/ChangeLog 2017-12-02 15:13:29 UTC (rev 225448)
@@ -1,3 +1,15 @@
+2017-12-02 Carlos Garcia Campos <[email protected]>
+
+ WebDriver: handle user prompts shown while executing scripts
+ https://bugs.webkit.org/show_bug.cgi?id=179979
+
+ Reviewed by Brian Burg.
+
+ * UIProcess/Automation/Automation.json: Add UnexpectedAlertOpen error.
+ * UIProcess/Automation/WebAutomationSession.cpp:
+ (WebKit::WebAutomationSession::willShowJavaScriptDialog): Finish pending evaluateJavaScriptFunction operations
+ with UnexpectedAlertOpen error.
+
2017-12-02 Wenson Hsieh <[email protected]>
Make some minor adjustments to TouchBarMenuData and TouchBarMenuItemData
Modified: trunk/Source/WebKit/UIProcess/Automation/Automation.json (225447 => 225448)
--- trunk/Source/WebKit/UIProcess/Automation/Automation.json 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebKit/UIProcess/Automation/Automation.json 2017-12-02 15:13:29 UTC (rev 225448)
@@ -71,7 +71,8 @@
"InvalidSelector",
"ElementNotInteractable",
"ElementNotSelectable",
- "ScreenshotError"
+ "ScreenshotError",
+ "UnexpectedAlertOpen"
]
},
{
Modified: trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp (225447 => 225448)
--- trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp 2017-12-02 14:56:26 UTC (rev 225447)
+++ trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp 2017-12-02 15:13:29 UTC (rev 225448)
@@ -551,14 +551,26 @@
void WebAutomationSession::willShowJavaScriptDialog(WebPageProxy& page)
{
// Wait until the next run loop iteration to give time for the client to show the dialog,
- // then check if page is loading and the dialog is still present. The dialog will block the
- // load in case of normal strategy, so we want to dispatch all pending navigation callbacks.
+ // then check if the dialog is still present. If the page is loading, the dialog will block
+ // the load in case of normal strategy, so we want to dispatch all pending navigation callbacks.
+ // If the dialog was shown during a script execution, we want to finish the evaluateJavaScriptFunction
+ // operation with an unexpected alert open error.
RunLoop::main().dispatch([this, protectedThis = makeRef(*this), page = makeRef(page)] {
- if (!page->isValid() || !page->pageLoadState().isLoading() || !m_client || !m_client->isShowingJavaScriptDialogOnPage(*this, page))
+ if (!page->isValid() || !m_client || !m_client->isShowingJavaScriptDialogOnPage(*this, page))
return;
- respondToPendingFrameNavigationCallbacksWithTimeout(m_pendingNormalNavigationInBrowsingContextCallbacksPerFrame);
- respondToPendingPageNavigationCallbacksWithTimeout(m_pendingNormalNavigationInBrowsingContextCallbacksPerPage);
+ if (page->pageLoadState().isLoading()) {
+ respondToPendingFrameNavigationCallbacksWithTimeout(m_pendingNormalNavigationInBrowsingContextCallbacksPerFrame);
+ respondToPendingPageNavigationCallbacksWithTimeout(m_pendingNormalNavigationInBrowsingContextCallbacksPerPage);
+ }
+
+ if (!m_evaluateJavaScriptFunctionCallbacks.isEmpty()) {
+ Inspector::ErrorString unexpectedAlertOpenError = STRING_FOR_PREDEFINED_ERROR_NAME(UnexpectedAlertOpen);
+ for (auto key : m_evaluateJavaScriptFunctionCallbacks.keys()) {
+ auto callback = m_evaluateJavaScriptFunctionCallbacks.take(key);
+ callback->sendFailure(unexpectedAlertOpenError);
+ }
+ }
});
}