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

[FedCM] Add testdriver support for FedCM #40006

Merged
merged 15 commits into from
May 25, 2023
11 changes: 11 additions & 0 deletions docs/writing-tests/testdriver.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ the global scope.
.. js:autofunction:: test_driver.set_spc_transaction_mode
```

### Federated Credential Management ###
```eval_rst
.. js:autofunction:: test_driver.cancel_fedcm_dialog
.. js:autofunction:: test_driver.select_fedcm_account
.. js:autofunction:: test_driver.get_fedcm_account_list
.. js:autofunction:: test_driver.get_fedcm_dialog_title
.. js:autofunction:: test_driver.get_fedcm_dialog_type
.. js:autofunction:: test_driver.set_fedcm_delay_enabled
.. js:autofunction:: test_driver.reset_fedcm_cooldown
```

### Using test_driver in other browsing contexts ###

Testdriver can be used in browsing contexts (i.e. windows or frames)
Expand Down
155 changes: 155 additions & 0 deletions resources/testdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,134 @@
set_spc_transaction_mode: function(mode, context=null) {
return window.test_driver_internal.set_spc_transaction_mode(mode, context);
},

/**
* Cancels the Federated Credential Management dialog
*
* Matches the `Cancel dialog
* <https://fedidcg.github.io/FedCM/#webdriver-canceldialog>`_
* 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 dialog is canceled, or rejected
* in case the WebDriver command errors
*/
cancel_fedcm_dialog: function(context=null) {
return window.test_driver_internal.cancel_fedcm_dialog(context);
},

/**
* Selects an account from the Federated Credential Management dialog
*
* Matches the `Select account
* <https://fedidcg.github.io/FedCM/#webdriver-selectaccount>`_
* WebDriver command.
*
* @param {number} account_index - Index of the account to select.
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} Fulfilled after the account is selected,
* or rejected in case the WebDriver command errors
*/
select_fedcm_account: function(account_index, context=null) {
return window.test_driver_internal.select_fedcm_account(account_index, context);
},

/**
* Gets the account list from the Federated Credential Management dialog
*
* Matches the `Account list
* <https://fedidcg.github.io/FedCM/#webdriver-accountlist>`_
* 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 account list is returned, or
* rejected in case the WebDriver command errors
*/
get_fedcm_account_list: function(context=null) {
return window.test_driver_internal.get_fedcm_account_list(context);
},

/**
* Gets the title of the Federated Credential Management dialog
*
* Matches the `Get title
* <https://fedidcg.github.io/FedCM/#webdriver-gettitle>`_
* 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 title is returned, or rejected
* in case the WebDriver command errors
*/
get_fedcm_dialog_title: function(context=null) {
return window.test_driver_internal.get_fedcm_dialog_title(context);
},

/**
* Gets the type of the Federated Credential Management dialog
*
* Matches the `Get dialog type
* <https://fedidcg.github.io/FedCM/#webdriver-getdialogtype>`_
* 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 dialog type is returned, or
* rejected in case the WebDriver command errors
*/
get_fedcm_dialog_type: function(context=null) {
return window.test_driver_internal.get_fedcm_dialog_type(context);
},

/**
* Sets whether promise rejection delay is enabled for the Federated Credential Management dialog
*
* Matches the `Set delay enabled
* <https://fedidcg.github.io/FedCM/#webdriver-setdelayenabled>`_
* WebDriver command.
*
* @param {boolean} enabled - Whether to delay FedCM promise rejection.
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} Fulfilled after the delay has been enabled or disabled,
* or rejected in case the WebDriver command errors
*/
set_fedcm_delay_enabled: function(enabled, context=null) {
return window.test_driver_internal.set_fedcm_delay_enabled(enabled, context);
},

/**
* Resets the Federated Credential Management dialog's cooldown
*
* Matches the `Reset cooldown
* <https://fedidcg.github.io/FedCM/#webdriver-resetcooldown>`_
* 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 cooldown has been reset,
* or rejected in case the WebDriver command errors
*/
reset_fedcm_cooldown: function(context=null) {
return window.test_driver_internal.reset_fedcm_cooldown(context);
}
};

window.test_driver_internal = {
Expand Down Expand Up @@ -805,5 +933,32 @@
throw new Error("set_spc_transaction_mode() is not implemented by testdriver-vendor.js");
},

async cancel_fedcm_dialog(context=null) {
throw new Error("cancel_fedcm_dialog() is not implemented by testdriver-vendor.js");
},

async select_fedcm_account(account_index, context=null) {
throw new Error("select_fedcm_account() is not implemented by testdriver-vendor.js");
},

async get_fedcm_account_list(context=null) {
throw new Error("get_fedcm_account_list() is not implemented by testdriver-vendor.js");
},

async get_fedcm_dialog_title(context=null) {
throw new Error("get_fedcm_dialog_title() is not implemented by testdriver-vendor.js");
},

async get_fedcm_dialog_type(context=null) {
throw new Error("get_fedcm_dialog_type() is not implemented by testdriver-vendor.js");
},

async set_fedcm_delay_enabled(enabled, context=null) {
throw new Error("set_fedcm_delay_enabled() is not implemented by testdriver-vendor.js");
},

async reset_fedcm_cooldown(context=null) {
throw new Error("reset_fedcm_cooldown() is not implemented by testdriver-vendor.js");
}
};
})();
88 changes: 87 additions & 1 deletion tools/wptrunner/wptrunner/executors/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,85 @@ def __call__(self, payload):
self.logger.debug("Setting SPC transaction mode to %s" % mode)
return self.protocol.spc_transactions.set_spc_transaction_mode(mode)

