]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html.ini
deleted file mode 100644
index 178680e5d14..00000000000
--- a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[script-onerror-insertion-point-2.html]
- expected: TIMEOUT
diff --git a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini
index 69bd952d756..910c88d3e81 100644
--- a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini
+++ b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini
@@ -1,5 +1,5 @@
[ignore-opens-during-unload.window.html]
- expected: TIMEOUT
+ expected: CRASH
[ignore-opens-during-unload]
expected: FAIL
diff --git a/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini b/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini
index 01f7b72cbe7..0cef5158fae 100644
--- a/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini
+++ b/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini
@@ -4,6 +4,3 @@
[The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT
- [The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
index a1effd5f801..5ddb9bfeff6 100644
--- a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
+++ b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
@@ -1,9 +1,10 @@
[promise-job-entry.html]
+ expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
- expected: FAIL
+ expected: TIMEOUT
[Sanity check: this all works as expected with no promises involved]
expected: FAIL
@@ -15,5 +16,5 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini b/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini
index bfd4d6dd2d6..bf2a1d61bab 100644
--- a/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini
+++ b/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini
@@ -1,5 +1,4 @@
[import-in-moduleworker.html]
- expected: ERROR
[Base URL in module dedicated workers: import]
expected: FAIL
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-001.html b/tests/wpt/web-platform-tests/css/css-color/predefined-001.html
new file mode 100644
index 00000000000..65cf808556b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-001.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, srgb, decimal values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-002.html b/tests/wpt/web-platform-tests/css/css-color/predefined-002.html
new file mode 100644
index 00000000000..4e125f96b57
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-002.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, srgb, percent values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-003.html b/tests/wpt/web-platform-tests/css/css-color/predefined-003.html
new file mode 100644
index 00000000000..1d014cb0483
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-003.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, default srgb, decimal values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-004.html b/tests/wpt/web-platform-tests/css/css-color/predefined-004.html
new file mode 100644
index 00000000000..f1bf6ddea30
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-004.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, default srgb, percent values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-005.html b/tests/wpt/web-platform-tests/css/css-color/predefined-005.html
new file mode 100644
index 00000000000..780b929d856
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-005.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, display-p3, decimal values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-006.html b/tests/wpt/web-platform-tests/css/css-color/predefined-006.html
new file mode 100644
index 00000000000..f53fb79a021
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-006.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, display-p3, percent values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-007.html b/tests/wpt/web-platform-tests/css/css-color/predefined-007.html
new file mode 100644
index 00000000000..d6797931827
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-007.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, a98-rgb, decimal values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-008.html b/tests/wpt/web-platform-tests/css/css-color/predefined-008.html
new file mode 100644
index 00000000000..57bbe3a51e7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-008.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, a98-rgb, percent values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-009.html b/tests/wpt/web-platform-tests/css/css-color/predefined-009.html
new file mode 100644
index 00000000000..e29305ec981
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-009.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, prophoto-rgb, decimal values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-010.html b/tests/wpt/web-platform-tests/css/css-color/predefined-010.html
new file mode 100644
index 00000000000..a0eb9952e1e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-010.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, prophoto-rgb, percent values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-011.html b/tests/wpt/web-platform-tests/css/css-color/predefined-011.html
new file mode 100644
index 00000000000..37a16f1b9f2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-011.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, rec2020, decimal values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-012.html b/tests/wpt/web-platform-tests/css/css-color/predefined-012.html
new file mode 100644
index 00000000000..a4ead241969
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-012.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, rec2020, percent values
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-013.html b/tests/wpt/web-platform-tests/css/css-color/predefined-013.html
new file mode 100644
index 00000000000..ed4a48f90b0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-013.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, lab
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-014.html b/tests/wpt/web-platform-tests/css/css-color/predefined-014.html
new file mode 100644
index 00000000000..51f72650bd7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-014.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, fallback
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-015.html b/tests/wpt/web-platform-tests/css/css-color/predefined-015.html
new file mode 100644
index 00000000000..27641397fa4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-015.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, fallback
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-016.html b/tests/wpt/web-platform-tests/css/css-color/predefined-016.html
new file mode 100644
index 00000000000..7b7c653010c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-016.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, lab
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-color/predefined-017.html b/tests/wpt/web-platform-tests/css/css-color/predefined-017.html
new file mode 100644
index 00000000000..ee1ebb6711f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-color/predefined-017.html
@@ -0,0 +1,17 @@
+
+
+CSS Color 4: predefined colorspaces, lab
+
+
+
+
+
+
+ Test passes if you see a green square, and no red.
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-overflow/overflow-clip-hit-testing.html b/tests/wpt/web-platform-tests/css/css-overflow/overflow-clip-hit-testing.html
new file mode 100644
index 00000000000..b22497601c2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-overflow/overflow-clip-hit-testing.html
@@ -0,0 +1,50 @@
+
+
+Overflow: clip hit testing doesn't include overflow: clip
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/docs/writing-tests/testdriver.md b/tests/wpt/web-platform-tests/docs/writing-tests/testdriver.md
index 8eec38729f4..fd87f355bc3 100644
--- a/tests/wpt/web-platform-tests/docs/writing-tests/testdriver.md
+++ b/tests/wpt/web-platform-tests/docs/writing-tests/testdriver.md
@@ -13,9 +13,6 @@ tests.
testdriver.js exposes its API through the `test_driver` variable in
the global scope.
-NB: presently, testdriver.js only works in the top-level test browsing
-context (and not therefore in any frame or window opened from it).
-
### Actions
Usage:
```
@@ -25,12 +22,17 @@ let actions = new test_driver.Actions()
actions.send()
```
-Test authors are encouraged to use the builder API to generate the sequence of actions. The builder
-API can be accessed via the `new test_driver.Actions()` object, and actions are defined in [testdriver-actions.js](https://github.com/web-platform-tests/wpt/blob/master/resources/testdriver-actions.js)
+Test authors are encouraged to use the builder API to generate the
+sequence of actions. The builder API can be accessed via the `new
+test_driver.Actions()` object, and actions are defined in
+[testdriver-actions.js](https://github.com/web-platform-tests/wpt/blob/master/resources/testdriver-actions.js)
-The `actions.send()` function causes the sequence of actions to be sent to the browser. It is based on the [WebDriver API](https://w3c.github.io/webdriver/#actions).
-The action can be a keyboard action, a pointer action or a pause. It returns a promise that
-resolves after the actions have been sent, or rejects if an error was thrown.
+The `actions.send()` function causes the sequence of actions to be
+sent to the browser. It is based on the [WebDriver
+API](https://w3c.github.io/webdriver/#actions). The action can be a
+keyboard action, a pointer action or a pause. It returns a promise
+that resolves after the actions have been sent, or rejects if an error
+was thrown.
Example:
@@ -49,7 +51,13 @@ let actions = new test_driver.Actions()
actions.send();
```
-Calling into `send()` is going to dispatch the action sequence (via `test_driver.action_sequence`) and also returns a promise which should be handled however is appropriate in the test. The other functions in the `Actions()` object are going to modify the state of the object by adding a new action in the sequence and returning the same object. So the functions can be easily chained, as shown in the example above. Here is a list of helper functions in the `Actions` class:
+Calling into `send()` is going to dispatch the action sequence (via
+`test_driver.action_sequence`) and also returns a promise which should
+be handled however is appropriate in the test. The other functions in
+the `Actions()` object are going to modify the state of the object by
+adding a new action in the sequence and returning the same object. So
+the functions can be easily chained, as shown in the example
+above. Here is a list of helper functions in the `Actions` class:
```
pointerDown: Create a pointerDown event for the current default pointer source
@@ -143,7 +151,7 @@ For example, to send the tab key you would send "\uE004".
### set_permission
-Usage: `test_driver.set_permission(descriptor, state, one_realm)`
+Usage: `test_driver.set_permission(descriptor, state, one_realm, context=null)`
* _descriptor_: a
[PermissionDescriptor](https://w3c.github.io/permissions/#dictdef-permissiondescriptor)
or derived object
@@ -152,6 +160,7 @@ Usage: `test_driver.set_permission(descriptor, state, one_realm)`
value
* _one_realm_: a boolean that indicates whether the permission settings
apply to only one realm
+ * context: a WindowProxy for the browsing context in which to perform the call
This function causes permission requests and queries for the status of a
certain permission type (e.g. "push", or "background-fetch") to always
@@ -164,3 +173,63 @@ Example:
await test_driver.set_permission({ name: "background-fetch" }, "denied");
await test_driver.set_permission({ name: "push", userVisibleOnly: true }, "granted", true);
```
+
+## Using testdriver in Other Browsing Contexts
+
+Testdriver can be used in browsing contexts (i.e. windows or frames)
+from which it's possible to get a reference to the top-level test
+context. There are two basic approaches depending on whether the
+context in which testdriver is used is same-origin with the test
+context, or different origin.
+
+For same-origin contexts, the context can be passed directly into the
+testdriver API calls. For functions that take an element argument this
+is done implicitly using the owner document of the element. For
+functions that don't take an element, this is done via an explicit
+context argument, which takes a WindowProxy object.
+
+Example:
+```
+let win = window.open("example.html")
+win.onload = () => {
+ await test_driver.set_permission({ name: "background-fetch" }, "denied", win);
+}
+```
+
+For the actions API, the context can be set using the `setContext`
+method on the builder:
+
+```
+let actions = new test_driver.Actions()
+ .setContext(frames[0])
+ .keyDown("p")
+ .keyUp("p");
+actions.send();
+```
+
+Note that if an action uses an element reference, the context will be
+derived from that element, and must match any explictly set
+context. Using elements in multiple contexts in a single action chain
+is not supported.
+
+
+For cross-origin cases, passing in the context id doesn't work because
+of limitations in the WebDriver protocol used to implement testdriver
+in a cross-browser fashion. Instead one may include the testdriver
+scripts directly in the relevant document, and use the
+`set_test_context` API to specify the browsing context containing
+testharness.js. Commands are then sent via postMessage to the test
+context. For convenience there is also a `message_test` function that
+can be used to send arbitary messages to the test window. For example,
+in an auxillary browsing context:
+
+
+```
+testdriver.set_test_context(window.opener)
+await testdriver.click(document.getElementsByTagName("button")[0])
+testdriver.message_test("click complete")
+```
+
+The requirement to have a handle to the test window does mean it's
+currently not possible to write tests where such handles can't be
+obtained e.g. in the case of `rel=noopener`.
diff --git a/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-blockification.html b/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-blockification.html
new file mode 100644
index 00000000000..cc94e92fe0c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-blockification.html
@@ -0,0 +1,35 @@
+
+
+CSS Test: details children blockification
+
+
+
+
+
+
+
+
+ foo
+ bar
+
+
+
+
+
+ foo
+ bar
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini b/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini
deleted file mode 100644
index b9465c066c7..00000000000
--- a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[actionsWithKeyPressed.html]
- expected:
- if product == "safari" or product == "epiphany" or product == "webkit": ERROR
diff --git a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/crossOrigin.sub.html.ini b/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/crossOrigin.sub.html.ini
new file mode 100644
index 00000000000..8cb7d29239b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/crossOrigin.sub.html.ini
@@ -0,0 +1,4 @@
+[crossOrigin.sub.html]
+ [Actions in cross-origin iframe]
+ expected:
+ if product == "safari": FAIL
diff --git a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini b/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini
deleted file mode 100644
index baf2116bad6..00000000000
--- a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[multiDevice.html]
- expected:
- if product == "safari" or product == "epiphany" or product == "webkit": ERROR
diff --git a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/penPointerEventProperties.html.ini b/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/penPointerEventProperties.html.ini
index 9a107f0f02d..648585f9e6d 100644
--- a/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/penPointerEventProperties.html.ini
+++ b/tests/wpt/web-platform-tests/infrastructure/metadata/infrastructure/testdriver/actions/penPointerEventProperties.html.ini
@@ -1,3 +1,6 @@
[penPointerEventProperties.html]
expected:
if product == "firefox": ERROR
+ [TestDriver actions: pointerevent properties of pen type]
+ expected:
+ if product == "safari": FAIL
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/crossOrigin.sub.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/crossOrigin.sub.html
new file mode 100644
index 00000000000..38b3610af65
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/crossOrigin.sub.html
@@ -0,0 +1,20 @@
+
+
+Actions in cross-origin iframe
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/crossOriginChild.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/crossOriginChild.html
new file mode 100644
index 00000000000..48e37e233e1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/crossOriginChild.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/iframe.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/iframe.html
new file mode 100644
index 00000000000..6c64d6f49ab
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/iframe.html
@@ -0,0 +1,35 @@
+
+
+TestDriver actions on a document in an iframe
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/iframeChild.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/iframeChild.html
new file mode 100644
index 00000000000..a46c54a7b7b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/actions/iframeChild.html
@@ -0,0 +1,2 @@
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/bless.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/bless.html
index b8a1c2e7d60..12257df01b7 100644
--- a/tests/wpt/web-platform-tests/infrastructure/testdriver/bless.html
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/bless.html
@@ -43,7 +43,7 @@ promise_test(t => {
promise_test(() => {
return test_driver.bless('demonstrates return value without action')
.then((value) => {
- assert_equals(value, undefined);
+ assert_equals(value, null);
});
}, 'no action function provided');
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/click_child_crossorigin.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_child_crossorigin.html
new file mode 100644
index 00000000000..6a8c6840a25
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_child_crossorigin.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+FAIL
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/click_child_testdriver.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_child_testdriver.html
new file mode 100644
index 00000000000..2c26a963f4a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_child_testdriver.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+FAIL
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/click_iframe_crossorigin.sub.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_iframe_crossorigin.sub.html
new file mode 100644
index 00000000000..01833dc23d4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_iframe_crossorigin.sub.html
@@ -0,0 +1,20 @@
+
+
+TestDriver click on a document in an iframe
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/click_nested_crossorigin.sub.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_nested_crossorigin.sub.html
new file mode 100644
index 00000000000..af90951df17
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_nested_crossorigin.sub.html
@@ -0,0 +1,25 @@
+
+
+TestDriver click method with multiple windows and nested iframe
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/infrastructure/testdriver/click_outer_child.sub.html b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_outer_child.sub.html
new file mode 100644
index 00000000000..8e72223f915
--- /dev/null
+++ b/tests/wpt/web-platform-tests/infrastructure/testdriver/click_outer_child.sub.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/interfaces/badging.idl b/tests/wpt/web-platform-tests/interfaces/badging.idl
index 0b011a92f00..28578621c9a 100644
--- a/tests/wpt/web-platform-tests/interfaces/badging.idl
+++ b/tests/wpt/web-platform-tests/interfaces/badging.idl
@@ -6,15 +6,15 @@
// Methods only exposed on documents.
[SecureContext]
partial interface Navigator {
- Promise setClientBadge(optional [EnforceRange] unsigned long long contents);
- Promise clearClientBadge();
+ Promise setClientBadge(optional [EnforceRange] unsigned long long contents);
+ Promise clearClientBadge();
};
// Methods exposed on both documents and service workers.
[SecureContext]
interface mixin NavigatorBadge {
- Promise setAppBadge(optional [EnforceRange] unsigned long long contents);
- Promise clearAppBadge();
+ Promise setAppBadge(optional [EnforceRange] unsigned long long contents);
+ Promise clearAppBadge();
};
Navigator includes NavigatorBadge;
diff --git a/tests/wpt/web-platform-tests/resources/testdriver-actions.js b/tests/wpt/web-platform-tests/resources/testdriver-actions.js
index b6030bf1213..f3e6388e8ac 100644
--- a/tests/wpt/web-platform-tests/resources/testdriver-actions.js
+++ b/tests/wpt/web-platform-tests/resources/testdriver-actions.js
@@ -23,6 +23,7 @@
this.createSource("none");
this.tickIdx = 0;
this.defaultTickDuration = defaultTickDuration;
+ this.context = null;
}
Actions.prototype = {
@@ -66,7 +67,17 @@
} catch(e) {
return Promise.reject(e);
}
- return test_driver.action_sequence(actions);
+ return test_driver.action_sequence(actions, this.context);
+ },
+
+ /**
+ * Set the context for the actions
+ *
+ * @param {WindowProxy} context - Context in which to run the action sequence
+ */
+ setContext: function(context) {
+ this.context = context;
+ return this;
},
/**
diff --git a/tests/wpt/web-platform-tests/resources/testdriver.js b/tests/wpt/web-platform-tests/resources/testdriver.js
index 165147d1430..c53b24136c0 100644
--- a/tests/wpt/web-platform-tests/resources/testdriver.js
+++ b/tests/wpt/web-platform-tests/resources/testdriver.js
@@ -1,6 +1,7 @@
(function() {
"use strict";
var idCounter = 0;
+ let testharness_context = null;
function getInViewCenterPoint(rect) {
var left = Math.max(0, rect.left);
@@ -48,6 +49,31 @@
* @namespace
*/
window.test_driver = {
+ /**
+ * Set the context in which testharness.js is loaded
+ *
+ * @param {WindowProxy} context - the window containing testharness.js
+ **/
+ set_test_context: function(context) {
+ if (window.test_driver_internal.set_test_context) {
+ window.test_driver_internal.set_test_context(context);
+ }
+ testharness_context = context;
+ },
+
+ /**
+ * postMessage to the context containing testharness.js
+ *
+ * @param {Object} msg - the data to POST
+ **/
+ message_test: function(msg) {
+ let target = testharness_context;
+ if (testharness_context === null) {
+ target = window;
+ }
+ target.postMessage(msg, "*");
+ },
+
/**
* Trigger user interaction in order to grant additional privileges to
* a provided function.
@@ -57,30 +83,35 @@
* @param {String} intent - a description of the action which much be
* triggered by user interaction
* @param {Function} action - code requiring escalated privileges
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} fulfilled following user interaction and
* execution of the provided `action` function;
* rejected if interaction fails or the provided
* function throws an error
*/
- bless: function(intent, action) {
- var button = document.createElement("button");
+ bless: function(intent, action, context=null) {
+ let contextDocument = context ? context.document : document;
+ var button = contextDocument.createElement("button");
button.innerHTML = "This test requires user interaction.
" +
"Please click here to allow " + intent + ".";
button.id = "wpt-test-driver-bless-" + (idCounter += 1);
- const elem = document.body || document.documentElement;
+ const elem = contextDocument.body || contextDocument.documentElement;
elem.appendChild(button);
- return new Promise(function(resolve, reject) {
- button.addEventListener("click", resolve);
+ let wait_click = new Promise(resolve => button.addEventListener("click", resolve));
- test_driver.click(button).catch(reject);
- }).then(function() {
+ return test_driver.click(button)
+ .then(wait_click)
+ .then(function() {
button.remove();
if (typeof action === "function") {
return action();
}
+ return null;
});
},
@@ -151,10 +182,14 @@
* https://github.com/WICG/page-lifecycle/blob/master/README.md|Lifecycle API
* for Web Pages}
*
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
+ *
* @returns {Promise} fulfilled after the freeze request is sent, or rejected
* in case the WebDriver command errors
*/
- freeze: function() {
+ freeze: function(context=null) {
return window.test_driver_internal.freeze();
},
@@ -166,19 +201,23 @@
* https://w3c.github.io/webdriver/#actions|WebDriver Actions Command}
*
* @param {Array} actions - an array of actions. The format is the same as the actions
- property of the WebDriver command {@link
- https://w3c.github.io/webdriver/#perform-actions|Perform
- Actions} command. Each element is an object representing an
- input source and each input source itself has an actions
- property detailing the behaviour of that source at each timestep
- (or tick). Authors are not expected to construct the actions
- sequence by hand, but to use the builder api provided in
- testdriver-actions.js
+ * property of the WebDriver command {@link
+ * https://w3c.github.io/webdriver/#perform-actions|Perform
+ * Actions} command. Each element is an object representing an
+ * input source and each input source itself has an actions
+ * property detailing the behaviour of that source at each timestep
+ * (or tick). Authors are not expected to construct the actions
+ * sequence by hand, but to use the builder api provided in
+ * testdriver-actions.js
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
+ *
* @returns {Promise} fufiled after the actions are performed, or rejected in
* the cases the WebDriver command errors
*/
- action_sequence: function(actions) {
- return window.test_driver_internal.action_sequence(actions);
+ action_sequence: function(actions, context=null) {
+ return window.test_driver_internal.action_sequence(actions, context);
},
/**
@@ -188,11 +227,15 @@
* by ReportingObserver) for testing purposes, as described in
* {@link https://w3c.github.io/reporting/#generate-test-report-command}
*
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
+ *
* @returns {Promise} fulfilled after the report is generated, or
* rejected if the report generation fails
*/
- generate_test_report: function(message) {
- return window.test_driver_internal.generate_test_report(message);
+ generate_test_report: function(message, context=null) {
+ return window.test_driver_internal.generate_test_report(message, context);
},
/**
@@ -206,6 +249,9 @@
* object
* @param {String} state - the state of the permission
* @param {boolean} one_realm - Optional. Whether the permission applies to only one realm
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* The above params are used to create a [PermissionSetParameters]{@link
* https://w3c.github.io/permissions/#dictdef-permissionsetparameters} object
@@ -213,13 +259,13 @@
* @returns {Promise} fulfilled after the permission is set, or rejected if setting the
* permission fails
*/
- set_permission: function(descriptor, state, one_realm) {
+ set_permission: function(descriptor, state, one_realm, context=null) {
let permission_params = {
descriptor,
state,
oneRealm: one_realm,
};
- return window.test_driver_internal.set_permission(permission_params);
+ return window.test_driver_internal.set_permission(permission_params, context);
},
/**
@@ -232,12 +278,16 @@
* @param {Object} config - an [Authenticator Configuration]{@link
* https://w3c.github.io/webauthn/#authenticator-configuration}
* object
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
+ *
* @returns {Promise} fulfilled after the authenticator is added, or
* rejected in the cases the WebDriver command
* errors. Returns the ID of the authenticator
*/
- add_virtual_authenticator: function(config) {
- return window.test_driver_internal.add_virtual_authenticator(config);
+ add_virtual_authenticator: function(config, context=null) {
+ return window.test_driver_internal.add_virtual_authenticator(config, context);
},
/**
@@ -249,13 +299,16 @@
*
* @param {String} authenticator_id - the ID of the authenticator to be
* removed.
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} fulfilled after the authenticator is removed, or
* rejected in the cases the WebDriver command
* errors
*/
- remove_virtual_authenticator: function(authenticator_id) {
- return window.test_driver_internal.remove_virtual_authenticator(authenticator_id);
+ remove_virtual_authenticator: function(authenticator_id, context=null) {
+ return window.test_driver_internal.remove_virtual_authenticator(authenticator_id, context);
},
/**
@@ -267,13 +320,16 @@
* @param {Object} credential - A [Credential Parameters]{@link
* https://w3c.github.io/webauthn/#credential-parameters}
* object
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} fulfilled after the credential is added, or
* rejected in the cases the WebDriver command
* errors
*/
- add_credential: function(authenticator_id, credential) {
- return window.test_driver_internal.add_credential(authenticator_id, credential);
+ add_credential: function(authenticator_id, credential, context=null) {
+ return window.test_driver_internal.add_credential(authenticator_id, credential, context);
},
/**
@@ -285,6 +341,9 @@
* https://w3c.github.io/webauthn/#sctn-automation-get-credentials
*
* @param {String} authenticator_id - the ID of the authenticator
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} fulfilled after the credentials are returned, or
* rejected in the cases the WebDriver command
@@ -292,8 +351,8 @@
* Parameters]{@link
* https://w3c.github.io/webauthn/#credential-parameters}
*/
- get_credentials: function(authenticator_id) {
- return window.test_driver_internal.get_credentials(authenticator_id);
+ get_credentials: function(authenticator_id, context=null) {
+ return window.test_driver_internal.get_credentials(authenticator_id, context=null);
},
/**
@@ -303,13 +362,16 @@
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {String} credential_id - the ID of the credential
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} fulfilled after the credential is removed, or
* rejected in the cases the WebDriver command
* errors.
*/
- remove_credential: function(authenticator_id, credential_id) {
- return window.test_driver_internal.remove_credential(authenticator_id, credential_id);
+ remove_credential: function(authenticator_id, credential_id, context=null) {
+ return window.test_driver_internal.remove_credential(authenticator_id, credential_id, context);
},
/**
@@ -318,13 +380,16 @@
* https://w3c.github.io/webauthn/#sctn-automation-remove-all-credentials
*
* @param {String} authenticator_id - the ID of the authenticator
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} fulfilled after the credentials are removed, or
* rejected in the cases the WebDriver command
* errors.
*/
- remove_all_credentials: function(authenticator_id) {
- return window.test_driver_internal.remove_all_credentials(authenticator_id);
+ remove_all_credentials: function(authenticator_id, context=null) {
+ return window.test_driver_internal.remove_all_credentials(authenticator_id, context);
},
/**
@@ -336,9 +401,12 @@
*
* @param {String} authenticator_id - the ID of the authenticator
* @param {boolean} uv - the User Verified flag
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*/
- set_user_verified: function(authenticator_id, uv) {
- return window.test_driver_internal.set_user_verified(authenticator_id, uv);
+ set_user_verified: function(authenticator_id, uv, context=null) {
+ return window.test_driver_internal.set_user_verified(authenticator_id, uv, context);
},
/**
@@ -355,16 +423,19 @@
* May be "*" to indicate all origins.
* @param {String} state - The storage access setting.
* Must be either "allowed" or "blocked".
+ * @param {WindowProxy} context - Browsing context in which
+ * to run the call, or null for the current
+ * browsing context.
*
* @returns {Promise} Fulfilled after the storage access rule has been
* set, or rejected if setting the rule fails.
*/
- set_storage_access: function(origin, embedding_origin, state) {
+ set_storage_access: function(origin, embedding_origin, state, context=null) {
if (state !== "allowed" && state !== "blocked") {
throw new Error("storage access status must be 'allowed' or 'blocked'");
}
const blocked = state === "blocked";
- return window.test_driver_internal.set_storage_access(origin, embedding_origin, blocked);
+ return window.test_driver_internal.set_storage_access(origin, embedding_origin, blocked, context);
},
};
@@ -377,13 +448,6 @@
*/
in_automation: false,
- /**
- * Waits for a user-initiated click
- *
- * @param {Element} element - element to be clicked
- * @param {{x: number, y: number} coords - viewport coordinates to click at
- * @returns {Promise} fulfilled after click occurs
- */
click: function(element, coords) {
if (this.in_automation) {
return Promise.reject(new Error('Not implemented'));
@@ -394,14 +458,6 @@
});
},
- /**
- * Waits for an element to receive a series of key presses
- *
- * @param {Element} element - element which should receve key presses
- * @param {String} keys - keys to expect
- * @returns {Promise} fulfilled after keys are received or rejected if
- * an incorrect key sequence is received
- */
send_keys: function(element, keys) {
if (this.in_automation) {
return Promise.reject(new Error('Not implemented'));
@@ -434,158 +490,52 @@
});
},
- /**
- * Freeze the current page
- *
- * @returns {Promise} fulfilled after freeze request is sent, otherwise
- * it gets rejected
- */
- freeze: function() {
+ freeze: function(context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Send a sequence of pointer actions
- *
- * @returns {Promise} fufilled after actions are sent, rejected if any actions
- * fail
- */
- action_sequence: function(actions) {
+ action_sequence: function(actions, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Generates a test report on the current page
- *
- * @param {String} message - the message to be contained in the report
- * @returns {Promise} fulfilled after the report is generated, or
- * rejected if the report generation fails
- */
- generate_test_report: function(message) {
+ generate_test_report: function(message, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Sets the state of a permission
- *
- * This function simulates a user setting a permission into a particular state as described
- * in {@link https://w3c.github.io/permissions/#set-permission-command}
- *
- * @param {Object} permission_params - a [PermissionSetParameters]{@lint
- * https://w3c.github.io/permissions/#dictdef-permissionsetparameters}
- * object
- * @returns {Promise} fulfilled after the permission is set, or rejected if setting the
- * permission fails
- */
- set_permission: function(permission_params) {
+ set_permission: function(permission_params, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Creates a virtual authenticator
- *
- * @param {Object} config - the authenticator configuration
- * @returns {Promise} fulfilled after the authenticator is added, or
- * rejected in the cases the WebDriver command
- * errors.
- */
- add_virtual_authenticator: function(config) {
+ add_virtual_authenticator: function(config, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Removes a virtual authenticator
- *
- * @param {String} authenticator_id - the ID of the authenticator to be
- * removed.
- *
- * @returns {Promise} fulfilled after the authenticator is removed, or
- * rejected in the cases the WebDriver command
- * errors
- */
- remove_virtual_authenticator: function(authenticator_id) {
+ remove_virtual_authenticator: function(authenticator_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Adds a credential to a virtual authenticator
- *
- * @param {String} authenticator_id - the ID of the authenticator
- * @param {Object} credential - A [Credential Parameters]{@link
- * https://w3c.github.io/webauthn/#credential-parameters}
- * object
- *
- * @returns {Promise} fulfilled after the credential is added, or
- * rejected in the cases the WebDriver command
- * errors
- *
- */
- add_credential: function(authenticator_id, credential) {
+ add_credential: function(authenticator_id, credential, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Gets all the credentials stored in an authenticator
- *
- * @param {String} authenticator_id - the ID of the authenticator
- *
- * @returns {Promise} fulfilled after the credentials are returned, or
- * rejected in the cases the WebDriver command
- * errors. Returns an array of [Credential
- * Parameters]{@link
- * https://w3c.github.io/webauthn/#credential-parameters}
- *
- */
- get_credentials: function(authenticator_id) {
+ get_credentials: function(authenticator_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Remove a credential stored in an authenticator
- *
- * @param {String} authenticator_id - the ID of the authenticator
- * @param {String} credential_id - the ID of the credential
- *
- * @returns {Promise} fulfilled after the credential is removed, or
- * rejected in the cases the WebDriver command
- * errors.
- *
- */
- remove_credential: function(authenticator_id, credential_id) {
+ remove_credential: function(authenticator_id, credential_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Removes all the credentials stored in a virtual authenticator
- *
- * @param {String} authenticator_id - the ID of the authenticator
- *
- * @returns {Promise} fulfilled after the credentials are removed, or
- * rejected in the cases the WebDriver command
- * errors.
- *
- */
- remove_all_credentials: function(authenticator_id) {
+ remove_all_credentials: function(authenticator_id, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Sets the User Verified flag on an authenticator
- *
- * @param {String} authenticator_id - the ID of the authenticator
- * @param {boolean} uv - the User Verified flag
- *
- */
- set_user_verified: function(authenticator_id, uv) {
+ set_user_verified: function(authenticator_id, uv, context=null) {
return Promise.reject(new Error("unimplemented"));
},
- /**
- * Sets the storage access policy for a third-party origin when loaded
- * in the current first party context
- */
- set_storage_access: function(origin, embedding_origin, blocked) {
+ set_storage_access: function(origin, embedding_origin, blocked, context=null) {
return Promise.reject(new Error("unimplemented"));
},
};
diff --git a/tests/wpt/web-platform-tests/svg/painting/reftests/markers-orient-002.svg b/tests/wpt/web-platform-tests/svg/painting/reftests/markers-orient-002.svg
new file mode 100644
index 00000000000..f371784e2ac
--- /dev/null
+++ b/tests/wpt/web-platform-tests/svg/painting/reftests/markers-orient-002.svg
@@ -0,0 +1,15 @@
+
diff --git a/tests/wpt/web-platform-tests/tools/ci/azure/safari-technology-preview.rb b/tests/wpt/web-platform-tests/tools/ci/azure/safari-technology-preview.rb
index 0268ac4b448..1a3620529c0 100644
--- a/tests/wpt/web-platform-tests/tools/ci/azure/safari-technology-preview.rb
+++ b/tests/wpt/web-platform-tests/tools/ci/azure/safari-technology-preview.rb
@@ -1,10 +1,10 @@
cask "safari-technology-preview" do
if MacOS.version <= :catalina
- version "113,001-46217-20200908-26bf578a-dcb0-4f70-b930-d9131bbf5d8a"
- sha256 "09f86d0808e067a46584e9394767040012d7bbae453bb9842cabbf593d9185d9"
+ version "114,001-54431-20201007-6899e5c7-457d-484b-bf38-fce2fcc967da"
+ sha256 "1803c0affc0e7b28d945e122e99ed5741c19b9f2a949b473133adf916023db5b"
else
- version "113,001-43557-20200908-b620aaf9-e006-4855-8bdf-e7e76b5950bc"
- sha256 "3dcf197b8c2c181861d0c3f3d00fbb65940d1c1aaf11511c76c94fb153d0a7f0"
+ version "114,001-53239-20201007-7bed156d-ab68-4db2-8ff0-3fa2e23fa2c0"
+ sha256 "c93ff3b5d485fce80b86f9656ffba3f5b967b189776cd20aea16a4c681419414"
end
url "https://secure-appldnld.apple.com/STP/#{version.after_comma}/SafariTechnologyPreview.dmg"
diff --git a/tests/wpt/web-platform-tests/tools/ci/tc/sink_task.py b/tests/wpt/web-platform-tests/tools/ci/tc/sink_task.py
index ba76d27640c..1efcd4225cd 100644
--- a/tests/wpt/web-platform-tests/tools/ci/tc/sink_task.py
+++ b/tests/wpt/web-platform-tests/tools/ci/tc/sink_task.py
@@ -2,40 +2,63 @@ import argparse
import logging
import os
+from six import ensure_text
import taskcluster
+from .github_checks_output import get_gh_checks_outputter
+
logging.basicConfig()
logger = logging.getLogger()
-def check_task_statuses(task_ids):
+def check_task_statuses(task_ids, github_checks_outputter):
"""Verifies whether a set of Taskcluster tasks completed successfully or not.
Returns 0 if all tasks passed completed successfully, 1 otherwise."""
queue = taskcluster.Queue({'rootUrl': os.environ['TASKCLUSTER_ROOT_URL']})
- success = True
+ failed_tasks = []
for task in task_ids:
status = queue.status(task)
state = status['status']['state']
if state == 'failed' or state == 'exception':
logger.error('Task {0} failed with state "{1}"'.format(task, state))
- success = False
+ failed_tasks.append(status)
elif state != 'completed':
logger.error('Task {0} had unexpected state "{1}"'.format(task, state))
- success = False
- if success:
+ failed_tasks.append(status)
+
+ if failed_tasks and github_checks_outputter:
+ github_checks_outputter.output('Failed tasks:')
+ for task in failed_tasks:
+ # We need to make an additional call to get the task name.
+ task_id = task['status']['taskId']
+ task_name = queue.task(task_id)['metadata']['name']
+ github_checks_outputter.output('* `{}` failed with status `{}`'.format(task_name, task['status']['state']))
+ else:
logger.info('All tasks completed successfully')
- return 0 if success else 1
+ if github_checks_outputter:
+ github_checks_outputter.output('All tasks completed successfully')
+ return 1 if failed_tasks else 0
def get_parser():
parser = argparse.ArgumentParser()
+ parser.add_argument("--github-checks-text-file", type=ensure_text,
+ help="Path to GitHub checks output file for Taskcluster runs")
parser.add_argument("tasks", nargs="+",
help="A set of Taskcluster task ids to verify the state of.")
return parser
def run(venv, **kwargs):
- return check_task_statuses(kwargs['tasks'])
+ github_checks_outputter = get_gh_checks_outputter(kwargs["github_checks_text_file"])
+
+ if github_checks_outputter:
+ github_checks_outputter.output(
+ "This check acts as a 'sink' for all other Taskcluster-based checks. "
+ "A failure here means that some other check has failed, which is the "
+ "real blocker.\n"
+ )
+ return check_task_statuses(kwargs['tasks'], github_checks_outputter)
diff --git a/tests/wpt/web-platform-tests/tools/ci/tc/tasks/test.yml b/tests/wpt/web-platform-tests/tools/ci/tc/tasks/test.yml
index 78891bf3023..4fa69e871bc 100644
--- a/tests/wpt/web-platform-tests/tools/ci/tc/tasks/test.yml
+++ b/tests/wpt/web-platform-tests/tools/ci/tc/tasks/test.yml
@@ -591,5 +591,5 @@ tasks:
use:
- wpt-base
- trigger-pr
- command: "./wpt tc-sink-task"
+ command: "./wpt tc-sink-task --github-checks-text-file=/home/test/artifacts/checkrun.md"
requires: all-resolved
diff --git a/tests/wpt/web-platform-tests/tools/wpt/browser.py b/tests/wpt/web-platform-tests/tools/wpt/browser.py
index 13ffa3f08b3..726d5598f52 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/browser.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/browser.py
@@ -661,7 +661,7 @@ class Chrome(Browser):
def find_webdriver(self, venv_path=None, channel=None, browser_binary=None):
return find_executable("chromedriver")
- def webdriver_supports_browser(self, webdriver_binary, browser_binary):
+ def webdriver_supports_browser(self, webdriver_binary, browser_binary, browser_channel):
chromedriver_version = self.webdriver_version(webdriver_binary)
if not chromedriver_version:
self.logger.warning(
@@ -676,9 +676,17 @@ class Chrome(Browser):
return True
# Check that the ChromeDriver version matches the Chrome version.
- chromedriver_major = chromedriver_version.split('.')[0]
- browser_major = browser_version.split('.')[0]
+ chromedriver_major = int(chromedriver_version.split('.')[0])
+ browser_major = int(browser_version.split('.')[0])
if chromedriver_major != browser_major:
+ # There is no official ChromeDriver release for the dev channel -
+ # it switches between beta and tip-of-tree, so we accept version+1
+ # too for dev.
+ if browser_channel == "dev" and chromedriver_major == (browser_major + 1):
+ self.logger.debug(
+ "Accepting ChromeDriver %s for Chrome/Chromium Dev %s" %
+ (chromedriver_version, browser_version))
+ return True
self.logger.warning(
"ChromeDriver %s does not match Chrome/Chromium %s" %
(chromedriver_version, browser_version))
diff --git a/tests/wpt/web-platform-tests/tools/wpt/run.py b/tests/wpt/web-platform-tests/tools/wpt/run.py
index dc130a16d11..561b8e85aa7 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/run.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/run.py
@@ -345,7 +345,7 @@ class Chrome(BrowserSetup):
if not kwargs["install_webdriver"]:
webdriver_binary = self.browser.find_webdriver()
if webdriver_binary and not self.browser.webdriver_supports_browser(
- webdriver_binary, kwargs["binary"]):
+ webdriver_binary, kwargs["binary"], browser_channel):
webdriver_binary = None
if webdriver_binary is None:
diff --git a/tests/wpt/web-platform-tests/tools/wpt/tests/test_browser.py b/tests/wpt/web-platform-tests/tools/wpt/tests/test_browser.py
index 0abdb9d45b8..3d5f2d3ae6f 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/tests/test_browser.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/tests/test_browser.py
@@ -80,25 +80,34 @@ def test_chrome_webdriver_supports_browser():
# ChromeDriver binary cannot be called.
chrome = browser.Chrome(logger)
chrome.webdriver_version = mock.MagicMock(return_value=None)
- assert not chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome')
+ assert not chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome', 'stable')
# Browser binary cannot be called.
chrome = browser.Chrome(logger)
chrome.webdriver_version = mock.MagicMock(return_value='70.0.1')
chrome.version = mock.MagicMock(return_value=None)
- assert chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome')
+ assert chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome', 'stable')
# Browser version matches.
chrome = browser.Chrome(logger)
chrome.webdriver_version = mock.MagicMock(return_value='70.0.1')
chrome.version = mock.MagicMock(return_value='70.1.5')
- assert chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome')
+ assert chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome', 'stable')
# Browser version doesn't match.
chrome = browser.Chrome(logger)
chrome.webdriver_version = mock.MagicMock(return_value='70.0.1')
chrome.version = mock.MagicMock(return_value='69.0.1')
- assert not chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome')
+ assert not chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome', 'stable')
+
+ # The dev channel switches between beta and ToT ChromeDriver, so is sometimes
+ # a version behind its ChromeDriver. As such, we accept browser version + 1 there.
+ chrome = browser.Chrome(logger)
+ chrome.webdriver_version = mock.MagicMock(return_value='70.0.1')
+ chrome.version = mock.MagicMock(return_value='70.1.0')
+ assert chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome', 'dev')
+ chrome.webdriver_version = mock.MagicMock(return_value='71.0.1')
+ assert chrome.webdriver_supports_browser('/usr/bin/chromedriver', '/usr/bin/chrome', 'dev')
# On Windows, webdriver_version directly calls _get_fileversion, so there is no
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/base.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/base.py
index 0247b3feed2..4c3891c1cb6 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/base.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/base.py
@@ -691,6 +691,9 @@ class ConnectionlessBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
pass
+ def window_handles(self):
+ return []
+
class ConnectionlessProtocol(Protocol):
implements = [ConnectionlessBaseProtocolPart]
@@ -787,6 +790,7 @@ class CallbackHandler(object):
def process_action(self, url, payload):
action = payload["action"]
+ cmd_id = payload["id"]
self.logger.debug("Got action: %s" % action)
try:
action_handler = self.actions[action]
@@ -797,21 +801,21 @@ class CallbackHandler(object):
result = action_handler(payload)
except self.unimplemented_exc:
self.logger.warning("Action %s not implemented" % action)
- self._send_message("complete", "error", "Action %s not implemented" % action)
+ self._send_message(cmd_id, "complete", "error", "Action %s not implemented" % action)
except Exception:
self.logger.warning("Action %s failed" % action)
self.logger.warning(traceback.format_exc())
- self._send_message("complete", "error")
+ self._send_message(cmd_id, "complete", "error")
raise
else:
self.logger.debug("Action %s completed with result %s" % (action, result))
return_message = {"result": result}
- self._send_message("complete", "success", json.dumps(return_message))
+ self._send_message(cmd_id, "complete", "success", json.dumps(return_message))
return False, None
- def _send_message(self, message_type, status, message=None):
- self.protocol.testdriver.send_message(message_type, status, message=message)
+ def _send_message(self, cmd_id, message_type, status, message=None):
+ self.protocol.testdriver.send_message(cmd_id, message_type, status, message=message)
class ActionContext(object):
@@ -820,28 +824,20 @@ class ActionContext(object):
self.protocol = protocol
self.context = context
self.initial_window = None
- self.switched_frame = False
def __enter__(self):
if self.context is None:
return
- window_id = self.context[0]
- if window_id:
- self.initial_window = self.protocol.base.current_window
- self.logger.debug("Switching to window %s" % window_id)
- self.protocol.testdriver.switch_to_window(window_id)
-
- for frame_id in self.context[1:]:
- self.switched_frame = True
- self.logger.debug("Switching to frame %s" % frame_id)
- self.protocol.testdriver.switch_to_frame(frame_id)
+ self.initial_window = self.protocol.base.current_window
+ self.logger.debug("Switching to window %s" % self.context)
+ self.protocol.testdriver.switch_to_window(self.context)
def __exit__(self, *args):
- if self.initial_window is not None:
- self.logger.debug("Switching back to initial window")
- self.protocol.base.set_window(self.initial_window)
- self.initial_window = None
- elif self.switched_frame:
- self.protocol.testdriver.switch_to_frame(None)
- self.switched_frame = False
+ if self.context is None:
+ return
+
+ self.logger.debug("Switching back to initial window")
+ self.protocol.base.set_window(self.initial_window)
+ self.protocol.testdriver._switch_to_frame(None)
+ self.initial_window = None
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executormarionette.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executormarionette.py
index e7c9726974b..7e2cc8e38a4 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executormarionette.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executormarionette.py
@@ -103,6 +103,9 @@ class MarionetteBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
_switch_to_window(self.marionette, handle)
+ def window_handles(self):
+ return self.marionette.window_handles
+
def load(self, url):
self.marionette.navigate(url)
@@ -460,8 +463,9 @@ class MarionetteTestDriverProtocolPart(TestDriverProtocolPart):
def setup(self):
self.marionette = self.parent.marionette
- def send_message(self, message_type, status, message=None):
+ def send_message(self, cmd_id, message_type, status, message=None):
obj = {
+ "cmd_id": cmd_id,
"type": "testdriver-%s" % str(message_type),
"status": str(status)
}
@@ -469,24 +473,12 @@ class MarionetteTestDriverProtocolPart(TestDriverProtocolPart):
obj["message"] = str(message)
self.parent.base.execute_script("window.postMessage(%s, '*')" % json.dumps(obj))
- def switch_to_window(self, window_id):
- if window_id is None:
- return
-
- for window_handle in self.marionette.window_handles:
- _switch_to_window(self.marionette, window_handle)
- try:
- handle_window_id = self.marionette.execute_script("return window.name")
- except errors.JavascriptException:
- continue
- if str(handle_window_id) == window_id:
- return
-
- raise Exception("Window with id %s not found" % window_id)
-
- def switch_to_frame(self, frame_number):
+ def _switch_to_frame(self, frame_number):
self.marionette.switch_to_frame(frame_number)
+ def _switch_to_parent_frame(self):
+ self.marionette.switch_to_parent_frame()
+
class MarionetteCoverageProtocolPart(CoverageProtocolPart):
def setup(self):
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py
index 82ab6f25560..ff26351f84e 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py
@@ -61,6 +61,9 @@ class SeleniumBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
self.webdriver.switch_to_window(handle)
+ def window_handles(self):
+ return self.webdriver.window_handles
+
def load(self, url):
self.webdriver.get(url)
@@ -200,8 +203,9 @@ class SeleniumTestDriverProtocolPart(TestDriverProtocolPart):
def setup(self):
self.webdriver = self.parent.webdriver
- def send_message(self, message_type, status, message=None):
+ def send_message(self, cmd_id, message_type, status, message=None):
obj = {
+ "cmd_id": cmd_id,
"type": "testdriver-%s" % str(message_type),
"status": str(status)
}
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservodriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservodriver.py
index dbed2fedbdf..2cd1dbf3ad0 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservodriver.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservodriver.py
@@ -76,6 +76,9 @@ class ServoBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
pass
+ def window_handles(self):
+ return []
+
def load(self, url):
pass
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py
index 139c475ce44..bad5fd07223 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py
@@ -61,6 +61,9 @@ class WebDriverBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
self.webdriver.window_handle = handle
+ def window_handles(self):
+ return self.webdriver.handles
+
def load(self, url):
self.webdriver.url = url
@@ -214,8 +217,9 @@ class WebDriverTestDriverProtocolPart(TestDriverProtocolPart):
def setup(self):
self.webdriver = self.parent.webdriver
- def send_message(self, message_type, status, message=None):
+ def send_message(self, cmd_id, message_type, status, message=None):
obj = {
+ "cmd_id": cmd_id,
"type": "testdriver-%s" % str(message_type),
"status": str(status)
}
@@ -223,24 +227,12 @@ class WebDriverTestDriverProtocolPart(TestDriverProtocolPart):
obj["message"] = str(message)
self.webdriver.execute_script("window.postMessage(%s, '*')" % json.dumps(obj))
- def switch_to_window(self, window_id):
- if window_id is None:
- return
-
- for window_handle in self.webdriver.handles:
- self.webdriver.window_handle = window_handle
- try:
- handle_window_id = self.webdriver.execute_script("return window.name")
- except client.JavascriptErrorException:
- continue
- if str(handle_window_id) == window_id:
- return
-
- raise Exception("Window with id %s not found" % window_id)
-
- def switch_to_frame(self, frame_number):
+ def _switch_to_frame(self, frame_number):
self.webdriver.switch_frame(frame_number)
+ def _switch_to_parent_frame(self):
+ self.webdriver.switch_frame("parent")
+
class WebDriverGenerateTestReportProtocolPart(GenerateTestReportProtocolPart):
def setup(self):
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/protocol.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/protocol.py
index 1c85c0f8b96..bd768b1073c 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/protocol.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/protocol.py
@@ -146,6 +146,11 @@ class BaseProtocolPart(ProtocolPart):
context."""
pass
+ @abstractmethod
+ def window_handles(self):
+ """Get a list of handles to top-level browsing contexts"""
+ pass
+
@abstractmethod
def load(self, url):
"""Load a url in the current browsing context
@@ -343,9 +348,10 @@ class TestDriverProtocolPart(ProtocolPart):
name = "testdriver"
@abstractmethod
- def send_message(self, message_type, status, message=None):
+ def send_message(self, cmd_id, message_type, status, message=None):
"""Send a testdriver message to the browser.
+ :param int cmd_id: The id of the command to which we're responding
:param str message_type: The kind of the message.
:param str status: Either "failure" or "success" depending on whether the
previous command succeeded.
@@ -356,14 +362,46 @@ class TestDriverProtocolPart(ProtocolPart):
"""Switch to a window given a wptrunner window id
:param str wptrunner_id: window id"""
- pass
+ if wptrunner_id is None:
+ return
- def switch_to_frame(self, index):
+ stack = [str(item) for item in self.parent.base.window_handles()]
+ while stack:
+ item = stack.pop()
+ if item is None:
+ self._switch_to_parent_frame()
+ continue
+ elif isinstance(item, str):
+ self.parent.base.set_window(item)
+ else:
+ self._switch_to_frame(item)
+
+ try:
+ handle_window_id = self.parent.base.execute_script("return window.__wptrunner_id")
+ if str(handle_window_id) == wptrunner_id:
+ return
+ except Exception:
+ pass
+ frame_count = self.parent.base.execute_script("return window.length")
+ # None here makes us switch back to the parent after we've processed all the subframes
+ stack.append(None)
+ if frame_count:
+ stack.extend(reversed(range(0, frame_count)))
+
+ raise Exception("Window with id %s not found" % wptrunner_id)
+
+ @abstractmethod
+ def _switch_to_frame(self, index):
"""Switch to a frame in the current window
:param int index: Frame id"""
pass
+ @abstractmethod
+ def _switch_to_parent_frame(self):
+ """Switch to the parent of the current frame"""
+ pass
+
class AssertsProtocolPart(ProtocolPart):
"""ProtocolPart that implements the functionality required to get a count of non-fatal
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testdriver-extra.js b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testdriver-extra.js
index 241fc833951..9c0c69af3a3 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testdriver-extra.js
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testdriver-extra.js
@@ -1,9 +1,13 @@
"use strict";
-(function(){
- let pending_resolve = null;
- let pending_reject = null;
+(function() {
+ const is_test_context = window.__wptrunner_message_queue !== undefined;
+ const pending = new Map();
+
let result = null;
+ let ctx_cmd_id = 0;
+ let testharness_context = null;
+
window.addEventListener("message", function(event) {
const data = event.data;
@@ -11,29 +15,70 @@
return;
}
- if (data.type !== "testdriver-complete") {
- return;
- }
-
- if (data.status === "success") {
- result = JSON.parse(data.message).result;
- pending_resolve(result);
- } else {
- pending_reject(`${data.status}: ${data.message}`);
+ if (is_test_context && data.type === "testdriver-command") {
+ const command = data.message;
+ const ctx_id = command.cmd_id;
+ delete command.cmd_id;
+ const cmd_id = window.__wptrunner_message_queue.push(command);
+ let on_success = (data) => {
+ data.type = "testdriver-complete";
+ data.cmd_id = ctx_id;
+ event.source.postMessage(data, "*");
+ };
+ let on_failure = (data) => {
+ data.type = "testdriver-complete";
+ data.cmd_id = ctx_id;
+ event.source.postMessage(data, "*");
+ };
+ pending.set(cmd_id, [on_success, on_failure]);
+ } else if (data.type === "testdriver-complete") {
+ const cmd_id = data.cmd_id;
+ const [on_success, on_failure] = pending.get(cmd_id);
+ pending.clear(cmd_id);
+ const resolver = data.status === "success" ? on_success : on_failure;
+ resolver(data);
+ if (is_test_context) {
+ window.__wptrunner_process_next_event();
+ }
}
});
- let last_window_id = 0;
+ // Code copied from /common/utils.js
+ function rand_int(bits) {
+ if (bits < 1 || bits > 53) {
+ throw new TypeError();
+ } else {
+ if (bits >= 1 && bits <= 30) {
+ return 0 | ((1 << bits) * Math.random());
+ } else {
+ var high = (0 | ((1 << (bits - 30)) * Math.random())) * (1 << 30);
+ var low = 0 | ((1 << 30) * Math.random());
+ return high + low;
+ }
+ }
+ }
+
+ function to_hex(x, length) {
+ var rv = x.toString(16);
+ while (rv.length < length) {
+ rv = "0" + rv;
+ }
+ return rv;
+ }
+
function get_window_id(win) {
- if (win === window) {
+ if (win == window && is_test_context) {
return null;
}
- // This is a hack until some implementations support proper window ids
- // It won't work cross-frame
- if (!win.name) {
- win.name = "__wptrunner_window " + last_window_id++;
+ if (!win.__wptrunner_id) {
+ // generate a uuid
+ win.__wptrunner_id = [to_hex(rand_int(32), 8),
+ to_hex(rand_int(16), 4),
+ to_hex(0x4000 | rand_int(12), 4),
+ to_hex(0x8000 | rand_int(14), 4),
+ to_hex(rand_int(48), 12)].join("-");
}
- return win.name;
+ return win.__wptrunner_id;
}
const get_context = function(element) {
@@ -44,23 +89,7 @@
if (!elementWindow) {
throw new Error("Browsing context for element was detached");
}
- let top = elementWindow.top;
- if (elementWindow === window) {
- if (top !== window) {
- throw new Error("Can't load testdriver in a frame");
- }
- // For the current window just return null
- return null;
- }
- let rv = [];
- let currentWindow = elementWindow;
- while (currentWindow !== top) {
- rv.push(Array.prototype.indexOf.call(currentWindow.parent.frames, currentWindow));
- currentWindow = currentWindow.parent;
- }
- rv.push(top !== window ? get_window_id(top) : null);
- rv.reverse();
- return rv;
+ return elementWindow;
};
const get_selector = function(element) {
@@ -93,43 +122,60 @@
return selector;
};
+ const create_action = function(name, props) {
+ let cmd_id;
+ const action_msg = {type: "action",
+ action: name,
+ ...props};
+ if (action_msg.context) {
+ action_msg.context = get_window_id(action_msg.context);
+ }
+ if (is_test_context) {
+ cmd_id = window.__wptrunner_message_queue.push(action_msg);
+ } else {
+ if (testharness_context === null) {
+ throw new Error("Tried to run in a non-testharness window without a call to set_test_context");
+ }
+ cmd_id = ctx_cmd_id++;
+ action_msg.cmd_id = cmd_id;
+ window.test_driver.message_test({type: "testdriver-command",
+ message: action_msg});
+ }
+ const pending_promise = new Promise(function(resolve, reject) {
+ const on_success = data => {
+ result = JSON.parse(data.message).result;
+ resolve(result);
+ };
+ const on_failure = data => {
+ reject(`${data.status}: ${data.message}`);
+ };
+ pending.set(cmd_id, [on_success, on_failure]);
+ });
+ return pending_promise;
+ };
+
window.test_driver_internal.in_automation = true;
+ window.test_driver_internal.set_test_context = function(context) {
+ if (window.__wptrunner_message_queue) {
+ throw new Error("Tried to set testharness context in a window containing testharness.js");
+ }
+ testharness_context = context;
+ };
+
window.test_driver_internal.click = function(element) {
- const context = get_context(element);
const selector = get_selector(element);
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "click",
- selector,
- context});
- return pending_promise;
+ const context = get_context(element);
+ return create_action("click", {selector, context});
};
window.test_driver_internal.send_keys = function(element, keys) {
const selector = get_selector(element);
const context = get_context(element);
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "send_keys",
- selector,
- keys,
- context});
- return pending_promise;
+ return create_action("send_keys", {selector, keys, context});
};
- window.test_driver_internal.action_sequence = function(actions) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- let context = null;
+ window.test_driver_internal.action_sequence = function(actions, context=null) {
for (let actionSequence of actions) {
if (actionSequence.type == "pointer") {
for (let action of actionSequence.actions) {
@@ -145,111 +191,42 @@
}
}
}
- window.__wptrunner_message_queue.push({type: "action",
- action: "action_sequence",
- actions,
- context});
- return pending_promise;
+ return create_action("action_sequence", {actions, context});
};
- window.test_driver_internal.generate_test_report = function(message) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "generate_test_report",
- message});
- return pending_promise;
+ window.test_driver_internal.generate_test_report = function(message, context=null) {
+ return create_action("generate_test_report", {message, context});
};
- window.test_driver_internal.set_permission = function(permission_params) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "set_permission",
- permission_params});
- return pending_promise;
+ window.test_driver_internal.set_permission = function(permission_params, context=null) {
+ return create_action("set_permission", {permission_params, context});
};
- window.test_driver_internal.add_virtual_authenticator = function(config) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "add_virtual_authenticator",
- config});
- return pending_promise;
+ window.test_driver_internal.add_virtual_authenticator = function(config, context=null) {
+ return create_action("add_virtual_authenticator", {config, context});
};
- window.test_driver_internal.remove_virtual_authenticator = function(authenticator_id) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "remove_virtual_authenticator",
- authenticator_id});
- return pending_promise;
+ window.test_driver_internal.remove_virtual_authenticator = function(authenticator_id, context=null) {
+ return create_action("remove_virtual_authenticator", {authenticator_id, context});
};
- window.test_driver_internal.add_credential = function(authenticator_id, credential) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "add_credential",
- authenticator_id, credential});
- return pending_promise;
+ window.test_driver_internal.add_credential = function(authenticator_id, credential, context=null) {
+ return create_action("add_credential", {authenticator_id, credential, context});
};
- window.test_driver_internal.get_credentials = function(authenticator_id) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "get_credentials",
- authenticator_id});
- return pending_promise;
+ window.test_driver_internal.get_credentials = function(authenticator_id, context=null) {
+ return create_action("get_credentials", {authenticator_id, context});
};
- window.test_driver_internal.remove_credential = function(authenticator_id, credential_id) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "remove_credential",
- authenticator_id,
- credential_id});
- return pending_promise;
+ window.test_driver_internal.remove_credential = function(authenticator_id, credential_id, context=null) {
+ return create_action("remove_credential", {authenticator_id, credential_id, context});
};
- window.test_driver_internal.remove_all_credentials = function(authenticator_id) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "remove_all_credentials",
- authenticator_id});
- return pending_promise;
+ window.test_driver_internal.remove_all_credentials = function(authenticator_id, context=null) {
+ return create_action("remove_all_credentials", {authenticator_id, context});
};
- window.test_driver_internal.set_user_verified = function(authenticator_id, uv) {
- const pending_promise = new Promise(function(resolve, reject) {
- pending_resolve = resolve;
- pending_reject = reject;
- });
- window.__wptrunner_message_queue.push({"type": "action",
- "action": "set_user_verified",
- authenticator_id,
- uv});
- return pending_promise;
+ window.test_driver_internal.set_user_verified = function(authenticator_id, uv, context=null) {
+ return create_action("set_user_verified", {authenticator_id, uv, context});
};
})();
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testharnessreport.js b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testharnessreport.js
index 29fc0e98731..9cd680e14ae 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testharnessreport.js
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testharnessreport.js
@@ -1,11 +1,15 @@
class MessageQueue {
constructor() {
+ this.item_id = 0;
this._queue = [];
}
push(item) {
+ let cmd_id = this.item_id++;
+ item.id = cmd_id;
this._queue.push(item);
__wptrunner_process_next_event();
+ return cmd_id;
}
shift() {