diff --git a/tests/download.spec.ts b/tests/download.spec.ts index fb338f9c51..72c7a8114e 100644 --- a/tests/download.spec.ts +++ b/tests/download.spec.ts @@ -39,6 +39,12 @@ it.describe('download event', () => { res.write('foo'); res.uncork(); }); + server.setRoute('/downloadWithCOOP', (req, res) => { + res.setHeader('Content-Type', 'application/octet-stream'); + res.setHeader('Content-Disposition', 'attachment'); + res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); + res.end(`Hello world`); + }); }); it('should report download when navigation turns into download', async ({ browser, server, browserName }) => { @@ -67,6 +73,32 @@ it.describe('download event', () => { await page.close(); }); + it('should work with Cross-Origin-Opener-Policy', async ({ browser, server, browserName }) => { + const page = await browser.newPage({ acceptDownloads: true }); + const [ download, responseOrError ] = await Promise.all([ + page.waitForEvent('download'), + page.goto(server.PREFIX + '/downloadWithCOOP').catch(e => e) + ]); + expect(download.page()).toBe(page); + expect(download.url()).toBe(`${server.PREFIX}/downloadWithCOOP`); + const path = await download.path(); + expect(fs.existsSync(path)).toBeTruthy(); + expect(fs.readFileSync(path).toString()).toBe('Hello world'); + if (browserName === 'chromium') { + expect(responseOrError instanceof Error).toBeTruthy(); + expect(responseOrError.message).toContain('net::ERR_ABORTED'); + expect(page.url()).toBe('about:blank'); + } else if (browserName === 'webkit') { + expect(responseOrError instanceof Error).toBeTruthy(); + expect(responseOrError.message).toContain('Download is starting'); + expect(page.url()).toBe('about:blank'); + } else { + expect(responseOrError.status()).toBe(200); + expect(page.url()).toBe(server.PREFIX + '/downloadWithCOOP'); + } + await page.close(); + }); + it('should report downloads with acceptDownloads: false', async ({ browser, server }) => { const page = await browser.newPage(); await page.setContent(`download`); diff --git a/tests/page/page-goto.spec.ts b/tests/page/page-goto.spec.ts index 7fdfae4f8a..40e54e09c7 100644 --- a/tests/page/page-goto.spec.ts +++ b/tests/page/page-goto.spec.ts @@ -58,14 +58,82 @@ it('should work cross-process', async ({ page, server }) => { expect(response.url()).toBe(url); }); +it('should work with cross-process that fails before committing', async ({ page, server }) => { + server.setRoute('/empty.html', (req, res) => { + req.socket.destroy(); + }); + const response1 = await page.goto(server.CROSS_PROCESS_PREFIX + '/title.html'); + await response1.finished(); + const error = await page.goto(server.EMPTY_PAGE).catch(e => e); + expect(error instanceof Error).toBeTruthy(); +}); + it('should work with Cross-Origin-Opener-Policy', async ({ page, server, browserName }) => { - it.fail(browserName === 'webkit', 'Regressed in https://trac.webkit.org/changeset/281516/webkit'); + it.fail(browserName === 'webkit', 'https://github.com/microsoft/playwright/issues/8796'); server.setRoute('/empty.html', (req, res) => { res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); res.end(); }); - await page.goto(server.EMPTY_PAGE); + const requests = new Set(); + const events = []; + page.on('request', r => { + events.push('request'); + requests.add(r); + }); + page.on('requestfailed', r => { + events.push('requestfailed'); + requests.add(r); + }); + page.on('requestfinished', r => { + events.push('requestfinished'); + requests.add(r); + }); + page.on('response', r => { + events.push('response'); + requests.add(r.request()); + }); + const response = await page.goto(server.EMPTY_PAGE); expect(page.url()).toBe(server.EMPTY_PAGE); + await response.finished(); + expect(events).toEqual(['request', 'response', 'requestfinished']); + expect(requests.size).toBe(1); + expect(response.request().failure()).toBeNull(); +}); + +it('should work with Cross-Origin-Opener-Policy after redirect', async ({ page, server, browserName }) => { + it.fail(browserName === 'webkit', 'https://github.com/microsoft/playwright/issues/8796'); + server.setRedirect('/redirect', '/empty.html'); + server.setRoute('/empty.html', (req, res) => { + res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); + res.end(); + }); + const requests = new Set(); + const events = []; + page.on('request', r => { + events.push('request'); + requests.add(r); + }); + page.on('requestfailed', r => { + events.push('requestfailed'); + requests.add(r); + }); + page.on('requestfinished', r => { + events.push('requestfinished'); + requests.add(r); + }); + page.on('response', r => { + events.push('response'); + requests.add(r.request()); + }); + const response = await page.goto(server.PREFIX + '/redirect'); + expect(page.url()).toBe(server.EMPTY_PAGE); + await response.finished(); + expect(events).toEqual(['request', 'response', 'requestfinished', 'request', 'response', 'requestfinished']); + expect(requests.size).toBe(2); + expect(response.request().failure()).toBeNull(); + const firstRequest = response.request().redirectedFrom(); + expect(firstRequest).toBeTruthy(); + expect(firstRequest.url()).toBe(server.PREFIX + '/redirect'); }); it('should capture iframe navigation request', async ({ page, server }) => { diff --git a/tests/page/page-request-continue.spec.ts b/tests/page/page-request-continue.spec.ts index d1d4c24b2c..3aca7263b2 100644 --- a/tests/page/page-request-continue.spec.ts +++ b/tests/page/page-request-continue.spec.ts @@ -167,3 +167,56 @@ it.describe('', () => { expect(arr[i]).toBe(buffer[i]); }); }); + +it('should work with Cross-Origin-Opener-Policy', async ({ page, server, browserName }) => { + it.fail(browserName === 'webkit', 'https://github.com/microsoft/playwright/issues/8796'); + let serverHeaders; + const serverRequests = []; + server.setRoute('/empty.html', (req, res) => { + serverRequests.push(req.url); + serverHeaders ??= req.headers; + res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); + res.end(); + }); + + const intercepted = []; + await page.route('**/*', (route, req) => { + intercepted.push(req.url()); + route.continue({ + headers: { + foo: 'bar' + } + }); + }); + const requests = new Set(); + const events = []; + page.on('request', r => { + events.push('request'); + requests.add(r); + }); + page.on('requestfailed', r => { + events.push('requestfailed'); + requests.add(r); + }); + page.on('requestfinished', r => { + events.push('requestfinished'); + requests.add(r); + }); + page.on('response', r => { + events.push('response'); + requests.add(r.request()); + }); + const response = await page.goto(server.EMPTY_PAGE); + expect(intercepted).toEqual([server.EMPTY_PAGE]); + // There should be only one request to the server. + if (browserName === 'webkit') + expect(serverRequests).toEqual(['/empty.html', '/empty.html']); + else + expect(serverRequests).toEqual(['/empty.html']); + expect(serverHeaders['foo']).toBe('bar'); + expect(page.url()).toBe(server.EMPTY_PAGE); + await response.finished(); + expect(events).toEqual(['request', 'response', 'requestfinished']); + expect(requests.size).toBe(1); + expect(response.request().failure()).toBeNull(); +});