Changeset 198913 in webkit


Ignore:
Timestamp:
Mar 31, 2016, 1:52:38 PM (9 years ago)
Author:
timothy@apple.com
Message:

Web Automation: Add support for script timeouts to the evaluateJavaScriptFunction command

https://bugs.webkit.org/show_bug.cgi?id=156052
rdar://problem/25457151

Reviewed by Brian Burg.

  • UIProcess/Automation/Automation.json: Added callbackTimeout to evaluateJavaScriptFunction.

Also made expectsImplicitCallbackArgument optional, since it is not required. Added JavaScriptTimeout error.

  • UIProcess/Automation/WebAutomationSession.cpp:

(WebKit::WebAutomationSession::evaluateJavaScriptFunction): Added callbackTimeout.

  • UIProcess/Automation/WebAutomationSession.h:
  • WebProcess/Automation/WebAutomationSessionProxy.cpp:

(WebKit::evaluateJavaScriptCallback): Send JavaScriptTimeout error if the timeout fired.
(WebKit::WebAutomationSessionProxy::evaluateJavaScriptFunction): Added callbackTimeout.

  • WebProcess/Automation/WebAutomationSessionProxy.h:
  • WebProcess/Automation/WebAutomationSessionProxy.js:

(AutomationSessionProxy.prototype.evaluateJavaScriptFunction): Set a timeout to fire if the
callback is not called, then return an error.

  • WebProcess/Automation/WebAutomationSessionProxy.messages.in:

(EvaluateJavaScriptFunction): Added callbackTimeout parameter.

