diff --git a/packages/playwright-core/src/server/injected/utilityScript.ts b/packages/playwright-core/src/server/injected/utilityScript.ts index 34932f82c3..92571ad8a2 100644 --- a/packages/playwright-core/src/server/injected/utilityScript.ts +++ b/packages/playwright-core/src/server/injected/utilityScript.ts @@ -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); diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 2d69d956c1..ff4d711a56 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -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)); diff --git a/tests/page/page-evaluate.spec.ts b/tests/page/page-evaluate.spec.ts index 7ea34a3a3c..d6af07678f 100644 --- a/tests/page/page-evaluate.spec.ts +++ b/tests/page/page-evaluate.spec.ts @@ -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(``); + }); + 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 diff --git a/tests/page/page-expose-function.spec.ts b/tests/page/page-expose-function.spec.ts index 088d1e2f61..c084e5ea21 100644 --- a/tests/page/page-expose-function.spec.ts +++ b/tests/page/page-expose-function.spec.ts @@ -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(``); + }); + await page.goto(server.PREFIX + '/test'); + await page.exposeFunction('add', (a, b) => a + b); + expect(await page.evaluate('add(5, 6)')).toBe(11); +});