Bug 1838664 - [webdriver-bidi] Implement "browsingContext.setViewport" command. r=webdriver-reviewers,jdescottes

Differential Revision: https://phabricator.services.mozilla.com/D181905
This commit is contained in:
Henrik Skupin 2023-07-13 12:08:56 +00:00
parent 729fd22776
commit 647dfb12ef
8 changed files with 170 additions and 105 deletions

View file

@ -983,10 +983,10 @@ export function setDefaultAndAssertSerializationOptions(options = {}) {
serializationOptions;
if (maxDomDepth !== null) {
lazy.assert.positiveNumber(maxDomDepth);
lazy.assert.positiveInteger(maxDomDepth);
}
if (maxObjectDepth !== null) {
lazy.assert.positiveNumber(maxObjectDepth);
lazy.assert.positiveInteger(maxObjectDepth);
}
const includeShadowTreeModesValues = Object.values(IncludeShadowTreeMode);
lazy.assert.that(

View file

@ -33,6 +33,9 @@ XPCOMUtils.defineLazyGetter(lazy, "logger", () =>
lazy.Log.get(lazy.Log.TYPES.WEBDRIVER_BIDI)
);
// Maximal window dimension allowed when emulating a viewport.
const MAX_WINDOW_SIZE = 10000000;
/**
* @typedef {object} CreateType
*/
@ -48,6 +51,17 @@ const CreateType = {
window: "window",
};
/**
* An object that contains details of a viewport.
*
* @typedef {object} Viewport
*
* @property {number} height
* The height of the viewport.
* @property {number} width
* The width of the viewport.
*/
/**
* @typedef {string} WaitCondition
*/
@ -561,6 +575,95 @@ class BrowsingContextModule extends Module {
};
}
/**
* Set the top-level browsing context's viewport to a given dimension.
*
* @param {object=} options
* @param {string} options.context
* Id of the browsing context.
* @param {Viewport|null} options.viewport
* Dimensions to set the viewport to, or `null` to reset it
* to the original dimensions.
*
* @throws {InvalidArgumentError}
* Raised if an argument is of an invalid type or value.
* @throws UnsupportedOperationError
* Raised when the command is called on Android.
*/
async setViewport(options = {}) {
const { context: contextId, viewport } = options;
if (lazy.AppInfo.isAndroid) {
// Bug 1840084: Add Android support for modifying the viewport.
throw new lazy.error.UnsupportedOperationError(
`Command not yet supported for ${lazy.AppInfo.name}`
);
}
lazy.assert.string(
contextId,
`Expected "context" to be a string, got ${contextId}`
);
const context = this.#getBrowsingContext(contextId);
if (context.parent) {
throw new lazy.error.InvalidArgumentError(
`Browsing Context with id ${contextId} is not top-level`
);
}
const browser = context.embedderElement;
if (typeof viewport !== "object") {
throw new lazy.error.InvalidArgumentError(
`Expected "viewport" to be an object or null, got ${viewport}`
);
}
let targetHeight, targetWidth;
if (viewport !== null) {
const { height, width } = viewport;
targetHeight = lazy.assert.positiveInteger(
height,
`Expected "height" to be a positive integer, got ${height}`
);
targetWidth = lazy.assert.positiveInteger(
width,
`Expected "width" to be a positive integer, got ${width}`
);
if (targetHeight > MAX_WINDOW_SIZE || targetWidth > MAX_WINDOW_SIZE) {
throw new lazy.error.UnsupportedOperationError(
`"width" or "height" cannot be larger than ${MAX_WINDOW_SIZE} px`
);
}
browser.style.setProperty("height", targetHeight + "px");
browser.style.setProperty("width", targetWidth + "px");
} else {
// Reset viewport to the original dimensions
targetHeight = browser.parentElement.clientHeight;
targetWidth = browser.parentElement.clientWidth;
browser.style.removeProperty("height");
browser.style.removeProperty("width");
}
// Wait until the viewport has been resized
await this.messageHandler.forwardCommand({
moduleName: "browsingContext",
commandName: "_awaitViewportDimensions",
destination: {
type: lazy.WindowGlobalMessageHandler.type,
id: context.id,
},
params: {
height: targetHeight,
width: targetWidth,
},
});
}
/**
* Start and await a navigation on the provided BrowsingContext. Returns a
* promise which resolves when the navigation is done according to the provided

View file

@ -7,6 +7,7 @@ import { WindowGlobalBiDiModule } from "chrome://remote/content/webdriver-bidi/m
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
AnimationFramePromise: "chrome://remote/content/shared/Sync.sys.mjs",
LoadListener: "chrome://remote/content/shared/listeners/LoadListener.sys.mjs",
});
@ -141,12 +142,54 @@ class BrowsingContextModule extends WindowGlobalBiDiModule {
}
}
/**
* Waits until the viewport has reached the new dimensions.
*
* @param {object} options
* @param {number} options.height
* Expected height the viewport will resize to.
* @param {number} options.width
* Expected width the viewport will resize to.
*
* @returns {Promise}
* Promise that resolves when the viewport has been resized.
*/
async _awaitViewportDimensions(options) {
const { height, width } = options;
const win = this.messageHandler.window;
let resized;
// Updates for background tabs are throttled, and we also have to make
// sure that the new browser dimensions have been received by the content
// process. As such wait for the next animation frame.
await lazy.AnimationFramePromise(win);
const checkBrowserSize = () => {
if (win.innerWidth === width && win.innerHeight === height) {
resized();
}
};
return new Promise(resolve => {
resized = resolve;
win.addEventListener("resize", checkBrowserSize);
// Trigger a layout flush in case none happened yet.
checkBrowserSize();
}).finally(() => {
win.removeEventListener("resize", checkBrowserSize);
});
}
_getBaseURL() {
return this.messageHandler.window.document.baseURI;
}
_getScreenshotRect() {
const win = this.messageHandler.window;
return new DOMRect(
win.pageXOffset,
win.pageYOffset,

View file

@ -2,14 +2,19 @@
expected:
if (os == "win") and not debug and (processor == "x86"): [OK, TIMEOUT]
if (os == "mac") and not debug: [OK, TIMEOUT]
[test_capture_with_viewport[height smaller-width smaller\]]
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084
[test_capture_with_viewport[height smaller-width larger\]]
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084
[test_capture_with_viewport[height larger-width smaller\]]
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084
[test_capture_with_viewport[height larger-width larger\]]
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084

View file

@ -1,81 +1,4 @@
[invalid.py]
[test_params_context_invalid_type[None\]]
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084
[test_params_context_invalid_type[False\]]
expected: FAIL
[test_params_context_invalid_type[42\]]
expected: FAIL
[test_params_context_invalid_type[value3\]]
expected: FAIL
[test_params_context_invalid_type[value4\]]
expected: FAIL
[test_params_context_invalid_value]
expected: FAIL
[test_params_context_iframe]
expected: FAIL
[test_params_viewport_invalid_type[False\]]
expected: FAIL
[test_params_viewport_invalid_type[42\]]
expected: FAIL
[test_params_viewport_invalid_type[\]]
expected: FAIL
[test_params_viewport_invalid_type[viewport3\]]
expected: FAIL
[test_params_viewport_invalid_type[viewport4\]]
expected: FAIL
[test_params_viewport_invalid_type[viewport5\]]
expected: FAIL
[test_params_viewport_invalid_type[viewport6\]]
expected: FAIL
[test_params_viewport_width_invalid_type[None\]]
expected: FAIL
[test_params_viewport_width_invalid_type[False\]]
expected: FAIL
[test_params_viewport_width_invalid_type[\]]
expected: FAIL
[test_params_viewport_width_invalid_type[width3\]]
expected: FAIL
[test_params_viewport_width_invalid_type[width4\]]
expected: FAIL
[test_params_viewport_height_invalid_type[None\]]
expected: FAIL
[test_params_viewport_height_invalid_type[False\]]
expected: FAIL
[test_params_viewport_height_invalid_type[\]]
expected: FAIL
[test_params_viewport_height_invalid_type[height3\]]
expected: FAIL
[test_params_viewport_height_invalid_type[height4\]]
expected: FAIL
[test_params_viewport_invalid_value[width negative\]]
expected: FAIL
[test_params_viewport_invalid_value[height negative\]]
expected: FAIL
[test_params_viewport_invalid_value[both negative\]]
expected: FAIL

View file

@ -1,24 +1,7 @@
[set_viewport.py]
[test_set_viewport]
expected: FAIL
[test_set_viewport_same_dimensions]
expected: FAIL
[test_set_viewport_reset]
expected: FAIL
[test_set_viewport_affects_specific_context]
expected: FAIL
[test_set_viewport_persists_on_navigation[http\]]
expected: FAIL
[test_set_viewport_persists_on_navigation[https\]]
expected: FAIL
[test_set_viewport_persists_on_navigation[https coop\]]
expected: FAIL
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084
[test_set_viewport_persists_on_reload]
bug: 1830859
expected: FAIL

View file

@ -0,0 +1,4 @@
[invalid.py]
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084

View file

@ -0,0 +1,4 @@
[set_viewport.py]
disabled:
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840084