diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 2a1c7646fd..ea85e669ef 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -1474,11 +1474,14 @@ export class Frame extends SdkObject { expression = js.normalizeEvaluationExpression(expression, isFunction); return controller.run(async progress => { return this.retryWithProgressAndTimeouts(progress, [100], async () => { - const context = await this._mainContext(); + const context = world === 'main' ? await this._mainContext() : await this._utilityContext(); const injectedScript = await context.injectedScript(); const handle = await injectedScript.evaluateHandle((injected, { expression, isFunction, polling, arg }) => { const predicate = (): R => { - let result = self.eval(expression); + // NOTE: make sure to use `globalThis.eval` instead of `self.eval` due to a bug with sandbox isolation + // in firefox. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1814898 + let result = globalThis.eval(expression); if (isFunction === true) { result = result(arg); } else if (isFunction === false) { diff --git a/tests/page/elementhandle-screenshot.spec.ts b/tests/page/elementhandle-screenshot.spec.ts index 0a2f8b60ec..3f172c9253 100644 --- a/tests/page/elementhandle-screenshot.spec.ts +++ b/tests/page/elementhandle-screenshot.spec.ts @@ -33,6 +33,18 @@ it.describe('element screenshot', () => { expect(screenshot).toMatchSnapshot('screenshot-element-bounding-box.png'); }); + it('should work when main world busts JSON.stringify', async ({ page, server }) => { + await page.setViewportSize({ width: 500, height: 500 }); + await page.goto(server.PREFIX + '/grid.html'); + await page.evaluate(() => { + window.scrollBy(50, 100); + JSON.stringify = () => undefined; + }); + const elementHandle = await page.$('.box:nth-of-type(3)'); + const screenshot = await elementHandle.screenshot(); + expect(screenshot).toMatchSnapshot('screenshot-element-bounding-box.png'); + }); + it('should take into account padding and border', async ({ page }) => { await page.setViewportSize({ width: 500, height: 500 }); await page.setContent(`