diff --git a/src/firefox/ffPage.ts b/src/firefox/ffPage.ts index b6222b42a7..0af4ca27ea 100644 --- a/src/firefox/ffPage.ts +++ b/src/firefox/ffPage.ts @@ -35,6 +35,7 @@ import { selectors } from '../selectors'; const UTILITY_WORLD_NAME = '__playwright_utility_world__'; export class FFPage implements PageDelegate { + readonly cspErrorsAsynchronousForInlineScipts = true; readonly rawMouse: RawMouseImpl; readonly rawKeyboard: RawKeyboardImpl; readonly _session: FFSession; diff --git a/src/frames.ts b/src/frames.ts index 76b20b8c4b..0faf59d94d 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -571,12 +571,19 @@ export class Frame { return this._raceWithCSPError(async () => { if (url !== null) return (await context.evaluateHandleInternal(addScriptUrl, { url, type })).asElement()!; + let result; if (path !== null) { let contents = await util.promisify(fs.readFile)(path, 'utf8'); contents += '//# sourceURL=' + path.replace(/\n/g, ''); - return (await context.evaluateHandleInternal(addScriptContent, { content: contents, type })).asElement()!; + result = (await context.evaluateHandleInternal(addScriptContent, { content: contents, type })).asElement()!; + } else { + result = (await context.evaluateHandleInternal(addScriptContent, { content: content!, type })).asElement()!; } - return (await context.evaluateHandleInternal(addScriptContent, { content: content!, type })).asElement()!; + // Another round trip to the browser to ensure that we receive CSP error messages + // (if any) logged asynchronously in a separate task on the content main thread. + if (this._page._delegate.cspErrorsAsynchronousForInlineScipts) + await context.evaluateInternal(() => true); + return result; }); async function addScriptUrl(options: { url: string, type: string }): Promise { diff --git a/src/page.ts b/src/page.ts index 4d0772e40a..080aa9c92b 100644 --- a/src/page.ts +++ b/src/page.ts @@ -75,6 +75,8 @@ export interface PageDelegate { // Work around Chrome's non-associated input and protocol. inputActionEpilogue(): Promise; + // Work around for asynchronously dispatched CSP errors in Firefox. + readonly cspErrorsAsynchronousForInlineScipts?: boolean; } type PageState = { diff --git a/test/page.spec.js b/test/page.spec.js index 74b81ae138..9c2e858aca 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -650,7 +650,7 @@ describe('Page.addScriptTag', function() { }); // Firefox fires onload for blocked script before it issues the CSP console error. - it.fail(FFOX)('should throw when added with content to the CSP page', async({page, server}) => { + it('should throw when added with content to the CSP page', async({page, server}) => { await page.goto(server.PREFIX + '/csp.html'); let error = null; await page.addScriptTag({ content: 'window.__injected = 35;' }).catch(e => error = e);