Bug 1841049 - [bidi] Serialize a context property for WindowProxy. r=webdriver-reviewers,whimboo

Differential Revision: https://phabricator.services.mozilla.com/D192703
This commit is contained in:
Alexandra Borovova 2023-11-08 15:32:16 +00:00
Родитель 01f1828166
Коммит 025458222b
4 изменённых файлов: 160 добавлений и 164 удалений

Просмотреть файл

@ -434,7 +434,7 @@
{
"testIdPattern": "[click.spec] Page.click should click the button with fixed position inside an iframe",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
@ -1517,12 +1517,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[click.spec] Page.click should click the button inside an iframe",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[click.spec] Page.click should click the button with deviceScaleFactor set",
"platforms": ["darwin", "linux", "win32"],
@ -1697,12 +1691,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.boxModel should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.click should return Point data",
"platforms": ["darwin", "linux", "win32"],
@ -1715,24 +1703,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.clickablePoint should work for iframes",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.clickablePoint should work for iframes",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.contentFrame should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.isIntersectingViewport should work",
"platforms": ["darwin", "linux", "win32"],
@ -1859,18 +1829,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["PASS", "TIMEOUT"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Frame.evaluate should have different execution contexts",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Frame.evaluate should have different execution contexts",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluate should await promise",
"platforms": ["darwin", "linux", "win32"],
@ -1919,12 +1877,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame Management should report different frame instance when frame re-attaches",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame Management should report frame from-inside shadow DOM",
"platforms": ["darwin", "linux", "win32"],
@ -1937,12 +1889,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame Management should report frame.parent()",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame Management should report frame.parent()",
"platforms": ["darwin", "linux", "win32"],
@ -1955,12 +1901,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame Management should send events when frames are manipulated dynamically",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame Management should support lazy frames",
"platforms": ["darwin", "linux", "win32"],
@ -1979,12 +1919,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame.evaluate should throw for detached frames",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[frame.spec] Frame specs Frame.executionContext should work",
"platforms": ["darwin", "linux", "win32"],
@ -2165,12 +2099,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[keyboard.spec] Keyboard should type emoji into an iframe",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[keyboard.spec] Keyboard should type emoji into an iframe",
"platforms": ["darwin", "linux", "win32"],
@ -2327,18 +2255,6 @@
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[locator.spec] Locator Locator.click should work with a OOPIF",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[locator.spec] Locator Locator.click should work with a OOPIF",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL", "TIMEOUT"]
},
{
"testIdPattern": "[locator.spec] Locator Locator.race races multiple locators",
"platforms": ["darwin", "linux", "win32"],
@ -2741,18 +2657,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[network.spec] network Page.Events.Request should fire for iframes",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[network.spec] network Page.Events.Request should fire for iframes",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[network.spec] network Page.setExtraHTTPHeaders should work",
"platforms": ["darwin", "linux", "win32"],
@ -2805,7 +2709,7 @@
"testIdPattern": "[network.spec] network Request.frame should work for subframe navigation request",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
"expectations": ["PASS", "TIMEOUT"]
},
{
"testIdPattern": "[network.spec] network Request.headers should define Firefox as user agent header",
@ -3785,24 +3689,12 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector Page.waitForSelector is shortcut for main frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should run in specified frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should run in specified frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should survive cross-process navigation",
"platforms": ["darwin", "linux", "win32"],
@ -3831,7 +3723,7 @@
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should throw when frame is detached",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
"expectations": ["PASS", "FAIL"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should work with removed MutationObserver",
@ -3839,12 +3731,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should run in specified frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should run in specified frame",
"platforms": ["darwin", "linux", "win32"],
@ -3861,7 +3747,7 @@
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should throw when frame is detached",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
"expectations": ["PASS", "FAIL"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should throw when frame is detached",

Просмотреть файл

@ -881,14 +881,9 @@ export function serialize(
}
return serialized;
} else if (
[
"ArrayBuffer",
"Function",
"Promise",
"WeakMap",
"WeakSet",
"Window",
].includes(className)
["ArrayBuffer", "Function", "Promise", "WeakMap", "WeakSet"].includes(
className
)
) {
return buildSerialized(className.toLowerCase(), handleId);
} else if (className.includes("Generator")) {
@ -923,6 +918,22 @@ export function serialize(
);
}
return serialized;
} else if (className === "Window") {
const serialized = buildSerialized("window", handleId);
const window = Cu.unwaiveXrays(value);
if (window.browsingContext.parent == null) {
serialized.value = {
context: window.browsingContext.browserId.toString(),
isTopBrowsingContext: true,
};
} else {
serialized.value = {
context: window.browsingContext.id.toString(),
};
}
return serialized;
} else if (ChromeUtils.isDOMObject(value)) {
const serialized = buildSerialized("object", handleId);

Просмотреть файл

@ -7,6 +7,7 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
getSeenNodesForBrowsingContext:
"chrome://remote/content/shared/webdriver/Session.sys.mjs",
TabManager: "chrome://remote/content/shared/TabManager.sys.mjs",
});
/**
@ -45,5 +46,56 @@ export function processExtraData(sessionId, payload) {
delete payload._extraData;
}
// Find serialized WindowProxy and resolve browsing context to a navigable id.
if (payload?.result) {
payload.result = addContextIdToSerializedWindow(payload.result);
} else if (payload.exceptionDetails) {
payload.exceptionDetails = addContextIdToSerializedWindow(
payload.exceptionDetails
);
}
return payload;
}
function addContextIdToSerializedWindow(serialized) {
if (serialized.value) {
switch (serialized.type) {
case "array":
case "htmlcollection":
case "nodelist":
case "set": {
serialized.value = serialized.value.map(value =>
addContextIdToSerializedWindow(value)
);
break;
}
case "map":
case "object": {
serialized.value = serialized.value.map(([key, value]) => [
key,
addContextIdToSerializedWindow(value),
]);
break;
}
case "window": {
if (serialized.value.isTopBrowsingContext) {
const browsingContext = BrowsingContext.getCurrentTopByBrowserId(
serialized.value.context
);
serialized.value = {
context: lazy.TabManager.getIdForBrowsingContext(browsingContext),
};
}
break;
}
}
} else if (serialized.exception) {
serialized.exception = addContextIdToSerializedWindow(serialized.exception);
}
return serialized;
}

Просмотреть файл

@ -120,7 +120,6 @@ add_task(async function test_serializeRemoteComplexValues() {
const domElRef = nodeCache.getOrCreateNodeReference(domEl, seenNodeIds);
const REMOTE_COMPLEX_VALUES = [
{ value: content, serialized: { type: "window" } },
{
value: content.document.querySelector("div"),
serialized: {
@ -179,46 +178,50 @@ add_task(async function test_serializeRemoteComplexValues() {
];
for (const type of REMOTE_COMPLEX_VALUES) {
const { value, serialized } = type;
const serializationOptionsWithDefaults = setDefaultSerializationOptions();
const serializationInternalMapWithNone = new Map();
serializeAndAssertRemoteValue(type);
}
});
});
info(`Checking '${serialized.type}' with none ownershipType`);
add_task(async function test_serializeWindow() {
await loadURL(inline("<iframe>"));
const serializedValue = serialize(
value,
serializationOptionsWithDefaults,
"none",
serializationInternalMapWithNone,
realm,
{ nodeCache, seenNodeIds }
);
await runTestInContent(() => {
const REMOTE_COMPLEX_VALUES = [
{
value: content,
serialized: {
type: "window",
value: {
context: content.browsingContext.browserId.toString(),
isTopBrowsingContext: true,
},
},
},
{
value: content.frames[0],
serialized: {
type: "window",
value: {
context: content.frames[0].browsingContext.id.toString(),
},
},
},
{
value: content.document.querySelector("iframe").contentWindow,
serialized: {
type: "window",
value: {
context: content.document
.querySelector("iframe")
.contentWindow.browsingContext.id.toString(),
},
},
},
];
assertInternalIds(serializationInternalMapWithNone, 0);
Assert.deepEqual(serialized, serializedValue, "Got expected structure");
info(`Checking '${serialized.type}' with root ownershipType`);
const serializationInternalMapWithRoot = new Map();
const serializedWithRoot = serialize(
value,
serializationOptionsWithDefaults,
"root",
serializationInternalMapWithRoot,
realm,
{ nodeCache, seenNodeIds }
);
assertInternalIds(serializationInternalMapWithRoot, 0);
Assert.equal(
typeof serializedWithRoot.handle,
"string",
"Got a handle property"
);
Assert.deepEqual(
Object.assign({}, serialized, { handle: serializedWithRoot.handle }),
serializedWithRoot,
"Got expected structure, plus a generated handle id"
);
for (const type of REMOTE_COMPLEX_VALUES) {
serializeAndAssertRemoteValue(type);
}
});
});
@ -791,6 +794,50 @@ function runTestInContent(callback) {
const realm = new WindowRealm(content);
const serializationInternalMap = new Map();
function serializeAndAssertRemoteValue(remoteValue) {
const { value, serialized } = remoteValue;
const serializationOptionsWithDefaults =
setDefaultSerializationOptions();
const serializationInternalMapWithNone = new Map();
info(`Checking '${serialized.type}' with none ownershipType`);
const serializedValue = serialize(
value,
serializationOptionsWithDefaults,
"none",
serializationInternalMapWithNone,
realm,
{ nodeCache, seenNodeIds }
);
assertInternalIds(serializationInternalMapWithNone, 0);
Assert.deepEqual(serialized, serializedValue, "Got expected structure");
info(`Checking '${serialized.type}' with root ownershipType`);
const serializationInternalMapWithRoot = new Map();
const serializedWithRoot = serialize(
value,
serializationOptionsWithDefaults,
"root",
serializationInternalMapWithRoot,
realm,
{ nodeCache, seenNodeIds }
);
assertInternalIds(serializationInternalMapWithRoot, 0);
Assert.equal(
typeof serializedWithRoot.handle,
"string",
"Got a handle property"
);
Assert.deepEqual(
Object.assign({}, serialized, { handle: serializedWithRoot.handle }),
serializedWithRoot,
"Got expected structure, plus a generated handle id"
);
}
// eslint-disable-next-line no-eval
eval(`(${callback})()`);
}