-
Notifications
You must be signed in to change notification settings - Fork 79
RFC 88: [testdriver] Extend the mechanisms for giving browsing contexts ids. #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| # RFC 87: `testdriver` Extend the mechanisms for giving browsing contexts ids. | ||
|
|
||
| ## Summary | ||
|
|
||
| Allow contexts to be identified using either a `testdriver_id` | ||
| property on the (window) global, or a `uuid` query parameter, either | ||
| on the container `src` attribute (for nested browsing contexts) or the | ||
| actual resource URL. | ||
|
|
||
| ## Details | ||
|
|
||
| When interacting with either browsing contexts or scripting realms | ||
| (hereafter: contexts) other than the test window, it's necessary to | ||
| have an identifier for the context that's available both on the js | ||
| side and can also be used by WebDriver to identify the context in | ||
| question. | ||
|
|
||
| Because of the limitations of the WebDriver-based testdriver setup, we | ||
| don't have an existing UUID for each context which could be reused for | ||
| this purpose. Instead the `testdriver-extra.js` file in wptrunner | ||
| has a `get_window_id` function that takes a `WindowProxy` object, | ||
| looks for a `__wptrunner_id` property, if not present sets it to a new | ||
| UUID, and then returns the value. Then on the wptrunner side, we use | ||
| WebDriver to search the tree of open contexts, executing script in | ||
| each one to find the window with that property set. | ||
|
|
||
| This setup works OK for cases where the cross-origin policy allows | ||
| setting the property. We also support the case where the non-test | ||
| window includes testdriver.js and can postMessage a request to the | ||
| top-level window to initiate an action; with some work this allows | ||
| supporting any case where it's possible to get a js handle between the | ||
| test window and the top-level window. However we have no support for | ||
| noopener cases or COOP headers, or other cases where it's not possible | ||
| to pass messages between windows using js alone. | ||
|
|
||
| To address these use cases, we propose allowing the use of a `uuid` | ||
| query parameter on URLs, which will provide an alternate identifier | ||
| for the window that loads the URL. | ||
|
|
||
| In addition we propose updating the `__wptrunner_id` property name to | ||
| `testdriver_id`, and making it a documented part of the harness | ||
| setup. This will allow the default implementation of testdriver.js to | ||
| refer to the property directly rather than it being part of the | ||
| wptrunner implementation. | ||
|
|
||
| testdriver will get a new function `get_context_id(ctx)`, with the | ||
| following behaviour: | ||
| * If `ctx` is a string, return `ctx`. | ||
| * If ctx is a WindowProxy with a readable `location.href` which parses | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the 2-years-in-stable policy I've suggested elsewhere, we could use |
||
| as a URL and has a `uuid` query parameter, return the UUID parameter. | ||
| * If ctx is a WindowProxy and it has a `testdriver_id` attribute, | ||
| return the value of the attribute, or if it doesn't have such an | ||
| attribute, but the Window is writable from the current context, set | ||
| `testdriver_id` to a new id and return that. | ||
| * If `ctx` is a nested browsing context container with a `src` | ||
| attribute (for `iframe`, `frame`, `embed`) or `data` attribute (for | ||
| `object`) and the attribute value parses as a URL with a uuid | ||
| query parameter, return the uuid parameter. | ||
|
|
||
| On the wptrunner side, we keep the same behaviour of searching through | ||
| the tree of browsing contexts, but in addition we parse `uuid` query | ||
| strings out of the attribute values of nested context containers and | ||
| the URLs of loaded documents, and match those against the target URL. | ||
|
|
||
| In this system a specific context may have more than one associated id | ||
| (if the various ways of setting it differ), but we can use any | ||
| associated id to get to the browsing context. | ||
|
|
||
| For noopener cases, we can now provide a uuid in the URL and use that | ||
| to invoke testdriver actions on the remote context: | ||
|
|
||
| ``` | ||
| // Use the server subn to generate a UUID | ||
| let uuid = "{{uuid()}}" | ||
| open(`child.html?uuid=${uuid}`) | ||
| // [...] stuff to ensure child is loaded etc. | ||
| // In this case the context identifier is used directly | ||
| test_driver.delete_all_cookies(uuid) | ||
| ``` | ||
|
|
||
| We can also access a cross-origin-nested context: | ||
| ``` | ||
| <iframe src=https://{{host}}:{{ports[https][1]}}/file.html?uuid={{uuid()}}></iframe> | ||
| <script> | ||
| onload = () => { | ||
| let frame = frames[0]; | ||
| test_driver.delete_all_cookies(frame) | ||
| } | ||
| </script> | ||
| ``` | ||
|
|
||
| TODO: How should this extend to other resources such as worker scripts. For | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you intend to leave the TODO here? |
||
| current testdriver functionality it doesn't make much sense to run in | ||
| a worker, but once we have cross-context messaging we might want to | ||
| send messages to a worker we can't access via js. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. COEP tests contain script injection into workers/service workers ( |
||
|
|
||
| ## Risks | ||
|
|
||
| This may clash with existing use of a uuid parameter on URLs. A full | ||
| CI runs should be done to avoid unexpected changes to the test | ||
| results. | ||
|
|
||
| The system of having multiple ids for a given context is complex. In | ||
| particular there's a risk that once we have WebDriver implementations | ||
| that natively support providing an id to each context | ||
| (e.g. WebDriver-BiDi) we won't want to support this kind of slightly | ||
| hacky approach, but tests may depend on the implementation | ||
| details. That was the original reason for `__wptrunner_id` being | ||
| clearly an implementation detail. | ||
|
|
||
| ## References | ||
|
|
||
| [PR 29803](https://github.com/web-platform-tests/wpt/pull/29803) | ||
| contains a prototype implementation of this. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the RFC title says "browsing contexts ids", is this / should this be actually IDs for Windows (and other realms)?
When we navigate from URL A to URL B (within the same browsing context), we need to, and the draft PR web-platform-tests/wpt#29803 does, distinguish these two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's a bit ambiguous, or rather you can do both. In the PR, if you have an browsing context container with a uuid in the src attribute, that can be used as the uuid irespective of the current url of the loaded document. But if you have a
noopenerwindow you'd need to pass the uuid into subsequent URLs loaded in order to keep the same one, or otherwise generate a new one to get a different id for each document loaded. Which you want depends on what you're trying to achieve.