class CancelFedCMDialogAction:
name = "cancel_fedcm_dialog"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
self.logger.debug("Canceling FedCM dialog")
return self.protocol.fedcm.cancel_fedcm_dialog()

class SelectFedCMAccountAction:
name = "select_fedcm_account"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
account_index = payload["account_index"]
self.logger.debug(f"Selecting FedCM account of index: {account_index}")
return self.protocol.fedcm.select_fedcm_account(account_index)

class GetFedCMAccountListAction:
name = "get_fedcm_account_list"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
self.logger.debug("Getting FedCM account list")
return self.protocol.fedcm.get_fedcm_account_list()

class GetFedCMDialogTitleAction:
name = "get_fedcm_dialog_title"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
self.logger.debug("Getting FedCM dialog title")
return self.protocol.fedcm.get_fedcm_dialog_title()

class GetFedCMDialogTypeAction:
name = "get_fedcm_dialog_type"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
self.logger.debug("Getting FedCM dialog type")
return self.protocol.fedcm.get_fedcm_dialog_type()

class SetFedCMDelayEnabledAction:
name = "set_fedcm_delay_enabled"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
enabled = payload["enabled"]
self.logger.debug("Setting FedCM delay enabled as %s" % enabled)
return self.protocol.fedcm.set_fedcm_delay_enabled(enabled)

class ResetFedCMCooldownAction:
name = "reset_fedcm_cooldown"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
self.logger.debug("Resetting FedCM cooldown")
return self.protocol.fedcm.reset_fedcm_cooldown()

actions = [ClickAction,
DeleteAllCookiesAction,
GetAllCookiesAction,
Expand All @@ -296,4 +375,11 @@ def __call__(self, payload):
RemoveCredentialAction,
RemoveAllCredentialsAction,
SetUserVerifiedAction,
SetSPCTransactionModeAction]
SetSPCTransactionModeAction,
CancelFedCMDialogAction,
SelectFedCMAccountAction,
GetFedCMAccountListAction,
GetFedCMDialogTitleAction,
GetFedCMDialogTypeAction,
SetFedCMDelayEnabledAction,
ResetFedCMCooldownAction]
30 changes: 30 additions & 0 deletions tools/wptrunner/wptrunner/executors/executorwebdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
WindowProtocolPart,
DebugProtocolPart,
SPCTransactionsProtocolPart,
FedCMProtocolPart,
merge_dicts)

from webdriver.client import Session
Expand Down Expand Up @@ -347,6 +348,34 @@ def set_spc_transaction_mode(self, mode):
return self.webdriver.send_session_command("POST", "secure-payment-confirmation/set-mode", body)


class WebDriverFedCMProtocolPart(FedCMProtocolPart):
def setup(self):
self.webdriver = self.parent.webdriver

def cancel_fedcm_dialog(self):
return self.webdriver.send_session_command("POST", "fedcm/canceldialog")

def select_fedcm_account(self, account_index):
body = {"accountIndex": account_index}
return self.webdriver.send_session_command("POST", "fedcm/selectaccount", body)

def get_fedcm_account_list(self):
return self.webdriver.send_session_command("GET", "fedcm/accountlist")

def get_fedcm_dialog_title(self):
return self.webdriver.send_session_command("GET", "fedcm/gettitle")

def get_fedcm_dialog_type(self):
return self.webdriver.send_session_command("GET", "fedcm/getdialogtype")

def set_fedcm_delay_enabled(self, enabled):
body = {"enabled": enabled}
return self.webdriver.send_session_command("POST", "fedcm/setdelayenabled", body)

def reset_fedcm_cooldown(self):
return self.webdriver.send_session_command("POST", "fedcm/resetcooldown")


class WebDriverDebugProtocolPart(DebugProtocolPart):
def load_devtools(self):
raise NotImplementedError()
Expand All @@ -367,6 +396,7 @@ class WebDriverProtocol(Protocol):
WebDriverSetPermissionProtocolPart,
WebDriverVirtualAuthenticatorProtocolPart,
WebDriverSPCTransactionsProtocolPart,
WebDriverFedCMProtocolPart,
WebDriverDebugProtocolPart]

def __init__(self, executor, browser, capabilities, **kwargs):
Expand Down
46 changes: 46 additions & 0 deletions tools/wptrunner/wptrunner/executors/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,52 @@ def set_spc_transaction_mode(self, mode):
pass


class FedCMProtocolPart(ProtocolPart):
"""Protocol part for Federated Credential Management"""
__metaclass__ = ABCMeta

name = "fedcm"

@abstractmethod
def cancel_fedcm_dialog(self):
"""Cancel the FedCM dialog"""
pass

@abstractmethod
def select_fedcm_account(self, account_index):
"""Select a FedCM account

:param int account_index: The index of the account to select"""
pass

@abstractmethod
def get_fedcm_account_list(self):
"""Get the FedCM account list"""
pass

@abstractmethod
def get_fedcm_dialog_title(self):
"""Get the FedCM dialog title"""
pass

@abstractmethod
def get_fedcm_dialog_type(self):
"""Get the FedCM dialog type"""
pass

@abstractmethod
def set_fedcm_delay_enabled(self, enabled):
"""Sets the FedCM delay as enabled or disabled

:param bool enabled: The delay to set"""
pass

@abstractmethod
def reset_fedcm_cooldown(self):
"""Set the FedCM cooldown"""
pass


class PrintProtocolPart(ProtocolPart):
"""Protocol part for rendering to a PDF."""
__metaclass__ = ABCMeta
Expand Down
Loading