зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1264259
- [marionette] Add support for unhandledPromptBehavior capability. r=ato
The handling of user prompts for each of the commands is set by the current sessions user prompt handler. To fully support this feature this patch adds support for it including all available options which are "accept", "accept and notify", "dismiss", "dismiss and notify", and "ignore". MozReview-Commit-ID: IWuYM7QfZUv --HG-- extra : rebase_source : 56726bab5aaa29ad629d22247ab2b5409ca83bb8
This commit is contained in:
Родитель
7e85fbddc9
Коммит
0c86782bb8
|
@ -23,6 +23,7 @@ this.EXPORTED_SYMBOLS = [
|
|||
"PageLoadStrategy",
|
||||
"Proxy",
|
||||
"Timeouts",
|
||||
"UnhandledPromptBehavior",
|
||||
];
|
||||
|
||||
// Enable testing this module, as Services.appinfo.* is not available
|
||||
|
@ -357,6 +358,30 @@ class Proxy {
|
|||
toString() { return "[object Proxy]"; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum of unhandled prompt behavior.
|
||||
*
|
||||
* @enum
|
||||
*/
|
||||
const UnhandledPromptBehavior = {
|
||||
/** All simple dialogs encountered should be accepted. */
|
||||
Accept: "accept",
|
||||
/**
|
||||
* All simple dialogs encountered should be accepted, and an error
|
||||
* returned that the dialog was handled.
|
||||
*/
|
||||
AcceptAndNotify: "accept and notify",
|
||||
/** All simple dialogs encountered should be dismissed. */
|
||||
Dismiss: "dismiss",
|
||||
/**
|
||||
* All simple dialogs encountered should be dismissed, and an error
|
||||
* returned that the dialog was handled.
|
||||
*/
|
||||
DismissAndNotify: "dismiss and notify",
|
||||
/** All simple dialogs encountered should be left to the user to handle. */
|
||||
Ignore: "ignore",
|
||||
};
|
||||
|
||||
/** WebDriver session capabilities representation. */
|
||||
class Capabilities extends Map {
|
||||
/** @class */
|
||||
|
@ -367,10 +392,11 @@ class Capabilities extends Map {
|
|||
["browserVersion", appinfo.version],
|
||||
["platformName", getWebDriverPlatformName()],
|
||||
["platformVersion", Services.sysinfo.getProperty("version")],
|
||||
["pageLoadStrategy", PageLoadStrategy.Normal],
|
||||
["acceptInsecureCerts", false],
|
||||
["timeouts", new Timeouts()],
|
||||
["pageLoadStrategy", PageLoadStrategy.Normal],
|
||||
["proxy", new Proxy()],
|
||||
["timeouts", new Timeouts()],
|
||||
["unhandledPromptBehavior", UnhandledPromptBehavior.DismissAndNotify],
|
||||
|
||||
// features
|
||||
["rotatable", appinfo.name == "B2G"],
|
||||
|
@ -470,6 +496,19 @@ class Capabilities extends Map {
|
|||
matched.set("timeouts", timeouts);
|
||||
break;
|
||||
|
||||
case "unhandledPromptBehavior":
|
||||
assert.string(v,
|
||||
pprint`Expected ${k} to be a string, got ${v}`);
|
||||
|
||||
if (Object.values(UnhandledPromptBehavior).includes(v)) {
|
||||
matched.set("unhandledPromptBehavior", v);
|
||||
} else {
|
||||
throw new InvalidArgumentError(
|
||||
`Unknown unhandled prompt behavior: ${v}`);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "moz:accessibilityChecks":
|
||||
assert.boolean(v,
|
||||
pprint`Expected ${k} to be a boolean, got ${v}`);
|
||||
|
@ -498,6 +537,7 @@ this.Capabilities = Capabilities;
|
|||
this.PageLoadStrategy = PageLoadStrategy;
|
||||
this.Proxy = Proxy;
|
||||
this.Timeouts = Timeouts;
|
||||
this.UnhandledPromptBehavior = UnhandledPromptBehavior;
|
||||
|
||||
function getWebDriverPlatformName() {
|
||||
let name = Services.sysinfo.getProperty("name");
|
||||
|
|
|
@ -20,6 +20,7 @@ const {
|
|||
const {
|
||||
Capabilities,
|
||||
Timeouts,
|
||||
UnhandledPromptBehavior,
|
||||
} = ChromeUtils.import("chrome://marionette/content/capabilities.js", {});
|
||||
ChromeUtils.import("chrome://marionette/content/capture.js");
|
||||
const {
|
||||
|
@ -41,6 +42,7 @@ const {
|
|||
NoSuchFrameError,
|
||||
NoSuchWindowError,
|
||||
SessionNotCreatedError,
|
||||
UnexpectedAlertOpenError,
|
||||
UnknownError,
|
||||
UnsupportedOperationError,
|
||||
WebDriverError,
|
||||
|
@ -1068,7 +1070,7 @@ GeckoDriver.prototype.execute_ = async function(
|
|||
GeckoDriver.prototype.get = async function(cmd) {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let url = cmd.parameters.url;
|
||||
|
||||
|
@ -1110,7 +1112,7 @@ GeckoDriver.prototype.get = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getCurrentUrl = function() {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
return this.currentURL.toString();
|
||||
};
|
||||
|
@ -1128,7 +1130,7 @@ GeckoDriver.prototype.getCurrentUrl = function() {
|
|||
*/
|
||||
GeckoDriver.prototype.getTitle = function() {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
return this.title;
|
||||
};
|
||||
|
@ -1154,7 +1156,7 @@ GeckoDriver.prototype.getWindowType = function() {
|
|||
*/
|
||||
GeckoDriver.prototype.getPageSource = async function() {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
switch (this.context) {
|
||||
case Context.Chrome:
|
||||
|
@ -1183,7 +1185,7 @@ GeckoDriver.prototype.getPageSource = async function() {
|
|||
GeckoDriver.prototype.goBack = async function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.curBrowser);
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
// If there is no history, just return
|
||||
if (!this.curBrowser.contentBrowser.webNavigation.canGoBack) {
|
||||
|
@ -1225,7 +1227,7 @@ GeckoDriver.prototype.goBack = async function() {
|
|||
GeckoDriver.prototype.goForward = async function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.curBrowser);
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
// If there is no history, just return
|
||||
if (!this.curBrowser.contentBrowser.webNavigation.canGoForward) {
|
||||
|
@ -1268,7 +1270,7 @@ GeckoDriver.prototype.goForward = async function() {
|
|||
GeckoDriver.prototype.refresh = async function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let refresh = this.listener.refresh(
|
||||
{pageTimeout: this.timeouts.pageLoad});
|
||||
|
@ -1411,7 +1413,7 @@ GeckoDriver.prototype.getChromeWindowHandles = function() {
|
|||
*/
|
||||
GeckoDriver.prototype.getWindowRect = function() {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
return this.curBrowser.rect;
|
||||
};
|
||||
|
@ -1449,7 +1451,7 @@ GeckoDriver.prototype.getWindowRect = function() {
|
|||
GeckoDriver.prototype.setWindowRect = async function(cmd) {
|
||||
assert.firefox();
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {x, y, width, height} = cmd.parameters;
|
||||
let origRect = this.curBrowser.rect;
|
||||
|
@ -1677,7 +1679,7 @@ GeckoDriver.prototype.getActiveFrame = function() {
|
|||
*/
|
||||
GeckoDriver.prototype.switchToParentFrame = async function() {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
await this.listener.switchToParentFrame();
|
||||
};
|
||||
|
@ -1698,7 +1700,7 @@ GeckoDriver.prototype.switchToParentFrame = async function() {
|
|||
*/
|
||||
GeckoDriver.prototype.switchToFrame = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {id, focus} = cmd.parameters;
|
||||
|
||||
|
@ -1913,7 +1915,7 @@ GeckoDriver.prototype.performActions = async function(cmd) {
|
|||
assert.content(this.context,
|
||||
"Command 'performActions' is not yet available in chrome context");
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let actions = cmd.parameters.actions;
|
||||
await this.listener.performActions({"actions": actions});
|
||||
|
@ -1932,7 +1934,7 @@ GeckoDriver.prototype.performActions = async function(cmd) {
|
|||
GeckoDriver.prototype.releaseActions = async function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
await this.listener.releaseActions();
|
||||
};
|
||||
|
@ -1956,7 +1958,7 @@ GeckoDriver.prototype.releaseActions = async function() {
|
|||
*/
|
||||
GeckoDriver.prototype.actionChain = async function(cmd) {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {chain, nextId} = cmd.parameters;
|
||||
|
||||
|
@ -1995,7 +1997,7 @@ GeckoDriver.prototype.actionChain = async function(cmd) {
|
|||
GeckoDriver.prototype.multiAction = async function(cmd) {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {value, max_length} = cmd.parameters; // eslint-disable-line camelcase
|
||||
await this.listener.multiAction(value, max_length);
|
||||
|
@ -2016,7 +2018,7 @@ GeckoDriver.prototype.multiAction = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.findElement = async function(cmd) {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {using, value} = cmd.parameters;
|
||||
let startNode;
|
||||
|
@ -2115,7 +2117,7 @@ GeckoDriver.prototype.findElements = async function(cmd) {
|
|||
GeckoDriver.prototype.getActiveElement = async function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
return this.listener.getActiveElement();
|
||||
};
|
||||
|
@ -2137,7 +2139,7 @@ GeckoDriver.prototype.getActiveElement = async function() {
|
|||
*/
|
||||
GeckoDriver.prototype.clickElement = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2196,7 +2198,7 @@ GeckoDriver.prototype.clickElement = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getElementAttribute = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let name = assert.string(cmd.parameters.name);
|
||||
|
@ -2237,7 +2239,7 @@ GeckoDriver.prototype.getElementAttribute = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getElementProperty = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let name = assert.string(cmd.parameters.name);
|
||||
|
@ -2277,7 +2279,7 @@ GeckoDriver.prototype.getElementProperty = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getElementText = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2318,7 +2320,7 @@ GeckoDriver.prototype.getElementText = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getElementTagName = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2356,7 +2358,7 @@ GeckoDriver.prototype.getElementTagName = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.isElementDisplayed = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2396,7 +2398,7 @@ GeckoDriver.prototype.isElementDisplayed = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getElementValueOfCssProperty = async function(cmd) {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let prop = assert.string(cmd.parameters.propertyName);
|
||||
|
@ -2436,7 +2438,7 @@ GeckoDriver.prototype.getElementValueOfCssProperty = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.isElementEnabled = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2475,7 +2477,7 @@ GeckoDriver.prototype.isElementEnabled = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.isElementSelected = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2506,7 +2508,7 @@ GeckoDriver.prototype.isElementSelected = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.getElementRect = async function(cmd) {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2549,7 +2551,7 @@ GeckoDriver.prototype.getElementRect = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.sendKeysToElement = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let text = assert.string(cmd.parameters.text);
|
||||
|
@ -2587,7 +2589,7 @@ GeckoDriver.prototype.sendKeysToElement = async function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.clearElement = async function(cmd) {
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let id = assert.string(cmd.parameters.id);
|
||||
let webEl = WebElement.fromUUID(id, this.context);
|
||||
|
@ -2656,7 +2658,7 @@ GeckoDriver.prototype.switchToShadowRoot = async function(cmd) {
|
|||
GeckoDriver.prototype.addCookie = function(cmd) {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {protocol, hostname} = this.currentURL;
|
||||
|
||||
|
@ -2686,7 +2688,7 @@ GeckoDriver.prototype.addCookie = function(cmd) {
|
|||
GeckoDriver.prototype.getCookies = function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {hostname, pathname} = this.currentURL;
|
||||
return [...cookie.iter(hostname, pathname)];
|
||||
|
@ -2705,7 +2707,7 @@ GeckoDriver.prototype.getCookies = function() {
|
|||
GeckoDriver.prototype.deleteAllCookies = function() {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {hostname, pathname} = this.currentURL;
|
||||
for (let toDelete of cookie.iter(hostname, pathname)) {
|
||||
|
@ -2726,7 +2728,7 @@ GeckoDriver.prototype.deleteAllCookies = function() {
|
|||
GeckoDriver.prototype.deleteCookie = function(cmd) {
|
||||
assert.content(this.context);
|
||||
assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let {hostname, pathname} = this.currentURL;
|
||||
let name = assert.string(cmd.parameters.name);
|
||||
|
@ -2756,7 +2758,7 @@ GeckoDriver.prototype.deleteCookie = function(cmd) {
|
|||
*/
|
||||
GeckoDriver.prototype.close = async function() {
|
||||
assert.open(this.getCurrentWindow(Context.Content));
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
let nwins = 0;
|
||||
|
||||
|
@ -3009,7 +3011,7 @@ GeckoDriver.prototype.setScreenOrientation = function(cmd) {
|
|||
GeckoDriver.prototype.minimizeWindow = async function() {
|
||||
assert.firefox();
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
if (WindowState.from(win.windowState) == WindowState.Fullscreen) {
|
||||
await exitFullscreen(win);
|
||||
|
@ -3046,7 +3048,7 @@ GeckoDriver.prototype.minimizeWindow = async function() {
|
|||
GeckoDriver.prototype.maximizeWindow = async function() {
|
||||
assert.firefox();
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
switch (WindowState.from(win.windowState)) {
|
||||
case WindowState.Fullscreen:
|
||||
|
@ -3132,7 +3134,7 @@ GeckoDriver.prototype.maximizeWindow = async function() {
|
|||
GeckoDriver.prototype.fullscreenWindow = async function() {
|
||||
assert.firefox();
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
this._assertAndDismissModal();
|
||||
this._handleUserPrompts();
|
||||
|
||||
if (WindowState.from(win.windowState) == WindowState.Minimized) {
|
||||
await restoreWindow(win, this.curBrowser.eventObserver);
|
||||
|
@ -3216,16 +3218,38 @@ GeckoDriver.prototype.sendKeysToDialog = async function(cmd) {
|
|||
|
||||
GeckoDriver.prototype._checkIfAlertIsPresent = function() {
|
||||
if (!this.dialog || !this.dialog.ui) {
|
||||
throw new NoSuchAlertError("No modal dialog is currently open");
|
||||
throw new NoSuchAlertError();
|
||||
}
|
||||
};
|
||||
|
||||
GeckoDriver.prototype._assertAndDismissModal = function() {
|
||||
try {
|
||||
assert.noUserPrompt(this.dialog);
|
||||
} catch (e) {
|
||||
this.dismissDialog();
|
||||
throw e;
|
||||
GeckoDriver.prototype._handleUserPrompts = function() {
|
||||
if (!this.dialog || !this.dialog.ui) {
|
||||
return;
|
||||
}
|
||||
|
||||
let behavior = this.capabilities.get("unhandledPromptBehavior");
|
||||
switch (behavior) {
|
||||
case UnhandledPromptBehavior.Accept:
|
||||
this.acceptDialog();
|
||||
break;
|
||||
|
||||
case UnhandledPromptBehavior.AcceptAndNotify:
|
||||
this.acceptDialog();
|
||||
throw new UnexpectedAlertOpenError();
|
||||
|
||||
case UnhandledPromptBehavior.Dismiss:
|
||||
this.dismissDialog();
|
||||
break;
|
||||
|
||||
case UnhandledPromptBehavior.DismissAndNotify:
|
||||
this.dismissDialog();
|
||||
throw new UnexpectedAlertOpenError();
|
||||
|
||||
case UnhandledPromptBehavior.Ignore:
|
||||
throw new UnexpectedAlertOpenError();
|
||||
|
||||
default:
|
||||
throw new TypeError(`Unknown unhandledPromptBehavior "${behavior}"`);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -160,3 +160,33 @@ class TestCapabilityMatching(MarionetteTestCase):
|
|||
self.assertIn("timeouts", self.marionette.session_capabilities)
|
||||
self.assertDictEqual(self.marionette.session_capabilities["timeouts"], timeouts)
|
||||
self.assertDictEqual(self.marionette._send_message("getTimeouts"), timeouts)
|
||||
|
||||
def test_unhandled_prompt_behavior(self):
|
||||
behaviors = [
|
||||
"accept",
|
||||
"accept and notify",
|
||||
"dismiss",
|
||||
"dismiss and notify",
|
||||
"ignore"
|
||||
]
|
||||
|
||||
for behavior in behaviors:
|
||||
print("valid unhandled prompt behavior {}".format(behavior))
|
||||
self.delete_session()
|
||||
self.marionette.start_session({"unhandledPromptBehavior": behavior})
|
||||
self.assertEqual(self.marionette.session_capabilities["unhandledPromptBehavior"],
|
||||
behavior)
|
||||
|
||||
# Default value
|
||||
self.delete_session()
|
||||
self.marionette.start_session()
|
||||
self.assertEqual(self.marionette.session_capabilities["unhandledPromptBehavior"],
|
||||
"dismiss and notify")
|
||||
|
||||
# Invalid values
|
||||
self.delete_session()
|
||||
for behavior in [None, "", "ACCEPT", True, 42, {}, []]:
|
||||
print("invalid unhandled prompt behavior {}".format(behavior))
|
||||
with self.assertRaisesRegexp(SessionNotCreatedException, "InvalidArgumentError"):
|
||||
self.marionette.start_session({"unhandledPromptBehavior": behavior})
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ from marionette_harness import MarionetteTestCase, WindowManagerMixin
|
|||
|
||||
class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
|
||||
|
||||
@property
|
||||
def alert_present(self):
|
||||
try:
|
||||
Alert(self.marionette).text
|
||||
|
@ -24,11 +25,11 @@ class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
|
|||
|
||||
def wait_for_alert(self, timeout=None):
|
||||
Wait(self.marionette, timeout=timeout).until(
|
||||
lambda _: self.alert_present())
|
||||
lambda _: self.alert_present)
|
||||
|
||||
def wait_for_alert_closed(self, timeout=None):
|
||||
Wait(self.marionette, timeout=timeout).until(
|
||||
lambda _: not self.alert_present())
|
||||
lambda _: not self.alert_present)
|
||||
|
||||
|
||||
class TestTabModalAlerts(BaseAlertTestCase):
|
||||
|
@ -38,7 +39,8 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
self.assertTrue(self.marionette.get_pref("prompts.tab_modal.enabled",
|
||||
"Tab modal alerts should be enabled by default."))
|
||||
|
||||
self.marionette.navigate(self.marionette.absolute_url("test_tab_modal_dialogs.html"))
|
||||
self.test_page = self.marionette.absolute_url("test_tab_modal_dialogs.html")
|
||||
self.marionette.navigate(self.test_page)
|
||||
|
||||
def tearDown(self):
|
||||
# Ensure to close a possible remaining tab modal dialog
|
||||
|
@ -183,7 +185,7 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
with self.assertRaises(errors.UnexpectedAlertOpen):
|
||||
self.marionette.find_element(By.ID, "click-result")
|
||||
|
||||
assert not self.alert_present()
|
||||
assert not self.alert_present
|
||||
|
||||
|
||||
class TestModalAlerts(BaseAlertTestCase):
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from marionette_driver import errors
|
||||
from marionette_driver.marionette import Alert
|
||||
from marionette_driver.wait import Wait
|
||||
from marionette_harness import MarionetteTestCase, parameterized
|
||||
|
||||
|
||||
class TestUnhandledPromptBehavior(MarionetteTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestUnhandledPromptBehavior, self).setUp()
|
||||
|
||||
self.marionette.delete_session()
|
||||
|
||||
def tearDown(self):
|
||||
# Ensure to close a possible remaining tab modal dialog
|
||||
try:
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
|
||||
Wait(self.marionette).until(lambda _: not self.alert_present)
|
||||
except errors.NoAlertPresentException:
|
||||
pass
|
||||
|
||||
super(TestUnhandledPromptBehavior, self).tearDown()
|
||||
|
||||
@property
|
||||
def alert_present(self):
|
||||
try:
|
||||
Alert(self.marionette).text
|
||||
return True
|
||||
except errors.NoAlertPresentException:
|
||||
return False
|
||||
|
||||
def perform_user_prompt_check(self, prompt_type, text, expected_result,
|
||||
expected_close=True, expected_notify=True):
|
||||
if prompt_type not in ["alert", "confirm", "prompt"]:
|
||||
raise TypeError("Invalid dialog type: {}".format(prompt_type))
|
||||
|
||||
# No need to call resolve() because opening a prompt stops the script
|
||||
self.marionette.execute_async_script("""
|
||||
window.return_value = null;
|
||||
window.return_value = window[arguments[0]](arguments[1]);
|
||||
""", script_args=(prompt_type, text))
|
||||
|
||||
if expected_notify:
|
||||
with self.assertRaises(errors.UnexpectedAlertOpen):
|
||||
self.marionette.title
|
||||
# Bug 1469752 - WebDriverError misses optional data property
|
||||
# self.assertEqual(ex.data.text, text)
|
||||
else:
|
||||
self.marionette.title
|
||||
|
||||
self.assertEqual(self.alert_present, not expected_close)
|
||||
|
||||
prompt_result = self.marionette.execute_script(
|
||||
"return window.return_value", new_sandbox=False)
|
||||
self.assertEqual(prompt_result, expected_result)
|
||||
|
||||
@parameterized("alert", "alert", None)
|
||||
@parameterized("confirm", "confirm", True)
|
||||
@parameterized("prompt", "prompt", "")
|
||||
def test_accept(self, prompt_type, result):
|
||||
self.marionette.start_session({"unhandledPromptBehavior": "accept"})
|
||||
self.perform_user_prompt_check(prompt_type, "foo {}".format(prompt_type), result,
|
||||
expected_notify=False)
|
||||
|
||||
@parameterized("alert", "alert", None)
|
||||
@parameterized("confirm", "confirm", True)
|
||||
@parameterized("prompt", "prompt", "")
|
||||
def test_accept_and_notify(self, prompt_type, result):
|
||||
self.marionette.start_session({"unhandledPromptBehavior": "accept and notify"})
|
||||
self.perform_user_prompt_check(prompt_type, "foo {}".format(prompt_type), result)
|
||||
|
||||
@parameterized("alert", "alert", None)
|
||||
@parameterized("confirm", "confirm", False)
|
||||
@parameterized("prompt", "prompt", None)
|
||||
def test_dismiss(self, prompt_type, result):
|
||||
self.marionette.start_session({"unhandledPromptBehavior": "dismiss"})
|
||||
self.perform_user_prompt_check(prompt_type, "foo {}".format(prompt_type), result,
|
||||
expected_notify=False)
|
||||
|
||||
@parameterized("alert", "alert", None)
|
||||
@parameterized("confirm", "confirm", False)
|
||||
@parameterized("prompt", "prompt", None)
|
||||
def test_dismiss_and_notify(self, prompt_type, result):
|
||||
self.marionette.start_session({"unhandledPromptBehavior": "dismiss and notify"})
|
||||
self.perform_user_prompt_check(prompt_type, "foo {}".format(prompt_type), result)
|
||||
|
||||
@parameterized("alert", "alert", None)
|
||||
@parameterized("confirm", "confirm", None)
|
||||
@parameterized("prompt", "prompt", None)
|
||||
def test_ignore(self, prompt_type, result):
|
||||
self.marionette.start_session({"unhandledPromptBehavior": "ignore"})
|
||||
self.perform_user_prompt_check(prompt_type, "foo {}".format(prompt_type), result,
|
||||
expected_close=False)
|
||||
|
||||
@parameterized("alert", "alert", None)
|
||||
@parameterized("confirm", "confirm", False)
|
||||
@parameterized("prompt", "prompt", None)
|
||||
def test_default(self, prompt_type, result):
|
||||
self.marionette.start_session({})
|
||||
self.perform_user_prompt_check(prompt_type, "foo {}".format(prompt_type), result)
|
|
@ -99,6 +99,9 @@ skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921
|
|||
|
||||
[test_modal_dialogs.py]
|
||||
skip-if = appname == 'fennec' # Bug 1325738
|
||||
[test_unhandled_prompt_behavior.py]
|
||||
skip-if = appname == 'fennec' # Bug 1325738
|
||||
|
||||
[test_key_actions.py]
|
||||
[test_legacy_mouse_action.py]
|
||||
skip-if = appname == 'fennec'
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Marionette Test</title>
|
||||
<title>Dialog Test</title>
|
||||
<script type="text/javascript">
|
||||
function handleAlert () {
|
||||
window.alert('Marionette alert');
|
||||
|
|
|
@ -13,6 +13,7 @@ const {
|
|||
PageLoadStrategy,
|
||||
Proxy,
|
||||
Timeouts,
|
||||
UnhandledPromptBehavior,
|
||||
} = ChromeUtils.import("chrome://marionette/content/capabilities.js", {});
|
||||
|
||||
add_test(function test_Timeouts_ctor() {
|
||||
|
@ -366,6 +367,16 @@ add_test(function test_Proxy_fromJSON() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_UnhandledPromptBehavior() {
|
||||
equal(UnhandledPromptBehavior.Accept, "accept");
|
||||
equal(UnhandledPromptBehavior.AcceptAndNotify, "accept and notify");
|
||||
equal(UnhandledPromptBehavior.Dismiss, "dismiss");
|
||||
equal(UnhandledPromptBehavior.DismissAndNotify, "dismiss and notify");
|
||||
equal(UnhandledPromptBehavior.Ignore, "ignore");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_Capabilities_ctor() {
|
||||
let caps = new Capabilities();
|
||||
ok(caps.has("browserName"));
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
|
@ -1,9 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
|
@ -1,33 +1,6 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if webrender: bug 1425588
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_ignore[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_ignore[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_ignore[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_twice[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
disabled: Bug 1459118
|
||||
|
|
|
@ -1,33 +1,6 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if webrender: bug 1425588
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_ignore[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_ignore[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_ignore[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_twice[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
disabled: Bug 1459118
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
|
@ -1,9 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
|
@ -1,20 +1,3 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if webrender: bug 1425588
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if webrender: bug 1425588
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if webrender: bug 1425588
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): wpt-sync Bug 1446953
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_dismiss[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_dismiss[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
|
@ -1,12 +1,3 @@
|
|||
[user_prompts.py]
|
||||
disabled:
|
||||
if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): wpt-sync Bug 1449780
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
[user_prompts.py]
|
||||
[test_handle_prompt_accept[capabilities0-alert\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-confirm\]]
|
||||
expected: FAIL
|
||||
|
||||
[test_handle_prompt_accept[capabilities0-prompt\]]
|
||||
expected: FAIL
|
||||
|
Загрузка…
Ссылка в новой задаче