diff options
Diffstat (limited to 'remote/webdriver-bidi/modules/windowglobal')
3 files changed, 91 insertions, 6 deletions
diff --git a/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs index 8421445d2c..adf821601d 100644 --- a/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs +++ b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs @@ -17,6 +17,7 @@ ChromeUtils.defineESModuleGetters(lazy, { "chrome://remote/content/webdriver-bidi/modules/root/browsingContext.sys.mjs", OriginType: "chrome://remote/content/webdriver-bidi/modules/root/browsingContext.sys.mjs", + PollPromise: "chrome://remote/content/shared/Sync.sys.mjs", }); const DOCUMENT_FRAGMENT_NODE = 11; @@ -356,6 +357,29 @@ class BrowsingContextModule extends WindowGlobalBiDiModule { }); } + /** + * Waits until the visibility state of the document has the expected value. + * + * @param {object} options + * @param {number} options.value + * Expected value of the visibility state. + * + * @returns {Promise} + * Promise that resolves when the visibility state has the expected value. + */ + async _awaitVisibilityState(options) { + const { value } = options; + const win = this.messageHandler.window; + + await lazy.PollPromise((resolve, reject) => { + if (win.document.visibilityState === value) { + resolve(); + } else { + reject(); + } + }); + } + _getBaseURL() { return this.messageHandler.window.document.baseURI; } diff --git a/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs index 099cf53d46..b91cce2310 100644 --- a/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs +++ b/remote/webdriver-bidi/modules/windowglobal/input.sys.mjs @@ -10,6 +10,7 @@ ChromeUtils.defineESModuleGetters(lazy, { action: "chrome://remote/content/shared/webdriver/Actions.sys.mjs", dom: "chrome://remote/content/shared/DOM.sys.mjs", error: "chrome://remote/content/shared/webdriver/Errors.sys.mjs", + event: "chrome://remote/content/shared/webdriver/Event.sys.mjs", }); class InputModule extends WindowGlobalBiDiModule { @@ -43,6 +44,67 @@ class InputModule extends WindowGlobalBiDiModule { this.#actionState = null; } + async setFiles(options) { + const { element: sharedReference, files } = options; + + const element = await this.#deserializeElementSharedReference( + sharedReference + ); + + if ( + !HTMLInputElement.isInstance(element) || + element.type !== "file" || + element.disabled + ) { + throw new lazy.error.UnableToSetFileInputError( + `Element needs to be an <input> element with type "file" and not disabled` + ); + } + + if (files.length > 1 && !element.hasAttribute("multiple")) { + throw new lazy.error.UnableToSetFileInputError( + `Element should have an attribute "multiple" set when trying to set more than 1 file` + ); + } + + const fileObjects = []; + for (const file of files) { + try { + fileObjects.push(await File.createFromFileName(file)); + } catch (e) { + throw new lazy.error.InvalidArgumentError( + `Failed to add file ${file} (${e})` + ); + } + } + + const selectedFiles = Array.from(element.files); + + const intersection = fileObjects.filter(fileObject => + selectedFiles.some( + selectedFile => + // Compare file fields to identify if the files are equal. + // TODO: Bug 1883856. Add check for full path or use a different way + // to compare files when it's available. + selectedFile.name === fileObject.name && + selectedFile.size === fileObject.size && + selectedFile.type === fileObject.type + ) + ); + + if ( + intersection.length === selectedFiles.length && + selectedFiles.length === fileObjects.length + ) { + lazy.event.cancel(element); + } else { + element.mozSetFileArray(fileObjects); + + lazy.event.input(element); + lazy.event.change(element); + } + } + /** * In the provided array of input.SourceActions, replace all origins matching * the input.ElementOrigin production with the Element corresponding to this @@ -75,8 +137,8 @@ class InputModule extends WindowGlobalBiDiModule { if (action?.origin?.type === "element") { promises.push( (async () => { - action.origin = await this.#getElementFromElementOrigin( - action.origin + action.origin = await this.#deserializeElementSharedReference( + action.origin.element ); })() ); @@ -87,11 +149,10 @@ class InputModule extends WindowGlobalBiDiModule { return Promise.all(promises); } - async #getElementFromElementOrigin(origin) { - const sharedReference = origin.element; + async #deserializeElementSharedReference(sharedReference) { if (typeof sharedReference?.sharedId !== "string") { throw new lazy.error.InvalidArgumentError( - `Expected "origin.element" to be a SharedReference, got: ${sharedReference}` + `Expected "element" to be a SharedReference, got: ${sharedReference}` ); } diff --git a/remote/webdriver-bidi/modules/windowglobal/script.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/script.sys.mjs index e0f9542bdd..88d58f8064 100644 --- a/remote/webdriver-bidi/modules/windowglobal/script.sys.mjs +++ b/remote/webdriver-bidi/modules/windowglobal/script.sys.mjs @@ -290,7 +290,7 @@ class ScriptModule extends WindowGlobalBiDiModule { const rawObject = maybeDebuggerObject.unsafeDereference(); // TODO: Getters for Maps and Sets iterators return "Opaque" objects and - // are not iterable. RemoteValue.jsm' serializer should handle calling + // are not iterable. RemoteValue.sys.mjs' serializer should handle calling // waiveXrays on Maps/Sets/... and then unwaiveXrays on entries but since // we serialize with maxDepth=1, calling waiveXrays once on the root // object allows to return correctly serialized values. |