зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1654454 - [marionette] Port WebDriver:FindElement and WebDriver:FindElements to JSWindowActor. r=marionette-reviewers,maja_zf
Differential Revision: https://phabricator.services.mozilla.com/D84568
This commit is contained in:
Родитель
3f547b9d29
Коммит
201cbd12be
|
@ -10,11 +10,28 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
const { element } = ChromeUtils.import(
|
||||
"chrome://marionette/content/element.js"
|
||||
);
|
||||
const { error } = ChromeUtils.import("chrome://marionette/content/error.js");
|
||||
const { evaluate } = ChromeUtils.import(
|
||||
"chrome://marionette/content/evaluate.js"
|
||||
);
|
||||
const { Log } = ChromeUtils.import("chrome://marionette/content/log.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "logger", Log.get);
|
||||
|
||||
class MarionetteFrameChild extends JSWindowActorChild {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.seenEls = new element.Store();
|
||||
}
|
||||
|
||||
get content() {
|
||||
return this.docShell.domWindow;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.browsingContext.id;
|
||||
}
|
||||
|
@ -43,4 +60,65 @@ class MarionetteFrameChild extends JSWindowActorChild {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async receiveMessage(msg) {
|
||||
const { name, data: serializedData } = msg;
|
||||
const data = evaluate.fromJSON(serializedData);
|
||||
|
||||
try {
|
||||
let result;
|
||||
|
||||
switch (name) {
|
||||
case "MarionetteFrameParent:findElement":
|
||||
result = await this.findElement(data);
|
||||
break;
|
||||
case "MarionetteFrameParent:findElements":
|
||||
result = await this.findElements(data);
|
||||
break;
|
||||
}
|
||||
|
||||
return { data: evaluate.toJSON(result) };
|
||||
} catch (e) {
|
||||
// Always wrap errors as WebDriverError
|
||||
return { error: error.wrap(e).toJSON() };
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of WebDriver commands
|
||||
|
||||
/**
|
||||
* Find an element in the current browsing context's document using the
|
||||
* given search strategy.
|
||||
*/
|
||||
async findElement(options = {}) {
|
||||
const { strategy, selector, opts } = options;
|
||||
|
||||
opts.all = false;
|
||||
|
||||
if (opts.startNode) {
|
||||
opts.startNode = this.seenEls.get(opts.startNode);
|
||||
}
|
||||
|
||||
const container = { frame: this.content };
|
||||
const el = await element.find(container, strategy, selector, opts);
|
||||
return this.seenEls.add(el);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find elements in the current browsing context's document using the
|
||||
* given search strategy.
|
||||
*/
|
||||
async findElements(options = {}) {
|
||||
const { strategy, selector, opts } = options;
|
||||
|
||||
opts.all = true;
|
||||
|
||||
if (opts.startNode) {
|
||||
opts.startNode = this.seenEls.get(opts.startNode);
|
||||
}
|
||||
|
||||
const container = { frame: this.content };
|
||||
const el = await element.find(container, strategy, selector, opts);
|
||||
return this.seenEls.addAll(el);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
("use strict");
|
||||
|
||||
const EXPORTED_SYMBOLS = ["MarionetteFrameParent"];
|
||||
|
||||
|
@ -14,6 +14,12 @@ const { EventEmitter } = ChromeUtils.import(
|
|||
"resource://gre/modules/EventEmitter.jsm"
|
||||
);
|
||||
|
||||
const { WebDriverError } = ChromeUtils.import(
|
||||
"chrome://marionette/content/error.js"
|
||||
);
|
||||
const { evaluate } = ChromeUtils.import(
|
||||
"chrome://marionette/content/evaluate.js"
|
||||
);
|
||||
const { Log } = ChromeUtils.import("chrome://marionette/content/log.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "logger", Log.get);
|
||||
|
@ -29,11 +35,43 @@ class MarionetteFrameParent extends JSWindowActorParent {
|
|||
logger.trace(`[${this.browsingContext.id}] Parent actor created`);
|
||||
}
|
||||
|
||||
receiveMessage({ name, data }) {
|
||||
receiveMessage(msg) {
|
||||
const { name, data } = msg;
|
||||
|
||||
switch (name) {
|
||||
case "MarionetteFrameChild:PageLoadEvent":
|
||||
this.emit("page-load-event", data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async sendQuery(name, data) {
|
||||
const serializedData = evaluate.toJSON(data);
|
||||
const result = await super.sendQuery(name, serializedData);
|
||||
|
||||
if ("error" in result) {
|
||||
throw WebDriverError.fromJSON(result.error);
|
||||
} else {
|
||||
return evaluate.fromJSON(result.data);
|
||||
}
|
||||
}
|
||||
|
||||
// Proxying methods for WebDriver commands
|
||||
// TODO: Maybe using a proxy class instead similar to proxy.js
|
||||
|
||||
findElement(strategy, selector, opts) {
|
||||
return this.sendQuery("MarionetteFrameParent:findElement", {
|
||||
strategy,
|
||||
selector,
|
||||
opts,
|
||||
});
|
||||
}
|
||||
|
||||
findElements(strategy, selector, opts) {
|
||||
return this.sendQuery("MarionetteFrameParent:findElements", {
|
||||
strategy,
|
||||
selector,
|
||||
opts,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2053,16 +2053,18 @@ GeckoDriver.prototype.multiAction = async function(cmd) {
|
|||
* A modal dialog is open, blocking this operation.
|
||||
*/
|
||||
GeckoDriver.prototype.findElement = async function(cmd) {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
await this._handleUserPrompts();
|
||||
const { element: el, using, value } = cmd.parameters;
|
||||
|
||||
let { using, value } = cmd.parameters;
|
||||
if (!SUPPORTED_STRATEGIES.has(using)) {
|
||||
throw new InvalidSelectorError(`Strategy not supported: ${using}`);
|
||||
}
|
||||
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
await this._handleUserPrompts();
|
||||
|
||||
let startNode;
|
||||
if (typeof cmd.parameters.element != "undefined") {
|
||||
startNode = WebElement.fromUUID(cmd.parameters.element, this.context);
|
||||
if (typeof el != "undefined") {
|
||||
startNode = WebElement.fromUUID(el, this.context);
|
||||
}
|
||||
|
||||
let opts = {
|
||||
|
@ -2071,6 +2073,11 @@ GeckoDriver.prototype.findElement = async function(cmd) {
|
|||
all: false,
|
||||
};
|
||||
|
||||
if (MarionettePrefs.useActors) {
|
||||
const actor = await this.getActor();
|
||||
return actor.findElement(using, value, opts);
|
||||
}
|
||||
|
||||
switch (this.context) {
|
||||
case Context.Chrome:
|
||||
let container = { frame: win };
|
||||
|
@ -2097,16 +2104,18 @@ GeckoDriver.prototype.findElement = async function(cmd) {
|
|||
* Value the client is looking for.
|
||||
*/
|
||||
GeckoDriver.prototype.findElements = async function(cmd) {
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
await this._handleUserPrompts();
|
||||
const { element: el, using, value } = cmd.parameters;
|
||||
|
||||
let { using, value } = cmd.parameters;
|
||||
if (!SUPPORTED_STRATEGIES.has(using)) {
|
||||
throw new InvalidSelectorError(`Strategy not supported: ${using}`);
|
||||
}
|
||||
|
||||
const win = assert.open(this.getCurrentWindow());
|
||||
await this._handleUserPrompts();
|
||||
|
||||
let startNode;
|
||||
if (typeof cmd.parameters.element != "undefined") {
|
||||
startNode = WebElement.fromUUID(cmd.parameters.element, this.context);
|
||||
if (typeof el != "undefined") {
|
||||
startNode = WebElement.fromUUID(el, this.context);
|
||||
}
|
||||
|
||||
let opts = {
|
||||
|
@ -2115,6 +2124,11 @@ GeckoDriver.prototype.findElements = async function(cmd) {
|
|||
all: true,
|
||||
};
|
||||
|
||||
if (MarionettePrefs.useActors) {
|
||||
const actor = await this.getActor();
|
||||
return actor.findElements(using, value, opts);
|
||||
}
|
||||
|
||||
switch (this.context) {
|
||||
case Context.Chrome:
|
||||
let container = { frame: win };
|
||||
|
|
Загрузка…
Ссылка в новой задаче