Skip to content
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

Add (or generate) typescript definitions for testdriver.js and other important files #130

Open
marcoscaceres opened this issue Dec 5, 2022 · 4 comments

Comments

@marcoscaceres
Copy link
Contributor

marcoscaceres commented Dec 5, 2022

Summary

Resources, such as testdriver.js, contain fantastic documentation and typescript compatible annotation information. It would be great if these were exported to .d.ts file(s) so they could be picked up by code editors.

Details

Because WPTests use absolute paths to script (and other reasons), the extremely useful documentation found in testdriver.js and other files can't be used by code editors, like VS Studio Code.

This means that people writing tests are missing out on all this valuable documentation and type checking information. Exposing such information would also catch test bugs, because it would could allow for TypeScript static checking.

It would also allow for introspection of test objects, to expose methods, signatures, properties, return types, etc.

What would be amazing would be if the testdriver.js annotations were in actual typescript files.

Risks

The typescript files getting out of sync with what's declared in the .js files. However, we could maybe include a warning that those files are automatically generated and shouldn't be touched (that is, if they can be automatically generated... I believe some can).

cc @saschanaz, who knows a lot more about TS than I do 🙇‍♀️

@jgraham
Copy link
Contributor

jgraham commented Dec 5, 2022

IIRC when I last updated this documentation there was an incompatibility with writing TypeScript directly in the documentation and what we were actually able to turn into documentation using the JSDoc+sphinx pipeline. I don't remember the details, but unless that's fixed it might be difficult to update the documentation to TypeScript. If it is fixed (or I'm misremebering the issue) I agree this would be a good idea.

@saschanaz
Copy link
Member

There is a TypeScript CLI way to generate a d.ts file from a JS file. That can be helpful.

@marcoscaceres
Copy link
Contributor Author

marcoscaceres commented Dec 5, 2022

As an initial strawperson, the simplest thing would be to just have class TestDriver{} and class TestDriverInternal{} declarations outside the anonymous self-executing functions, and move some of the utility functions as private members of TestDriver.

Then, just:

window.test_driver = new TestDriver();
window.test_driver_internal = new TestDriverInternal();

Running:

 npx -p typescript tsc resources/testdriver.js --declaration --allowJs --emitDeclarationOnly --outDir resources/

If that's not too egregious, that produces the following output:

declare class TestDriver {
    /**
     * Set the context in which testharness.js is loaded
     *
     * @param {WindowProxy} context - the window containing testharness.js
     **/
    set_test_context(context: WindowProxy): void;
    /**
     * postMessage to the context containing testharness.js
     *
     * @param {Object} msg - the data to POST
     **/
    message_test(msg: any): void;
    /**
     * Trigger user interaction in order to grant additional privileges to
     * a provided function.
     *
     * See `Tracking user activation
     * `_.
     *
     * @example
     * var mediaElement = document.createElement('video');
     *
     * test_driver.bless('initiate media playback', function () {
     *   mediaElement.play();
     * });
     *
     * @param {String} intent - a description of the action which must 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(intent: string, action: Function, context?: WindowProxy): Promise;
    /**
     * Triggers a user-initiated click
     *
     * If ``element`` isn't inside the
     * viewport, it will be scrolled into view before the click
     * occurs.
     *
     * If ``element`` is from a different browsing context, the
     * command will be run in that context.
     *
     * Matches the behaviour of the `Element Click
     * `_
     * WebDriver command.
     *
     * **Note:** If the element to be clicked does not have a
     * unique ID, the document must not have any DOM mutations
     * made between the function being called and the promise
     * settling.
     *
     * @param {Element} element - element to be clicked
     * @returns {Promise} fulfilled after click occurs, or rejected in
     *                    the cases the WebDriver command errors
     */
    click(element: Element): Promise;
    /**
     * Deletes all cookies.
     *
     * Matches the behaviour of the `Delete All Cookies
     * `_
     * WebDriver command.
     *
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     *
     * @returns {Promise} fulfilled after cookies are deleted, or rejected in
     *                    the cases the WebDriver command errors
     */
    delete_all_cookies(context?: WindowProxy): Promise;
    /**
     * Get details for all cookies in the current context.
     * See https://w3c.github.io/webdriver/#get-all-cookies
     *
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     *
     * @returns {Promise} Returns an array of cookies objects as defined in the spec:
     *                    https://w3c.github.io/webdriver/#cookies
     */
    get_all_cookies(context?: WindowProxy): Promise;
    /**
     * Get details for a cookie in the current context by name if it exists.
     * See https://w3c.github.io/webdriver/#get-named-cookie
     *
     * @param {String} name - The name of the cookie to get.
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     *
     * @returns {Promise} Returns the matching cookie as defined in the spec:
     *                    https://w3c.github.io/webdriver/#cookies
     *                    Rejected if no such cookie exists.
     */
    get_named_cookie(name: string, context?: WindowProxy): Promise;
    /**
     * Send keys to an element.
     *
     * If ``element`` isn't inside the
     * viewport, it will be scrolled into view before the click
     * occurs.
     *
     * If ``element`` is from a different browsing context, the
     * command will be run in that context.
     *
     * To send special keys, send the respective key's codepoint,
     * as defined by `WebDriver
     * `_.  For
     * example, the "tab" key is represented as "``\uE004``".
     *
     * **Note:** these special-key codepoints are not necessarily
     * what you would expect. For example, Esc is the
     * invalid Unicode character ``\uE00C``, not the ``\u001B`` Escape
     * character from ASCII.
     *
     * This matches the behaviour of the
     * `Send Keys
     * `_
     * WebDriver command.
     *
     * **Note:** If the element to be clicked does not have a
     * unique ID, the document must not have any DOM mutations
     * made between the function being called and the promise
     * settling.
     *
     * @param {Element} element - element to send keys to
     * @param {String} keys - keys to send to the element
     * @returns {Promise} fulfilled after keys are sent, or rejected in
     *                    the cases the WebDriver command errors
     */
    send_keys(element: Element, keys: string): Promise;
    /**
     * Freeze the current page
     *
     * The freeze function transitions the page from the HIDDEN state to
     * the FROZEN state as described in `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(context?: WindowProxy): Promise;
    /**
     * Minimizes the browser window.
     *
     * Matches the the behaviour of the `Minimize
     * `_
     * WebDriver command
     *
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     *
     * @returns {Promise} fulfilled with the previous {@link
     *                    https://www.w3.org/TR/webdriver/#dfn-windowrect-object|WindowRect}
     *                      value, after the window is minimized.
     */
    minimize_window(context?: WindowProxy): Promise;
    /**
     * Restore the window from minimized/maximized state to a given rect.
     *
     * Matches the behaviour of the `Set Window Rect
     * `_
     * WebDriver command
     *
     * @param {Object} rect - A {@link
     *                           https://www.w3.org/TR/webdriver/#dfn-windowrect-object|WindowRect}
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     *
     * @returns {Promise} fulfilled after the window is restored to the given rect.
     */
    set_window_rect(rect: any, context?: WindowProxy): Promise;
    /**
     * Send a sequence of actions
     *
     * This function sends a sequence of actions to perform.
     *
     * Matches the behaviour of the `Actions
     * `_ feature in
     * WebDriver.
     *
     * Authors are encouraged to use the
     * :js:class:`test_driver.Actions` builder rather than
     * invoking this API directly.
     *
     * @param {Array} actions - an array of actions. The format is
     *                          the same as the actions property
     *                          of the `Perform Actions
     *                          `_
     *                          WebDriver 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} fulfilled after the actions are performed, or rejected in
     *                    the cases the WebDriver command errors
     */
    action_sequence(actions: any[], context?: WindowProxy): Promise;
    /**
     * Generates a test report on the current page
     *
     * The generate_test_report function generates a report (to be
     * observed by ReportingObserver) for testing purposes.
     *
     * Matches the `Generate Test Report
     * `_
     * WebDriver 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(message: any, context?: WindowProxy): Promise;
    /**
     * Sets the state of a permission
     *
     * This function simulates a user setting a permission into a
     * particular state.
     *
     * Matches the `Set Permission
     * `_
     * WebDriver command.
     *
     * @example
     * await test_driver.set_permission({ name: "background-fetch" } "denied");
     * await test_driver.set_permission({ name: "push", userVisibleOnly: true } "granted");
     *
     * @param {PermissionDescriptor} descriptor - a `PermissionDescriptor
     *                              `_
     *                              dictionary.
     * @param {String} state - the state of the permission
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     * @returns {Promise} fulfilled after the permission is set, or rejected if setting the
     *                    permission fails
     */
    set_permission(descriptor: PermissionDescriptor, state: string, context?: WindowProxy): Promise;
    /**
     * Creates a virtual authenticator
     *
     * This function creates a virtual authenticator for use with
     * the U2F and WebAuthn APIs.
     *
     * Matches the `Add Virtual Authenticator
     * `_
     * WebDriver command.
     *
     * @param {Object} config - an `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(config: any, context?: WindowProxy): Promise;
    /**
     * Removes a virtual authenticator
     *
     * This function removes a virtual authenticator that has been
     * created by :js:func:`add_virtual_authenticator`.
     *
     * Matches the `Remove Virtual Authenticator
     * `_
     * WebDriver command.
     *
     * @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(authenticator_id: string, context?: WindowProxy): Promise;
    /**
     * Adds a credential to a virtual authenticator
     *
     * Matches the `Add Credential
     * `_
     * WebDriver command.
     *
     * @param {String} authenticator_id - the ID of the authenticator
     * @param {Object} credential - A `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(authenticator_id: string, credential: any, context?: WindowProxy): Promise;
    /**
     * Gets all the credentials stored in an authenticator
     *
     * This function retrieves all the credentials (added via the U2F API,
     * WebAuthn, or the add_credential function) stored in a virtual
     * authenticator
     *
     * Matches the `Get Credentials
     * `_
     * WebDriver command.
     *
     * @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 errors. Returns an
     *                    array of `Credential Parameters
     *                    `_
     */
    get_credentials(authenticator_id: string, context?: WindowProxy): Promise;
    /**
     * Remove a credential stored in an authenticator
     *
     * Matches the `Remove Credential
     * `_
     * WebDriver command.
     *
     * @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(authenticator_id: string, credential_id: string, context?: WindowProxy): Promise;
    /**
     * Removes all the credentials stored in a virtual authenticator
     *
     * Matches the `Remove All Credentials
     * `_
     * WebDriver command.
     *
     * @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(authenticator_id: string, context?: WindowProxy): Promise;
    /**
     * Sets the User Verified flag on an authenticator
     *
     * Sets whether requests requiring user verification will succeed or
     * fail on a given virtual authenticator
     *
     * Matches the `Set User Verified
     * `_
     * WebDriver command.
     *
     * @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(authenticator_id: string, uv: boolean, context?: WindowProxy): any;
    /**
     * Sets the storage access rule for an origin when embedded
     * in a third-party context.
     *
     * Matches the `Set Storage Access
     * `_
     * WebDriver command.
     *
     * @param {String} origin - A third-party origin to block or allow.
     *                          May be "*" to indicate all origins.
     * @param {String} embedding_origin - an embedding (first-party) origin
     *                                    on which {origin}'s access should
     *                                    be blocked or allowed.
     *                                    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(origin: string, embedding_origin: string, state: string, context?: WindowProxy): Promise;
    /**
     * Sets the current transaction automation mode for Secure Payment
     * Confirmation.
     *
     * This function places `Secure Payment
     * Confirmation `_ into
     * an automated 'autoaccept' or 'autoreject' mode, to allow testing
     * without user interaction with the transaction UX prompt.
     *
     * Matches the `Set SPC Transaction Mode
     * `_
     * WebDriver command.
     *
     * @example
     * await test_driver.set_spc_transaction_mode("autoaccept");
     * test.add_cleanup(() => {
     *   return test_driver.set_spc_transaction_mode("none");
     * });
     *
     * // Assumption: `request` is a PaymentRequest with a secure-payment-confirmation
     * // payment method.
     * const response = await request.show();
     *
     * @param {String} mode - The `transaction mode
     *                        `_
     *                        to set. Must be one of "``none``",
     *                        "``autoaccept``", or
     *                        "``autoreject``".
     * @param {WindowProxy} context - Browsing context in which
     *                                to run the call, or null for the current
     *                                browsing context.
     *
     * @returns {Promise} Fulfilled after the transaction mode has been set,
     *                    or rejected if setting the mode fails.
     */
    set_spc_transaction_mode(mode: string, context?: WindowProxy): Promise;
}
declare class TestDriverInternal {
    /**
     * This flag should be set to `true` by any code which implements the
     * internal methods defined below for automation purposes. Doing so
     * allows the library to signal failure immediately when an automated
     * implementation of one of the methods is not available.
     */
    in_automation: boolean;
    click(element: any, coords: any): any;
    delete_all_cookies(context?: any): any;
    get_all_cookies(context?: any): any;
    get_named_cookie(name: any, context?: any): any;
    send_keys(element: any, keys: any): any;
    freeze(context?: any): any;
    minimize_window(context?: any): any;
    set_window_rect(rect: any, context?: any): any;
    action_sequence(actions: any, context?: any): any;
    generate_test_report(message: any, context?: any): any;
    set_permission(permission_params: any, context?: any): any;
    add_virtual_authenticator(config: any, context?: any): any;
    remove_virtual_authenticator(authenticator_id: any, context?: any): any;
    add_credential(authenticator_id: any, credential: any, context?: any): any;
    get_credentials(authenticator_id: any, context?: any): any;
    remove_credential(authenticator_id: any, credential_id: any, context?: any): any;
    remove_all_credentials(authenticator_id: any, context?: any): any;
    set_user_verified(authenticator_id: any, uv: any, context?: any): any;
    set_storage_access(origin: any, embedding_origin: any, blocked: any, context?: any): any;
    set_spc_transaction_mode(mode: any, context?: any): any;
}

@saschanaz
Copy link
Member

Looks promising!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants