summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/docs/writing-tests/testdriver.md
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/docs/writing-tests/testdriver.md')
-rw-r--r--testing/web-platform/tests/docs/writing-tests/testdriver.md228
1 files changed, 228 insertions, 0 deletions
diff --git a/testing/web-platform/tests/docs/writing-tests/testdriver.md b/testing/web-platform/tests/docs/writing-tests/testdriver.md
new file mode 100644
index 0000000000..11193b147f
--- /dev/null
+++ b/testing/web-platform/tests/docs/writing-tests/testdriver.md
@@ -0,0 +1,228 @@
+# testdriver.js Automation
+
+```eval_rst
+
+.. contents:: Table of Contents
+ :depth: 3
+ :local:
+ :backlinks: none
+```
+
+testdriver.js provides a means to automate tests that cannot be
+written purely using web platform APIs. Outside of automation
+contexts, it allows human operators to provide expected input
+manually (for operations which may be described in simple terms).
+
+It is currently supported only for [testharness.js](testharness)
+tests.
+
+## Markup ##
+
+The `testdriver.js` and `testdriver-vendor.js` must both be included
+in any document that uses testdriver (and in the top-level test
+document when using testdriver from a different context):
+
+```html
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+```
+
+## API ##
+
+testdriver.js exposes its API through the `test_driver` variable in
+the global scope.
+
+### User Interaction ###
+
+```eval_rst
+.. js:autofunction:: test_driver.click
+.. js:autofunction:: test_driver.send_keys
+.. js:autofunction:: test_driver.action_sequence
+.. js:autofunction:: test_driver.bless
+```
+
+### Window State ###
+```eval_rst
+.. js:autofunction:: test_driver.minimize_window
+.. js:autofunction:: test_driver.set_window_rect
+```
+
+### Cookies ###
+```eval_rst
+.. js:autofunction:: test_driver.delete_all_cookies
+.. js:autofunction:: test_driver.get_all_cookies
+.. js:autofunction:: test_driver.get_named_cookie
+```
+
+### Permissions ###
+```eval_rst
+.. js:autofunction:: test_driver.set_permission
+```
+
+### Authentication ###
+
+```eval_rst
+.. js:autofunction:: test_driver.add_virtual_authenticator
+.. js:autofunction:: test_driver.remove_virtual_authenticator
+.. js:autofunction:: test_driver.add_credential
+.. js:autofunction:: test_driver.get_credentials
+.. js:autofunction:: test_driver.remove_credential
+.. js:autofunction:: test_driver.remove_all_credentials
+.. js:autofunction:: test_driver.set_user_verified
+```
+
+### Page Lifecycle ###
+```eval_rst
+.. js:autofunction:: test_driver.freeze
+```
+
+### Reporting Observer ###
+```eval_rst
+.. js:autofunction:: test_driver.generate_test_report
+```
+
+### Storage ###
+```eval_rst
+.. js:autofunction:: test_driver.set_storage_access
+
+```
+
+### Seure Payment Confirmation ###
+```eval_rst
+.. js:autofunction:: test_driver.set_spc_transaction_mode
+```
+
+### Using test_driver 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);
+}
+```
+
+```eval_rst
+.. js:autofunction:: test_driver.set_test_context
+.. js:autofunction:: test_driver.message_test
+```
+
+For cross-origin cases, passing in the `context` 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
+[`test_driver.set_test_context`](#test_driver.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 [`test_driver.message_test`](#test_driver.message_test)
+function that can be used to send arbitary messages to the test
+window. For example, in an auxillary browsing context:
+
+```js
+test_driver.set_test_context(window.opener)
+await test_driver.click(document.getElementsByTagName("button")[0])
+test_driver.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`.
+
+## Actions ##
+
+### Markup ###
+
+To use the [Actions](#Actions) API `testdriver-actions.js` must be
+included in the document, in addition to `testdriver.js`:
+
+```html
+<script src="/resources/testdriver-actions.js"></script>
+```
+
+### API ###
+
+```eval_rst
+.. js:autoclass:: Actions
+ :members:
+```
+
+
+### Using in other browsing contexts ###
+
+For the actions API, the context can be set using the `setContext`
+method on the builder:
+
+```js
+let actions = new test_driver.Actions()
+ .setContext(frames[0])
+ .keyDown("p")
+ .keyUp("p");
+await actions.send();
+```
+
+Note that if an action uses an element reference, the context will be
+derived from that element, and must match any explicitly set
+context. Using elements in multiple contexts in a single action chain
+is not supported.
+
+### send_keys
+
+Usage: `test_driver.send_keys(element, keys)`
+ * _element_: a DOM Element object
+ * _keys_: string to send to the element
+
+This function causes the string _keys_ to be sent to the target
+element (an `Element` object), potentially scrolling the document to
+make it possible to send keys. It returns a promise that resolves
+after the keys have been sent, or rejects if the keys cannot be sent
+to the element.
+
+This works with elements in other frames/windows as long as they are
+same-origin with the test, and the test does not depend on the
+window.name property remaining unset on the target window.
+
+Note that if the element that the keys need to be sent to does not have
+a unique ID, the document must not have any DOM mutations made
+between the function being called and the promise settling.
+
+To send special keys, one must send the respective key's codepoint. Since this uses the WebDriver protocol, you can find a [list for code points to special keys in the spec](https://w3c.github.io/webdriver/#keyboard-actions).
+For example, to send the tab key you would send "\uE004".
+
+_Note: these special-key codepoints are not necessarily what you would expect. For example, <kbd>Esc</kbd> is the invalid Unicode character `\uE00C`, not the `\u001B` Escape character from ASCII._
+
+[activation]: https://html.spec.whatwg.org/multipage/interaction.html#activation
+
+### set_permission
+
+Usage: `test_driver.set_permission(descriptor, state, context=null)`
+ * _descriptor_: a
+ [PermissionDescriptor](https://w3c.github.io/permissions/#dictdef-permissiondescriptor)
+ or derived object
+ * _state_: a
+ [PermissionState](https://w3c.github.io/permissions/#enumdef-permissionstate)
+ value
+ * 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
+return _state_. It returns a promise that resolves after the permission has
+been set to be overridden with _state_.
+
+Example:
+
+``` js
+await test_driver.set_permission({ name: "background-fetch" }, "denied");
+await test_driver.set_permission({ name: "push", userVisibleOnly: true }, "granted");
+```