Location:
trunk/Source/WebKit2
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r198911 r198913  
     12016-03-30  Timothy Hatcher  <timothy@apple.com>
     2
     3        Web Automation: Add support for script timeouts to the evaluateJavaScriptFunction command
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=156052
     6        rdar://problem/25457151
     7
     8        Reviewed by Brian Burg.
     9
     10        * UIProcess/Automation/Automation.json: Added callbackTimeout to evaluateJavaScriptFunction.
     11        Also made expectsImplicitCallbackArgument optional, since it is not required. Added JavaScriptTimeout error.
     12        * UIProcess/Automation/WebAutomationSession.cpp:
     13        (WebKit::WebAutomationSession::evaluateJavaScriptFunction): Added callbackTimeout.
     14        * UIProcess/Automation/WebAutomationSession.h:
     15        * WebProcess/Automation/WebAutomationSessionProxy.cpp:
     16        (WebKit::evaluateJavaScriptCallback): Send JavaScriptTimeout error if the timeout fired.
     17        (WebKit::WebAutomationSessionProxy::evaluateJavaScriptFunction): Added callbackTimeout.
     18        * WebProcess/Automation/WebAutomationSessionProxy.h:
     19        * WebProcess/Automation/WebAutomationSessionProxy.js:
     20        (AutomationSessionProxy.prototype.evaluateJavaScriptFunction): Set a timeout to fire if the
     21        callback is not called, then return an error.
     22        * WebProcess/Automation/WebAutomationSessionProxy.messages.in:
     23        (EvaluateJavaScriptFunction): Added callbackTimeout parameter.
     24
    1252016-03-31  Jiewen Tan  <jiewen_tan@apple.com>
    226
  • trunk/Source/WebKit2/UIProcess/Automation/Automation.json

    r198907 r198913  
    4949                "InternalError",
    5050                "JavaScriptError",
     51                "JavaScriptTimeout",
    5152                "WindowNotFound",
    5253                "FrameNotFound",
     
    281282                { "name": "function", "type": "string", "description": "The script to evaluate in the browsing context. It must be a function result." },
    282283                { "name": "arguments", "type": "array", "items": { "type": "string" }, "description": "The arguments to pass to the function when called. They will be parsed as JSON before calling the function." },
    283                 { "name": "expectsImplicitCallbackArgument", "type": "boolean", "description": "The function expects a callback function as the last argument. It is expected to call this callback with a result." }
     284                { "name": "expectsImplicitCallbackArgument", "type": "boolean", "optional": true, "description": "The function expects a callback function as the last argument. It is expected to call this callback with a result." },
     285                { "name": "callbackTimeout", "type": "integer", "optional": true, "description": "The timeout in milliseconds that the implicit callback is expected to be called in, otherwise a <code>JavaScriptTimeout</code> error is returned." }
    284286            ],
    285287            "returns": [
  • trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp

    r198907 r198913  
    396396}
    397397
    398 void WebAutomationSession::evaluateJavaScriptFunction(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, bool expectsImplicitCallbackArgument, Ref<EvaluateJavaScriptFunctionCallback>&& callback)
     398void WebAutomationSession::evaluateJavaScriptFunction(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<EvaluateJavaScriptFunctionCallback>&& callback)
    399399{
    400400    WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
     
    415415    }
    416416
     417    bool expectsImplicitCallbackArgument = optionalExpectsImplicitCallbackArgument ? *optionalExpectsImplicitCallbackArgument : false;
     418    int callbackTimeout = optionalCallbackTimeout ? *optionalCallbackTimeout : 0;
     419
    417420    uint64_t callbackID = m_nextEvaluateJavaScriptCallbackID++;
    418421    m_evaluateJavaScriptFunctionCallbacks.set(callbackID, WTFMove(callback));
    419422
    420     page->process().send(Messages::WebAutomationSessionProxy::EvaluateJavaScriptFunction(frame->frameID(), function, argumentsVector, expectsImplicitCallbackArgument, callbackID), 0);
     423    page->process().send(Messages::WebAutomationSessionProxy::EvaluateJavaScriptFunction(frame->frameID(), function, argumentsVector, expectsImplicitCallbackArgument, callbackTimeout, callbackID), 0);
    421424}
    422425
  • trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h

    r198907 r198913  
    104104    void goForwardInBrowsingContext(Inspector::ErrorString&, const String&) override;
    105105    void reloadBrowsingContext(Inspector::ErrorString&, const String&) override;
    106     void evaluateJavaScriptFunction(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, bool expectsImplicitCallbackArgument, Ref<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>&&) override;
     106    void evaluateJavaScriptFunction(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>&&) override;
    107107    void performMouseInteraction(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& requestedPosition, const String& mouseButton, const String& mouseInteraction, const Inspector::InspectorArray& keyModifiers, RefPtr<Inspector::Protocol::Automation::Point>& updatedPosition) override;
    108108    void performKeyboardInteractions(Inspector::ErrorString&, const String& handle, const Inspector::InspectorArray& interactions) override;
  • trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp

    r198907 r198913  
    127127static JSValueRef evaluateJavaScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    128128{
    129     ASSERT_ARG(argumentCount, argumentCount == 3);
     129    ASSERT_ARG(argumentCount, argumentCount == 4);
    130130    ASSERT_ARG(arguments, JSValueIsNumber(context, arguments[0]));
    131131    ASSERT_ARG(arguments, JSValueIsNumber(context, arguments[1]));
    132132    ASSERT_ARG(arguments, JSValueIsString(context, arguments[2]));
     133    ASSERT_ARG(arguments, JSValueIsBoolean(context, arguments[3]));
    133134
    134135    auto automationSessionProxy = WebProcess::singleton().automationSessionProxy();
     
    140141    JSRetainPtr<JSStringRef> result(Adopt, JSValueToStringCopy(context, arguments[2], exception));
    141142
    142     automationSessionProxy->didEvaluateJavaScriptFunction(frameID, callbackID, result->string(), String());
     143    bool resultIsErrorName = JSValueToBoolean(context, arguments[3]);
     144
     145    if (resultIsErrorName) {
     146        if (result->string() == "JavaScriptTimeout") {
     147            String errorType = Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::JavaScriptTimeout);
     148            automationSessionProxy->didEvaluateJavaScriptFunction(frameID, callbackID, String(), errorType);
     149        } else {
     150            ASSERT_NOT_REACHED();
     151            String errorType = Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::InternalError);
     152            automationSessionProxy->didEvaluateJavaScriptFunction(frameID, callbackID, String(), errorType);
     153        }
     154    } else
     155        automationSessionProxy->didEvaluateJavaScriptFunction(frameID, callbackID, result->string(), String());
    143156
    144157    return JSValueMakeUndefined(context);
     
    213226}
    214227
    215 void WebAutomationSessionProxy::evaluateJavaScriptFunction(uint64_t frameID, const String& function, Vector<String> arguments, bool expectsImplicitCallbackArgument, uint64_t callbackID)
     228void WebAutomationSessionProxy::evaluateJavaScriptFunction(uint64_t frameID, const String& function, Vector<String> arguments, bool expectsImplicitCallbackArgument, int callbackTimeout, uint64_t callbackID)
    216229{
    217230    WebFrame* frame = WebProcess::singleton().webFrame(frameID);
     
    225238    JSValueRef exception = nullptr;
    226239    JSGlobalContextRef context = frame->jsContext();
    227 
    228     JSObjectRef callbackFunction = JSObjectMakeFunctionWithCallback(context, nullptr, evaluateJavaScriptCallback);
    229240
    230241    if (expectsImplicitCallbackArgument) {
     
    239250        JSValueMakeNumber(context, frameID),
    240251        JSValueMakeNumber(context, callbackID),
    241         callbackFunction
     252        JSObjectMakeFunctionWithCallback(context, nullptr, evaluateJavaScriptCallback),
     253        JSValueMakeNumber(context, callbackTimeout)
    242254    };
    243255
  • trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h

    r198907 r198913  
    5959
    6060    // Called by WebAutomationSessionProxy messages
    61     void evaluateJavaScriptFunction(uint64_t frameID, const String& function, Vector<String> arguments, bool expectsImplicitCallbackArgument, uint64_t callbackID);
     61    void evaluateJavaScriptFunction(uint64_t frameID, const String& function, Vector<String> arguments, bool expectsImplicitCallbackArgument, int callbackTimeout, uint64_t callbackID);
    6262    void resolveChildFrameWithOrdinal(uint64_t frameID, uint32_t ordinal, uint64_t callbackID);
    6363    void resolveChildFrameWithNodeHandle(uint64_t frameID, const String& nodeHandle, uint64_t callbackID);
  • trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.js

    r198906 r198913  
    4040    // Public
    4141
    42     evaluateJavaScriptFunction(functionString, argumentStrings, expectsImplicitCallbackArgument, frameID, callbackID, resultCallback)
     42    evaluateJavaScriptFunction(functionString, argumentStrings, expectsImplicitCallbackArgument, frameID, callbackID, resultCallback, callbackTimeout)
    4343    {
    4444        // The script is expected to be a function declaration. Evaluate it inside parenthesis to get the function value.
     
    4848
    4949        let argumentValues = argumentStrings.map(this._jsonParse, this);
    50         let callback = (result) => resultCallback(frameID, callbackID, this._jsonStringify(result));
     50
     51        let timeoutIdentifier = 0;
     52
     53        let reportResult = (result) => { clearTimeout(timeoutIdentifier); resultCallback(frameID, callbackID, this._jsonStringify(result), false); }
     54        let reportTimeoutError = () => { clearTimeout(timeoutIdentifier); resultCallback(frameID, callbackID, "JavaScriptTimeout", true); }
    5155
    5256        if (expectsImplicitCallbackArgument) {
    53             argumentValues.push(callback);
     57            timeoutIdentifier = setTimeout(reportTimeoutError, callbackTimeout);
     58
     59            argumentValues.push(reportResult);
    5460            functionValue.apply(null, argumentValues);
    5561        } else
    56             callback(functionValue.apply(null, argumentValues));
     62            reportResult(functionValue.apply(null, argumentValues));
    5763    }
    5864
  • trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in

    r198907 r198913  
    2222
    2323messages -> WebAutomationSessionProxy {
    24     EvaluateJavaScriptFunction(uint64_t frameID, String function, Vector<String> arguments, bool expectsImplicitCallbackArgument, uint64_t callbackID)
     24    EvaluateJavaScriptFunction(uint64_t frameID, String function, Vector<String> arguments, bool expectsImplicitCallbackArgument, int callbackTimeout, uint64_t callbackID)
    2525
    2626    ResolveChildFrameWithOrdinal(uint64_t frameID, uint32_t ordinal, uint64_t callbackID)
Note: See TracChangeset for help on using the changeset viewer.