chore: make evaluate work with busted Array.prototype.map/push (#22528)

Fixes https://github.com/microsoft/playwright/issues/22460

Signed-off-by: Max Schmitt <max@schmitt.mx>
Co-authored-by: Dmitry Gozman <dgozman@gmail.com>
This commit is contained in:
Max Schmitt 2023-04-21 19:52:13 +02:00 committed by GitHub
parent bbc47ba315
commit f6aa9f49ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 4 deletions

View File

@ -23,7 +23,9 @@ export class UtilityScript {
evaluate(isFunction: boolean | undefined, returnByValue: boolean, exposeUtilityScript: boolean | undefined, expression: string, argCount: number, ...argsAndHandles: any[]) {
const args = argsAndHandles.slice(0, argCount);
const handles = argsAndHandles.slice(argCount);
const parameters = args.map(a => parseEvaluationResultValue(a, handles));
const parameters = [];
for (let i = 0; i < args.length; i++)
parameters[i] = this.parseEvaluationResultValue(args[i], handles);
if (exposeUtilityScript)
parameters.unshift(this);

View File

@ -818,9 +818,12 @@ function addPageBinding(bindingName: string, needsHandle: boolean, utilityScript
handles.set(seq, args[0]);
payload = { name: bindingName, seq };
} else {
const serializedArgs = args.map(a => utilityScriptSerializers.serializeAsCallArgument(a, v => {
return { fallThrough: v };
}));
const serializedArgs = [];
for (let i = 0; i < args.length; i++) {
serializedArgs[i] = utilityScriptSerializers.serializeAsCallArgument(args[i], v => {
return { fallThrough: v };
});
}
payload = { name: bindingName, seq, serializedArgs };
}
binding(JSON.stringify(payload));

View File

@ -681,6 +681,21 @@ it('should work with overridden Object.defineProperty', async ({ page, server })
expect(await page.evaluate('1+2')).toBe(3);
});
it('should work with busted Array.prototype.map/push', async ({ page, server }) => {
server.setRoute('/test', (req, res) => {
res.writeHead(200, {
'content-type': 'text/html',
});
res.end(`<script>
Array.prototype.map = null;
Array.prototype.push = null;
</script>`);
});
await page.goto(server.PREFIX + '/test');
expect(await page.evaluate('1+2')).toBe(3);
expect(await ((await page.evaluateHandle('1+2')).jsonValue())).toBe(3);
});
it('should work with overridden globalThis.Window/Document/Node', async ({ page, server }) => {
const testCases = [
// @ts-ignore

View File

@ -285,3 +285,18 @@ it('should work with overridden console object', async ({ page }) => {
await page.exposeFunction('add', (a, b) => a + b);
expect(await page.evaluate('add(5, 6)')).toBe(11);
});
it('should work with busted Array.prototype.map/push', async ({ page, server }) => {
server.setRoute('/test', (req, res) => {
res.writeHead(200, {
'content-type': 'text/html',
});
res.end(`<script>
Array.prototype.map = null;
Array.prototype.push = null;
</script>`);
});
await page.goto(server.PREFIX + '/test');
await page.exposeFunction('add', (a, b) => a + b);
expect(await page.evaluate('add(5, 6)')).toBe(11);
});