From f5781f90bacaa60ce4e9caca53a3222c191f2e1b Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 2 Apr 2021 21:07:45 -0700 Subject: [PATCH] test: migrate most non-page tests to new folio (#6059) --- test/pause.spec.ts | 3 +- .../chromium-darwin/focused-input.png | Bin .../chromium-linux/focused-input.png | Bin .../chromium-win32/focused-input.png | Bin .../firefox-darwin/focused-input.png | Bin .../firefox-linux/focused-input.png | Bin .../firefox-win32/focused-input.png | Bin .../webkit-darwin/focused-input.png | Bin .../webkit-linux/focused-input.png | Bin .../webkit-win32/focused-input.png | Bin {test => tests}/beforeunload.spec.ts | 14 ++--- .../browsercontext-add-cookies.spec.ts | 7 +-- .../browsercontext-add-init-script.spec.ts | 4 +- {test => tests}/browsercontext-basic.spec.ts | 4 +- .../browsercontext-clearcookies.spec.ts | 2 +- .../browsercontext-cookies.spec.ts | 14 ++--- .../browsercontext-credentials.spec.ts | 14 ++--- {test => tests}/browsercontext-csp.spec.ts | 5 +- {test => tests}/browsercontext-device.spec.ts | 22 +++---- {test => tests}/browsercontext-dsf.spec.ts | 2 +- .../browsercontext-expose-function.spec.ts | 3 +- {test => tests}/browsercontext-locale.spec.ts | 3 +- .../browsercontext-page-event.spec.ts | 16 ++--- {test => tests}/browsercontext-proxy.spec.ts | 21 +++---- {test => tests}/browsercontext-route.spec.ts | 3 +- ...wsercontext-set-extra-http-headers.spec.ts | 2 +- .../browsercontext-storage-state.spec.ts | 10 ++-- .../browsercontext-timezone-id.spec.ts | 3 +- .../browsercontext-user-agent.spec.ts | 5 +- .../browsercontext-viewport-mobile.spec.ts | 10 ++-- .../browsercontext-viewport.spec.ts | 14 +++-- .../browsertype-launch-server.spec.ts | 24 ++++---- {test => tests}/browsertype-launch.spec.ts | 32 +++++----- {test => tests}/capabilities.spec.ts | 51 +++++++++------- {test => tests}/channels.spec.ts | 26 ++++---- tests/config/androidTest.ts | 2 +- tests/config/browserEnv.ts | 6 +- tests/config/browserTest.ts | 15 ++++- tests/config/cliTest.ts | 2 +- tests/config/default.config.ts | 6 +- tests/config/electronTest.ts | 2 +- tests/config/pageTest.ts | 3 +- tests/config/playwrightTest.ts | 2 +- tests/config/serverEnv.ts | 13 ++-- {test => tests}/css-parser.spec.ts | 2 +- .../defaultbrowsercontext-1.spec.ts | 10 ++-- .../defaultbrowsercontext-2.spec.ts | 56 ++++++++---------- {test => tests}/downloads-path.spec.ts | 17 +++--- tests/elementhandle-scroll-into-view.spec.ts | 2 +- tests/folio/src/expect.ts | 5 ++ tests/folio/src/workerRunner.ts | 2 + {test => tests}/geolocation.spec.ts | 24 +++++--- {test => tests}/har.spec.ts | 42 +++++++------ {test => tests}/headful.spec.ts | 35 +++++------ {test => tests}/ignorehttpserrors.spec.ts | 2 +- {test => tests}/launcher.spec.ts | 8 +-- {test => tests}/logger.spec.ts | 2 +- tests/page-add-script-tag.spec.ts | 2 +- tests/page-add-style-tag.spec.ts | 2 +- tests/page-click-scroll.spec.ts | 2 +- tests/page-event-request.spec.ts | 2 +- tests/page-route.spec.ts | 2 +- {test => tests}/pdf.spec.ts | 10 ++-- {test => tests}/popup.spec.ts | 2 +- {test => tests}/proxy.spec.ts | 14 ++--- {test => tests}/selector-generator.spec.ts | 22 +++---- tests/tsconfig.json | 13 ++++ 67 files changed, 345 insertions(+), 298 deletions(-) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-darwin/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-linux/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-win32/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-darwin/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-linux/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-win32/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-darwin/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-linux/focused-input.png (100%) rename {test => tests}/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-win32/focused-input.png (100%) rename {test => tests}/beforeunload.spec.ts (86%) rename {test => tests}/browsercontext-add-cookies.spec.ts (97%) rename {test => tests}/browsercontext-add-init-script.spec.ts (94%) rename {test => tests}/browsercontext-basic.spec.ts (98%) rename {test => tests}/browsercontext-clearcookies.spec.ts (96%) rename {test => tests}/browsercontext-cookies.spec.ts (93%) rename {test => tests}/browsercontext-credentials.spec.ts (87%) rename {test => tests}/browsercontext-csp.spec.ts (97%) rename {test => tests}/browsercontext-device.spec.ts (95%) rename {test => tests}/browsercontext-dsf.spec.ts (95%) rename {test => tests}/browsercontext-expose-function.spec.ts (98%) rename {test => tests}/browsercontext-locale.spec.ts (99%) rename {test => tests}/browsercontext-page-event.spec.ts (93%) rename {test => tests}/browsercontext-proxy.spec.ts (92%) rename {test => tests}/browsercontext-route.spec.ts (98%) rename {test => tests}/browsercontext-set-extra-http-headers.spec.ts (96%) rename {test => tests}/browsercontext-storage-state.spec.ts (89%) rename {test => tests}/browsercontext-timezone-id.spec.ts (98%) rename {test => tests}/browsercontext-user-agent.spec.ts (96%) rename {test => tests}/browsercontext-viewport-mobile.spec.ts (97%) rename {test => tests}/browsercontext-viewport.spec.ts (92%) rename {test => tests}/browsertype-launch-server.spec.ts (86%) rename {test => tests}/browsertype-launch.spec.ts (86%) rename {test => tests}/capabilities.spec.ts (61%) rename {test => tests}/channels.spec.ts (92%) rename {test => tests}/css-parser.spec.ts (98%) rename {test => tests}/defaultbrowsercontext-1.spec.ts (96%) rename {test => tests}/defaultbrowsercontext-2.spec.ts (85%) rename {test => tests}/downloads-path.spec.ts (91%) rename {test => tests}/geolocation.spec.ts (86%) rename {test => tests}/har.spec.ts (87%) rename {test => tests}/headful.spec.ts (85%) rename {test => tests}/ignorehttpserrors.spec.ts (98%) rename {test => tests}/launcher.spec.ts (86%) rename {test => tests}/logger.spec.ts (97%) rename {test => tests}/pdf.spec.ts (69%) rename {test => tests}/popup.spec.ts (99%) rename {test => tests}/proxy.spec.ts (93%) rename {test => tests}/selector-generator.spec.ts (95%) create mode 100644 tests/tsconfig.json diff --git a/test/pause.spec.ts b/test/pause.spec.ts index ce045a5307..abc8300f26 100644 --- a/test/pause.spec.ts +++ b/test/pause.spec.ts @@ -14,11 +14,10 @@ * limitations under the License. */ -import { expect } from 'folio'; import { Page } from '..'; import { folio } from './fixtures'; import { recorderPageGetter } from './utils'; -const { afterEach, it, describe } = folio; +const { afterEach, it, describe, expect } = folio; describe('pause', (suite, { mode }) => { suite.skip(mode !== 'default'); diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-darwin/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-darwin/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-darwin/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-darwin/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-linux/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-linux/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-linux/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-linux/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-win32/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-win32/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-win32/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/chromium-win32/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-darwin/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-darwin/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-darwin/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-darwin/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-linux/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-linux/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-linux/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-linux/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-win32/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-win32/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-win32/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/firefox-win32/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-darwin/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-darwin/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-darwin/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-darwin/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-linux/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-linux/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-linux/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-linux/focused-input.png diff --git a/test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-win32/focused-input.png b/tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-win32/focused-input.png similarity index 100% rename from test/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-win32/focused-input.png rename to tests/__snapshots__/headful/focused-input-should-produce-the-same-screenshot/webkit-win32/focused-input.png diff --git a/test/beforeunload.spec.ts b/tests/beforeunload.spec.ts similarity index 86% rename from test/beforeunload.spec.ts rename to tests/beforeunload.spec.ts index 55c1e9b620..f0cd52a93e 100644 --- a/test/beforeunload.spec.ts +++ b/tests/beforeunload.spec.ts @@ -15,10 +15,9 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; -it('should close browser with beforeunload page', (test, {browserName}) => { -}, async ({server, browserType, browserOptions }) => { +it('should close browser with beforeunload page', async ({server, browserType, browserOptions }) => { const browser = await browserType.launch(browserOptions); const page = await browser.newPage(); await page.goto(server.PREFIX + '/beforeunload.html'); @@ -28,8 +27,7 @@ it('should close browser with beforeunload page', (test, {browserName}) => { await browser.close(); }); -it('should close browsercontext with beforeunload page', (test, {browserName}) => { -}, async ({server, contextFactory }) => { +it('should close browsercontext with beforeunload page', async ({server, contextFactory }) => { const browserContext = await contextFactory(); const page = await browserContext.newPage(); await page.goto(server.PREFIX + '/beforeunload.html'); @@ -39,7 +37,8 @@ it('should close browsercontext with beforeunload page', (test, {browserName}) = await browserContext.close(); }); -it('should close page with beforeunload listener', async ({context, server}) => { +it('should close page with beforeunload listener', async ({contextFactory, server}) => { + const context = await contextFactory(); const newPage = await context.newPage(); await newPage.goto(server.PREFIX + '/beforeunload.html'); // We have to interact with a page so that 'beforeunload' handlers @@ -48,7 +47,8 @@ it('should close page with beforeunload listener', async ({context, server}) => await newPage.close(); }); -it('should run beforeunload if asked for', async ({context, server, isChromium, isWebKit}) => { +it('should run beforeunload if asked for', async ({contextFactory, server, isChromium, isWebKit}) => { + const context = await contextFactory(); const newPage = await context.newPage(); await newPage.goto(server.PREFIX + '/beforeunload.html'); // We have to interact with a page so that 'beforeunload' handlers diff --git a/test/browsercontext-add-cookies.spec.ts b/tests/browsercontext-add-cookies.spec.ts similarity index 97% rename from test/browsercontext-add-cookies.spec.ts rename to tests/browsercontext-add-cookies.spec.ts index d937bfea79..cd436ce1b8 100644 --- a/test/browsercontext-add-cookies.spec.ts +++ b/tests/browsercontext-add-cookies.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { contextTest as it, expect } from './config/browserTest'; +import { slowTest as playwrightTest } from './config/playwrightTest'; it('should work', async ({context, page, server}) => { await page.goto(server.EMPTY_PAGE); @@ -157,9 +158,7 @@ it('should isolate send cookie header', async ({server, context, browser}) => { } }); -it('should isolate cookies between launches', test => { - test.slow(); -}, async ({browserType, server, browserOptions}) => { +playwrightTest('should isolate cookies between launches', async ({browserType, server, browserOptions}) => { const browser1 = await browserType.launch(browserOptions); const context1 = await browser1.newContext(); await context1.addCookies([{url: server.EMPTY_PAGE, name: 'cookie-in-context-1', value: 'value', expires: Date.now() / 1000 + 10000}]); diff --git a/test/browsercontext-add-init-script.spec.ts b/tests/browsercontext-add-init-script.spec.ts similarity index 94% rename from test/browsercontext-add-init-script.spec.ts rename to tests/browsercontext-add-init-script.spec.ts index a8bba367a5..0649bcaf74 100644 --- a/test/browsercontext-add-init-script.spec.ts +++ b/tests/browsercontext-add-init-script.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { contextTest as it, expect } from './config/browserTest'; import path from 'path'; it('should work with browser context scripts', async ({ context, server }) => { @@ -54,7 +54,7 @@ it('should work without navigation in popup', async ({ context }) => { }); it('should work with browser context scripts with a path', async ({ context, server }) => { - await context.addInitScript({ path: path.join(__dirname, 'assets/injectedfile.js') }); + await context.addInitScript({ path: path.join(__dirname, '../test/assets/injectedfile.js') }); const page = await context.newPage(); await page.goto(server.PREFIX + '/tamperable.html'); expect(await page.evaluate(() => window['result'])).toBe(123); diff --git a/test/browsercontext-basic.spec.ts b/tests/browsercontext-basic.spec.ts similarity index 98% rename from test/browsercontext-basic.spec.ts rename to tests/browsercontext-basic.spec.ts index c8eb4a2401..fa2675c12d 100644 --- a/test/browsercontext-basic.spec.ts +++ b/tests/browsercontext-basic.spec.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; -import { verifyViewport } from './utils'; +import { test as it, expect } from './config/browserTest'; +import { verifyViewport } from '../test/utils'; it('should create new context', async function({browser}) { expect(browser.contexts().length).toBe(0); diff --git a/test/browsercontext-clearcookies.spec.ts b/tests/browsercontext-clearcookies.spec.ts similarity index 96% rename from test/browsercontext-clearcookies.spec.ts rename to tests/browsercontext-clearcookies.spec.ts index 43a58bc2c8..78427795c6 100644 --- a/test/browsercontext-clearcookies.spec.ts +++ b/tests/browsercontext-clearcookies.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { contextTest as it, expect } from './config/browserTest'; it('should clear cookies', async ({context, page, server}) => { await page.goto(server.EMPTY_PAGE); diff --git a/test/browsercontext-cookies.spec.ts b/tests/browsercontext-cookies.spec.ts similarity index 93% rename from test/browsercontext-cookies.spec.ts rename to tests/browsercontext-cookies.spec.ts index 50057dfdb2..c2443e4e30 100644 --- a/test/browsercontext-cookies.spec.ts +++ b/tests/browsercontext-cookies.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { contextTest as it, expect } from './config/browserTest'; it('should return no cookies in pristine browser context', async ({context, page, server}) => { expect(await context.cookies()).toEqual([]); @@ -73,9 +73,9 @@ it('should properly report httpOnly cookie', async ({context, page, server}) => expect(cookies[0].httpOnly).toBe(true); }); -it('should properly report "Strict" sameSite cookie', (test, { browserName, platform }) => { - test.fail(browserName === 'webkit' && platform === 'win32'); -}, async ({context, page, server}) => { +it('should properly report "Strict" sameSite cookie', async ({context, page, server, browserName, platform}) => { + it.fail(browserName === 'webkit' && platform === 'win32'); + server.setRoute('/empty.html', (req, res) => { res.setHeader('Set-Cookie', 'name=value;SameSite=Strict'); res.end(); @@ -86,9 +86,9 @@ it('should properly report "Strict" sameSite cookie', (test, { browserName, plat expect(cookies[0].sameSite).toBe('Strict'); }); -it('should properly report "Lax" sameSite cookie', (test, { browserName, platform }) => { - test.fail(browserName === 'webkit' && platform === 'win32'); -}, async ({context, page, server}) => { +it('should properly report "Lax" sameSite cookie', async ({context, page, server, browserName, platform}) => { + it.fail(browserName === 'webkit' && platform === 'win32'); + server.setRoute('/empty.html', (req, res) => { res.setHeader('Set-Cookie', 'name=value;SameSite=Lax'); res.end(); diff --git a/test/browsercontext-credentials.spec.ts b/tests/browsercontext-credentials.spec.ts similarity index 87% rename from test/browsercontext-credentials.spec.ts rename to tests/browsercontext-credentials.spec.ts index 711835dcd3..2d2b3a76d2 100644 --- a/test/browsercontext-credentials.spec.ts +++ b/tests/browsercontext-credentials.spec.ts @@ -15,11 +15,11 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; + +it('should fail without credentials', async ({browser, server, browserName, headful}) => { + it.fail(browserName === 'chromium' && headful); -it('should fail without credentials', (test, { browserName, headful}) => { - test.fail(browserName === 'chromium' && headful); -}, async ({browser, server}) => { server.setAuth('/empty.html', 'user', 'pass'); const context = await browser.newContext(); const page = await context.newPage(); @@ -28,9 +28,9 @@ it('should fail without credentials', (test, { browserName, headful}) => { await context.close(); }); -it('should work with setHTTPCredentials', (test, { browserName, headful }) => { - test.fail(browserName === 'chromium' && headful); -}, async ({browser, server}) => { +it('should work with setHTTPCredentials', async ({browser, server, browserName, headful}) => { + it.fail(browserName === 'chromium' && headful); + server.setAuth('/empty.html', 'user', 'pass'); const context = await browser.newContext(); const page = await context.newPage(); diff --git a/test/browsercontext-csp.spec.ts b/tests/browsercontext-csp.spec.ts similarity index 97% rename from test/browsercontext-csp.spec.ts rename to tests/browsercontext-csp.spec.ts index 3146e7b45d..229731887a 100644 --- a/test/browsercontext-csp.spec.ts +++ b/tests/browsercontext-csp.spec.ts @@ -14,8 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; -import { attachFrame } from './utils'; + +import { test as it, expect } from './config/browserTest'; +import { attachFrame } from '../test/utils'; it('should bypass CSP meta tag', async ({browser, server}) => { // Make sure CSP prohibits addScriptTag. diff --git a/test/browsercontext-device.spec.ts b/tests/browsercontext-device.spec.ts similarity index 95% rename from test/browsercontext-device.spec.ts rename to tests/browsercontext-device.spec.ts index 6a6b7a126f..3608445ae5 100644 --- a/test/browsercontext-device.spec.ts +++ b/tests/browsercontext-device.spec.ts @@ -15,11 +15,13 @@ * limitations under the License. */ -import { it, expect, describe } from './fixtures'; +import { test as it, expect } from './config/browserTest'; + +it.describe('device', () => { + it.beforeEach(async ({browserName}) => { + it.skip(browserName === 'firefox'); + }); -describe('device', (suite, { browserName }) => { - suite.skip(browserName === 'firefox'); -}, () => { it('should work', async ({playwright, browser, server}) => { const iPhone = playwright.devices['iPhone 6']; const context = await browser.newContext({ ...iPhone }); @@ -81,9 +83,9 @@ describe('device', (suite, { browserName }) => { await context.close(); }); - it('should reset scroll top after a navigation', (test, {browserName}) => { - test.skip(browserName === 'webkit'); - }, async ({server, contextFactory, playwright, contextOptions}) => { + it('should reset scroll top after a navigation', async ({server, contextFactory, playwright, contextOptions, browserName}) => { + it.skip(browserName === 'webkit'); + const device = playwright.devices['iPhone 6']; const context = await contextFactory({ ...contextOptions, @@ -98,9 +100,9 @@ describe('device', (suite, { browserName }) => { await context.close(); }); - it('should scroll to a precise position with mobile scale', (test, {browserName}) => { - test.skip(browserName === 'webkit'); - }, async ({server, contextFactory, playwright, contextOptions}) => { + it('should scroll to a precise position with mobile scale', async ({server, contextFactory, playwright, contextOptions, browserName}) => { + it.skip(browserName === 'webkit'); + const device = playwright.devices['iPhone 6']; const context = await contextFactory({ ...contextOptions, diff --git a/test/browsercontext-dsf.spec.ts b/tests/browsercontext-dsf.spec.ts similarity index 95% rename from test/browsercontext-dsf.spec.ts rename to tests/browsercontext-dsf.spec.ts index ecae80127e..7deeb97ff6 100644 --- a/test/browsercontext-dsf.spec.ts +++ b/tests/browsercontext-dsf.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; it('should fetch lodpi assets', async ({ contextFactory, server}) => { const context = await contextFactory({ diff --git a/test/browsercontext-expose-function.spec.ts b/tests/browsercontext-expose-function.spec.ts similarity index 98% rename from test/browsercontext-expose-function.spec.ts rename to tests/browsercontext-expose-function.spec.ts index 4e60ce595b..0823a2fb9f 100644 --- a/test/browsercontext-expose-function.spec.ts +++ b/tests/browsercontext-expose-function.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; + +import { contextTest as it, expect } from './config/browserTest'; it('expose binding should work', async ({context}) => { let bindingSource; diff --git a/test/browsercontext-locale.spec.ts b/tests/browsercontext-locale.spec.ts similarity index 99% rename from test/browsercontext-locale.spec.ts rename to tests/browsercontext-locale.spec.ts index c98aa3e6a8..5b1c3465c0 100644 --- a/test/browsercontext-locale.spec.ts +++ b/tests/browsercontext-locale.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; + +import { test as it, expect } from './config/browserTest'; it('should affect accept-language header', async ({browser, server}) => { const context = await browser.newContext({ locale: 'fr-CH' }); diff --git a/test/browsercontext-page-event.spec.ts b/tests/browsercontext-page-event.spec.ts similarity index 93% rename from test/browsercontext-page-event.spec.ts rename to tests/browsercontext-page-event.spec.ts index 27cce17ae2..21666175a7 100644 --- a/test/browsercontext-page-event.spec.ts +++ b/tests/browsercontext-page-event.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; it('should have url', async ({browser, server}) => { const context = await browser.newContext(); @@ -157,9 +157,9 @@ it('should fire page lifecycle events', async function({browser, server}) { await context.close(); }); -it('should work with Shift-clicking', (test, { browserName }) => { - test.fixme(browserName === 'webkit', 'WebKit: Shift+Click does not open a new window.'); -}, async ({browser, server}) => { +it('should work with Shift-clicking', async ({browser, server, browserName}) => { + it.fixme(browserName === 'webkit', 'WebKit: Shift+Click does not open a new window.'); + const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); @@ -172,10 +172,10 @@ it('should work with Shift-clicking', (test, { browserName }) => { await context.close(); }); -it('should work with Ctrl-clicking', (test, { browserName }) => { - test.fixme(browserName === 'webkit', 'Ctrl+Click does not open a new tab.'); - test.fixme(browserName === 'firefox', 'Reports an opener in this case.'); -}, async ({browser, server, isMac}) => { +it('should work with Ctrl-clicking', async ({browser, server, isMac, browserName}) => { + it.fixme(browserName === 'webkit', 'Ctrl+Click does not open a new tab.'); + it.fixme(browserName === 'firefox', 'Reports an opener in this case.'); + const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); diff --git a/test/browsercontext-proxy.spec.ts b/tests/browsercontext-proxy.spec.ts similarity index 92% rename from test/browsercontext-proxy.spec.ts rename to tests/browsercontext-proxy.spec.ts index ee968c1654..71dbee955a 100644 --- a/test/browsercontext-proxy.spec.ts +++ b/tests/browsercontext-proxy.spec.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { folio as baseFolio } from './fixtures'; - -const fixtures = baseFolio.extend(); -fixtures.browserOptions.override(async ({ browserOptions }, run) => { - await run({ ...browserOptions, proxy: { server: 'per-context' } }); -}); - -const { it, expect } = fixtures.build(); +import { proxyTest as it, expect } from './config/browserTest'; it('should throw for missing global proxy', async ({ browserType, browserOptions, server }) => { delete browserOptions.proxy; @@ -164,9 +157,9 @@ it('should authenticate with empty password', async ({contextFactory, contextOpt }); -it('should isolate proxy credentials between contexts', (test, { browserName }) => { - test.fixme(browserName === 'firefox', 'Credentials from the first context stick around'); -}, async ({contextFactory, contextOptions, server}) => { +it('should isolate proxy credentials between contexts', async ({contextFactory, contextOptions, server, browserName}) => { + it.fixme(browserName === 'firefox', 'Credentials from the first context stick around'); + server.setRoute('/target.html', async (req, res) => { const auth = req.headers['proxy-authorization']; if (!auth) { @@ -200,9 +193,9 @@ it('should isolate proxy credentials between contexts', (test, { browserName }) } }); -it('should exclude patterns', (test, { browserName, headful }) => { - test.fixme(browserName === 'chromium' && headful, 'Chromium headful crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame.'); -}, async ({contextFactory, contextOptions, server}) => { +it('should exclude patterns', async ({contextFactory, contextOptions, server, browserName, headful}) => { + it.fixme(browserName === 'chromium' && headful, 'Chromium headful crashes with CHECK(!in_frame_tree_) in RenderFrameImpl::OnDeleteFrame.'); + server.setRoute('/target.html', async (req, res) => { res.end('Served by the proxy'); }); diff --git a/test/browsercontext-route.spec.ts b/tests/browsercontext-route.spec.ts similarity index 98% rename from test/browsercontext-route.spec.ts rename to tests/browsercontext-route.spec.ts index 6bec90882d..65bedaba67 100644 --- a/test/browsercontext-route.spec.ts +++ b/tests/browsercontext-route.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; + +import { test as it, expect } from './config/browserTest'; it('should intercept', async ({browser, server}) => { const context = await browser.newContext(); diff --git a/test/browsercontext-set-extra-http-headers.spec.ts b/tests/browsercontext-set-extra-http-headers.spec.ts similarity index 96% rename from test/browsercontext-set-extra-http-headers.spec.ts rename to tests/browsercontext-set-extra-http-headers.spec.ts index 5fe0a97c1c..f486508f9c 100644 --- a/test/browsercontext-set-extra-http-headers.spec.ts +++ b/tests/browsercontext-set-extra-http-headers.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; it('should override extra headers from browser context', async ({browser, server}) => { const context = await browser.newContext({ diff --git a/test/browsercontext-storage-state.spec.ts b/tests/browsercontext-storage-state.spec.ts similarity index 89% rename from test/browsercontext-storage-state.spec.ts rename to tests/browsercontext-storage-state.spec.ts index e8f9378bb2..2d6fef9416 100644 --- a/test/browsercontext-storage-state.spec.ts +++ b/tests/browsercontext-storage-state.spec.ts @@ -15,10 +15,11 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; import fs from 'fs'; -it('should capture local storage', async ({ context }) => { +it('should capture local storage', async ({ contextFactory }) => { + const context = await contextFactory(); const page1 = await context.newPage(); await page1.route('**/*', route => { route.fulfill({ body: '' }).catch(() => {}); @@ -71,7 +72,8 @@ it('should set local storage', async ({ browser }) => { await context.close(); }); -it('should round-trip through the file', async ({ browser, context, testInfo }) => { +it('should round-trip through the file', async ({ contextFactory }, testInfo) => { + const context = await contextFactory(); const page1 = await context.newPage(); await page1.route('**/*', route => { route.fulfill({ body: '' }).catch(() => {}); @@ -88,7 +90,7 @@ it('should round-trip through the file', async ({ browser, context, testInfo }) const written = await fs.promises.readFile(path, 'utf8'); expect(JSON.stringify(state, undefined, 2)).toBe(written); - const context2 = await browser.newContext({ storageState: path }); + const context2 = await contextFactory({ storageState: path }); const page2 = await context2.newPage(); await page2.route('**/*', route => { route.fulfill({ body: '' }).catch(() => {}); diff --git a/test/browsercontext-timezone-id.spec.ts b/tests/browsercontext-timezone-id.spec.ts similarity index 98% rename from test/browsercontext-timezone-id.spec.ts rename to tests/browsercontext-timezone-id.spec.ts index 4e0c199726..5be420f3e2 100644 --- a/test/browsercontext-timezone-id.spec.ts +++ b/tests/browsercontext-timezone-id.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; + +import { test as it, expect } from './config/browserTest'; it('should work', async ({ browser }) => { const func = () => new Date(1479579154987).toString(); diff --git a/test/browsercontext-user-agent.spec.ts b/tests/browsercontext-user-agent.spec.ts similarity index 96% rename from test/browsercontext-user-agent.spec.ts rename to tests/browsercontext-user-agent.spec.ts index 2cf7c390f9..d25186c246 100644 --- a/test/browsercontext-user-agent.spec.ts +++ b/tests/browsercontext-user-agent.spec.ts @@ -14,8 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; -import { attachFrame } from './utils'; + +import { test as it, expect } from './config/browserTest'; +import { attachFrame } from '../test/utils'; it('should work', async ({browser, server}) => { { diff --git a/test/browsercontext-viewport-mobile.spec.ts b/tests/browsercontext-viewport-mobile.spec.ts similarity index 97% rename from test/browsercontext-viewport-mobile.spec.ts rename to tests/browsercontext-viewport-mobile.spec.ts index c62051a4c8..4a63b60ac2 100644 --- a/test/browsercontext-viewport-mobile.spec.ts +++ b/tests/browsercontext-viewport-mobile.spec.ts @@ -15,11 +15,13 @@ * limitations under the License. */ -import { it, expect, describe } from './fixtures'; +import { test as it, expect } from './config/browserTest'; + +it.describe('mobile viewport', () => { + it.beforeEach(async ({ browserName }) => { + it.skip(browserName === 'firefox'); + }); -describe('mobile viewport', (suite, { browserName }) => { - suite.skip(browserName === 'firefox'); -}, () => { it('should support mobile emulation', async ({playwright, browser, server}) => { const iPhone = playwright.devices['iPhone 6']; const context = await browser.newContext({ ...iPhone }); diff --git a/test/browsercontext-viewport.spec.ts b/tests/browsercontext-viewport.spec.ts similarity index 92% rename from test/browsercontext-viewport.spec.ts rename to tests/browsercontext-viewport.spec.ts index b0fa8c5c2c..f9922aa47b 100644 --- a/test/browsercontext-viewport.spec.ts +++ b/tests/browsercontext-viewport.spec.ts @@ -14,8 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect } from './fixtures'; -import { verifyViewport } from './utils'; + +import { test as it, expect } from './config/pageTest'; +import { test as browserTest } from './config/browserTest'; +import { verifyViewport } from '../test/utils'; + +it.beforeEach(async () => { + it.skip(!!process.env.PW_ANDROID_TESTS); +}); it('should get the proper default viewport size', async ({page, server}) => { await verifyViewport(page, 1280, 720); @@ -95,7 +101,7 @@ it('should not have touch by default', async ({page, server}) => { expect(await page.evaluate(() => document.body.textContent.trim())).toBe('NO'); }); -it('should support touch with null viewport', async ({browser, server}) => { +browserTest('should support touch with null viewport', async ({browser, server}) => { const context = await browser.newContext({ viewport: null, hasTouch: true }); const page = await context.newPage(); await page.goto(server.PREFIX + '/mobile.html'); @@ -103,7 +109,7 @@ it('should support touch with null viewport', async ({browser, server}) => { await context.close(); }); -it('should report null viewportSize when given null viewport', async ({browser, server}) => { +browserTest('should report null viewportSize when given null viewport', async ({browser, server}) => { const context = await browser.newContext({ viewport: null }); const page = await context.newPage(); expect(page.viewportSize()).toBe(null); diff --git a/test/browsertype-launch-server.spec.ts b/tests/browsertype-launch-server.spec.ts similarity index 86% rename from test/browsertype-launch-server.spec.ts rename to tests/browsertype-launch-server.spec.ts index 9574d2b671..f5d95e89d6 100644 --- a/test/browsertype-launch-server.spec.ts +++ b/tests/browsertype-launch-server.spec.ts @@ -15,21 +15,23 @@ * limitations under the License. */ -import { folio } from './fixtures'; -const { it, expect, describe } = folio; +import { test as it, expect } from './config/playwrightTest'; + +it.describe('launch server', () => { + it.beforeEach(async ({ mode}) => { + it.skip(mode !== 'default'); + }); -describe('launch server', (suite, { mode }) => { - suite.skip(mode !== 'default'); -}, () => { it('should work', async ({browserType, browserOptions}) => { const browserServer = await browserType.launchServer(browserOptions); expect(browserServer.wsEndpoint()).not.toBe(null); await browserServer.close(); }); - it('should work with port', async ({browserType, browserOptions, testWorkerIndex}) => { - const browserServer = await browserType.launchServer({ ...browserOptions, port: 8800 + testWorkerIndex }); - expect(browserServer.wsEndpoint()).toContain(String(8800 + testWorkerIndex)); + it('should work with port', async ({browserType, browserOptions}, testInfo) => { + const port = 8800 + testInfo.workerIndex; + const browserServer = await browserType.launchServer({ ...browserOptions, port }); + expect(browserServer.wsEndpoint()).toContain(String(port)); await browserServer.close(); }); @@ -60,9 +62,9 @@ describe('launch server', (suite, { mode }) => { await browserServer.close(); }); - it('should fire close event', (test, { browserChannel }) => { - test.fixme(!!browserChannel, 'Uncomment on roll'); - }, async ({browserType, browserOptions}) => { + it('should fire close event', async ({browserType, browserOptions, browserChannel}) => { + it.fixme(!!browserChannel, 'Uncomment on roll'); + const browserServer = await browserType.launchServer(browserOptions); const [result] = await Promise.all([ // @ts-expect-error The signal parameter is not documented. diff --git a/test/browsertype-launch.spec.ts b/tests/browsertype-launch.spec.ts similarity index 86% rename from test/browsertype-launch.spec.ts rename to tests/browsertype-launch.spec.ts index 92246e26d4..2b4f5c7a88 100644 --- a/test/browsertype-launch.spec.ts +++ b/tests/browsertype-launch.spec.ts @@ -16,7 +16,7 @@ */ import path from 'path'; -import { it, expect } from './fixtures'; +import { test as it, slowTest, expect } from './config/playwrightTest'; it('should reject all promises when browser is closed', async ({browserType, browserOptions}) => { const browser = await browserType.launch(browserOptions); @@ -55,9 +55,9 @@ it('should throw if port option is passed for persistent context', async ({brows expect(error.message).toContain('Cannot specify a port without launching as a server.'); }); -it('should throw if page argument is passed', (test, { browserName }) => { - test.skip(browserName === 'firefox'); -}, async ({browserType, browserOptions}) => { +it('should throw if page argument is passed', async ({browserType, browserOptions, browserName}) => { + it.skip(browserName === 'firefox'); + let waitError = null; const options = Object.assign({}, browserOptions, { args: ['http://example.com'] }); await browserType.launch(options).catch(e => waitError = e); @@ -65,7 +65,7 @@ it('should throw if page argument is passed', (test, { browserName }) => { }); it('should reject if launched browser fails immediately', async ({browserType, browserOptions}) => { - const options = Object.assign({}, browserOptions, {executablePath: path.join(__dirname, 'assets', 'dummy_bad_browser_executable.js')}); + const options = Object.assign({}, browserOptions, {executablePath: path.join(__dirname, '..', 'test', 'assets', 'dummy_bad_browser_executable.js')}); let waitError = null; await browserType.launch(options).catch(e => waitError = e); expect(waitError.message).toContain('== logs =='); @@ -78,9 +78,9 @@ it('should reject if executable path is invalid', async ({browserType, browserOp expect(waitError.message).toContain('Failed to launch'); }); -it('should handle timeout', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions}) => { +it('should handle timeout', async ({browserType, browserOptions, mode}) => { + it.skip(mode !== 'default'); + const options = { ...browserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) }; const error = await browserType.launch(options).catch(e => e); expect(error.message).toContain(`browserType.launch: Timeout 5000ms exceeded.`); @@ -88,27 +88,25 @@ it('should handle timeout', (test, { mode }) => { expect(error.message).toContain(` pid=`); }); -it('should handle exception', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions}) => { +it('should handle exception', async ({browserType, browserOptions, mode}) => { + it.skip(mode !== 'default'); + const e = new Error('Dummy'); const options = { ...browserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 }; const error = await browserType.launch(options).catch(e => e); expect(error.message).toContain('Dummy'); }); -it('should report launch log', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions}) => { +it('should report launch log', async ({browserType, browserOptions, mode}) => { + it.skip(mode !== 'default'); + const e = new Error('Dummy'); const options = { ...browserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 }; const error = await browserType.launch(options).catch(e => e); expect(error.message).toContain(''); }); -it('should accept objects as options', (test, parameters) => { - test.slow(); -}, async ({browserType, browserOptions}) => { +slowTest('should accept objects as options', async ({browserType, browserOptions}) => { // @ts-expect-error process is not a real option. const browser = await browserType.launch({ ...browserOptions, process }); await browser.close(); diff --git a/test/capabilities.spec.ts b/tests/capabilities.spec.ts similarity index 61% rename from test/capabilities.spec.ts rename to tests/capabilities.spec.ts index 4c331b89a5..c00e80c4fc 100644 --- a/test/capabilities.spec.ts +++ b/tests/capabilities.spec.ts @@ -16,16 +16,20 @@ import os from 'os'; import url from 'url'; -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; -it('Web Assembly should work', (test, { browserName, platform }) => { - test.fail(browserName === 'webkit' && platform === 'win32'); -}, async function({page, server}) { +it('Web Assembly should work', async function({contextFactory, server, browserName, platform}) { + it.fail(browserName === 'webkit' && platform === 'win32'); + + const context = await contextFactory(); + const page = await context.newPage(); await page.goto(server.PREFIX + '/wasm/table2.html'); expect(await page.evaluate('loadTable()')).toBe('42, 83'); }); -it('WebSocket should work', async ({page, server}) => { +it('WebSocket should work', async ({contextFactory, server}) => { + const context = await contextFactory(); + const page = await context.newPage(); const value = await page.evaluate(port => { let cb; const result = new Promise(f => cb = f); @@ -37,7 +41,7 @@ it('WebSocket should work', async ({page, server}) => { expect(value).toBe('incoming'); }); -it('should respect CSP', async ({page, server}) => { +it('should respect CSP', async ({contextFactory, server}) => { server.setRoute('/empty.html', async (req, res) => { res.setHeader('Content-Security-Policy', `script-src 'unsafe-inline';`); res.end(` @@ -47,19 +51,22 @@ it('should respect CSP', async ({page, server}) => { `); }); + const context = await contextFactory(); + const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS'); }); -it('should play video', (test, { browserName, platform }) => { - test.fixme(browserName === 'webkit' && platform !== 'darwin'); - // Doesnt' work on BigSur - test.fixme(browserName === 'webkit' && platform === 'darwin' && parseInt(os.release(), 10) >= 20); -}, async ({page, asset, isWebKit}) => { +it('should play video', async ({contextFactory, asset, isWebKit, browserName, platform}) => { // TODO: the test passes on Windows locally but fails on GitHub Action bot, // apparently due to a Media Pack issue in the Windows Server. // Also the test is very flaky on Linux WebKit. - // + it.fixme(browserName === 'webkit' && platform !== 'darwin'); + it.fixme(browserName === 'webkit' && platform === 'darwin' && parseInt(os.release(), 10) >= 20, 'Does not work on BigSur'); + + const context = await contextFactory(); + const page = await context.newPage(); + // Safari only plays mp4 so we test WebKit with an .mp4 clip. const fileName = isWebKit ? 'video_mp4.html' : 'video.html'; const absolutePath = asset(fileName); @@ -70,9 +77,11 @@ it('should play video', (test, { browserName, platform }) => { await page.$eval('video', v => v.pause()); }); -it('should support webgl', (test, {browserName, headful}) => { - test.fixme(browserName === 'firefox' && !headful); -}, async ({page}) => { +it('should support webgl', async ({contextFactory, browserName, headful}) => { + it.fixme(browserName === 'firefox' && !headful); + + const context = await contextFactory(); + const page = await context.newPage(); const hasWebGL = await page.evaluate(() => { const canvas = document.createElement('canvas'); return !!canvas.getContext('webgl'); @@ -80,11 +89,13 @@ it('should support webgl', (test, {browserName, headful}) => { expect(hasWebGL).toBe(true); }); -it('should support webgl 2', (test, {browserName, headful}) => { - test.skip(browserName === 'webkit', 'WebKit doesn\'t have webgl2 enabled yet upstream.'); - test.fixme(browserName === 'firefox' && !headful); - test.fixme(browserName === 'chromium' && headful, 'chromium doesn\'t like webgl2 when running under xvfb'); -}, async ({page}) => { +it('should support webgl 2', async ({contextFactory, browserName, headful}) => { + it.skip(browserName === 'webkit', 'WebKit doesn\'t have webgl2 enabled yet upstream.'); + it.fixme(browserName === 'firefox' && !headful); + it.fixme(browserName === 'chromium' && headful, 'chromium doesn\'t like webgl2 when running under xvfb'); + + const context = await contextFactory(); + const page = await context.newPage(); const hasWebGL2 = await page.evaluate(() => { const canvas = document.createElement('canvas'); return !!canvas.getContext('webgl2'); diff --git a/test/channels.spec.ts b/tests/channels.spec.ts similarity index 92% rename from test/channels.spec.ts rename to tests/channels.spec.ts index d6441405ce..0d6baa9976 100644 --- a/test/channels.spec.ts +++ b/tests/channels.spec.ts @@ -16,14 +16,10 @@ */ import domain from 'domain'; -import { folio } from './fixtures'; -const { it, expect } = folio; +import { test as it, expect } from './config/playwrightTest'; -it('should work', async ({browser}) => { - expect(!!browser['_connection']).toBeTruthy(); -}); - -it('should scope context handles', async ({browser, server}) => { +it('should scope context handles', async ({browserType, browserOptions, server}) => { + const browser = await browserType.launch(browserOptions); const GOLDEN_PRECONDITION = { _guid: '', objects: [ @@ -68,11 +64,13 @@ it('should scope context handles', async ({browser, server}) => { await context.close(); await expectScopeState(browser, GOLDEN_PRECONDITION); + await browser.close(); }); -it('should scope CDPSession handles', (test, { browserName }) => { - test.skip(browserName !== 'chromium'); -}, async ({browserType, browser}) => { +it('should scope CDPSession handles', async ({browserType, browserOptions, browserName}) => { + it.skip(browserName !== 'chromium'); + + const browser = await browserType.launch(browserOptions); const GOLDEN_PRECONDITION = { _guid: '', objects: [ @@ -109,6 +107,8 @@ it('should scope CDPSession handles', (test, { browserName }) => { await session.detach(); await expectScopeState(browserType, GOLDEN_PRECONDITION); + + await browser.close(); }); it('should scope browser handles', async ({browserType, browserOptions}) => { @@ -117,10 +117,7 @@ it('should scope browser handles', async ({browserType, browserOptions}) => { objects: [ { _guid: 'Android', objects: [] }, { _guid: 'BrowserType', objects: [] }, - { _guid: 'BrowserType', objects: [ - { _guid: 'Browser', objects: [] }, - ] - }, + { _guid: 'BrowserType', objects: [] }, { _guid: 'BrowserType', objects: [] }, { _guid: 'Electron', objects: [] }, { _guid: 'Playwright', objects: [] }, @@ -138,7 +135,6 @@ it('should scope browser handles', async ({browserType, browserOptions}) => { { _guid: 'BrowserType', objects: [] }, { _guid: 'BrowserType', objects: [] }, { _guid: 'BrowserType', objects: [ - { _guid: 'Browser', objects: [] }, { _guid: 'Browser', objects: [ { _guid: 'BrowserContext', objects: [] } diff --git a/tests/config/androidTest.ts b/tests/config/androidTest.ts index a199291edb..07de5bb1ee 100644 --- a/tests/config/androidTest.ts +++ b/tests/config/androidTest.ts @@ -18,7 +18,7 @@ import { newTestType } from '../folio/out'; import type { AndroidDevice } from '../../index'; import type { CommonTestArgs } from './pageTest'; import type { ServerTestArgs } from './serverTest'; -export { expect } from 'folio'; +export { expect } from '../folio/out'; export type AndroidTestArgs = CommonTestArgs & { androidDevice: AndroidDevice; diff --git a/tests/config/browserEnv.ts b/tests/config/browserEnv.ts index 4bf8839f2b..a897978c85 100644 --- a/tests/config/browserEnv.ts +++ b/tests/config/browserEnv.ts @@ -187,8 +187,6 @@ export class PlaywrightEnv implements Env { } async afterEach(testInfo: TestInfo) { - await removeFolders(this._userDataDirs); - this._userDataDirs = []; if (this._persistentContext) { await this._persistentContext.close(); this._persistentContext = undefined; @@ -197,6 +195,8 @@ export class PlaywrightEnv implements Env { await this._remoteServer.close(); this._remoteServer = undefined; } + await removeFolders(this._userDataDirs); + this._userDataDirs = []; } async afterAll(workerInfo: WorkerInfo) { @@ -204,7 +204,7 @@ export class PlaywrightEnv implements Env { const { coverage, uninstall } = this._coverage!; uninstall(); const coveragePath = path.join(__dirname, '..', '..', 'test', 'coverage-report', workerInfo.workerIndex + '.json'); - const coverageJSON = [...coverage.keys()].filter(key => coverage.get(key)); + const coverageJSON = Array.from(coverage.keys()).filter(key => coverage.get(key)); await fs.promises.mkdir(path.dirname(coveragePath), { recursive: true }); await fs.promises.writeFile(coveragePath, JSON.stringify(coverageJSON, undefined, 2), 'utf8'); } diff --git a/tests/config/browserTest.ts b/tests/config/browserTest.ts index 4ab99e028c..de8c7a50ef 100644 --- a/tests/config/browserTest.ts +++ b/tests/config/browserTest.ts @@ -15,9 +15,10 @@ */ import { newTestType } from '../folio/out'; -import type { Browser, BrowserContextOptions, BrowserContext } from '../../index'; +import type { Browser, BrowserContextOptions, BrowserContext, Page } from '../../index'; import type { PlaywrightTestArgs } from './playwrightTest'; -export { expect } from 'folio'; +import type { ServerTestArgs } from './serverTest'; +export { expect } from '../folio/out'; export type BrowserTestArgs = PlaywrightTestArgs & { browser: Browser; @@ -25,4 +26,12 @@ export type BrowserTestArgs = PlaywrightTestArgs & { contextFactory: (options?: BrowserContextOptions) => Promise; }; -export const test = newTestType(); +export const test = newTestType(); +export const proxyTest = newTestType(); + +// Context test guarantees an isolated context. +export type ContextTestArgs = BrowserTestArgs & { + context: BrowserContext; + page: Page; +}; +export const contextTest = newTestType(); diff --git a/tests/config/cliTest.ts b/tests/config/cliTest.ts index cb42a5b250..a8298345f8 100644 --- a/tests/config/cliTest.ts +++ b/tests/config/cliTest.ts @@ -22,7 +22,7 @@ import * as http from 'http'; import * as path from 'path'; import type { Source } from '../../src/server/supplements/recorder/recorderTypes'; import { ChildProcess, spawn } from 'child_process'; -export { expect } from 'folio'; +export { expect } from '../folio/out'; interface CLIHTTPServer { setHandler: (handler: http.RequestListener) => void diff --git a/tests/config/default.config.ts b/tests/config/default.config.ts index 56a7be6be2..7b1d59490c 100644 --- a/tests/config/default.config.ts +++ b/tests/config/default.config.ts @@ -17,7 +17,7 @@ import { setConfig, Config } from '../folio/out'; import * as path from 'path'; import { test as playwrightTest, slowTest as playwrightSlowTest } from './playwrightTest'; -import { test as browserTest } from './browserTest'; +import { test as browserTest, contextTest, proxyTest } from './browserTest'; import { test as pageTest } from './pageTest'; import { test as electronTest } from './electronTest'; import { test as cliTest } from './cliTest'; @@ -64,7 +64,11 @@ for (const browserName of browsers) { playwrightTest.runWith(browserName, serverEnv, new PlaywrightEnv(browserName, options), {}); playwrightSlowTest.runWith(browserName, serverEnv, new PlaywrightEnv(browserName, options), { timeout: config.timeout * 3 }); browserTest.runWith(browserName, serverEnv, new BrowserEnv(browserName, options), {}); + // TODO: perhaps export proxyTest from the test file? + proxyTest.runWith(browserName, serverEnv, new BrowserEnv(browserName, { ...options, proxy: { server: 'per-context' } }), {}); pageTest.runWith(browserName, serverEnv, new PageEnv(browserName, options), {}); + // TODO: get rid of contextTest if there isn't too many of them. + contextTest.runWith(browserName, serverEnv, new PageEnv(browserName, options), {}); cliTest.runWith(browserName, serverEnv, new CLIEnv(browserName, options), {}); if (browserName === 'chromium') electronTest.runWith(browserName, serverEnv, new ElectronEnv({ mode })); diff --git a/tests/config/electronTest.ts b/tests/config/electronTest.ts index cd17ff3214..71db54f0d1 100644 --- a/tests/config/electronTest.ts +++ b/tests/config/electronTest.ts @@ -18,7 +18,7 @@ import { newTestType } from '../folio/out'; import { ElectronApplication, Page } from '../../index'; import type { CommonTestArgs } from './pageTest'; import type { ServerTestArgs } from './serverTest'; -export { expect } from 'folio'; +export { expect } from '../folio/out'; export type ElectronTestArgs = CommonTestArgs & { electronApp: ElectronApplication; diff --git a/tests/config/pageTest.ts b/tests/config/pageTest.ts index 17698c98e2..6add16dad5 100644 --- a/tests/config/pageTest.ts +++ b/tests/config/pageTest.ts @@ -17,7 +17,7 @@ import { newTestType } from '../folio/out'; import type { Page } from '../../index'; import type { ServerTestArgs } from './serverTest'; -export { expect } from 'folio'; +export { expect } from '../folio/out'; export type CommonTestArgs = { mode: 'default' | 'driver' | 'service'; @@ -37,6 +37,7 @@ export type CommonTestArgs = { isLinux: boolean; }; +// Page test does not guarantee an isolated context, just a new page (because Android). export type PageTestArgs = CommonTestArgs & { page: Page; }; diff --git a/tests/config/playwrightTest.ts b/tests/config/playwrightTest.ts index c14650a18f..a020039b8c 100644 --- a/tests/config/playwrightTest.ts +++ b/tests/config/playwrightTest.ts @@ -19,7 +19,7 @@ import type { Browser, BrowserType, LaunchOptions, BrowserContext, Page } from ' import { CommonTestArgs } from './pageTest'; import type { ServerTestArgs } from './serverTest'; import { RemoteServer, RemoteServerOptions } from './remoteServer'; -export { expect } from 'folio'; +export { expect } from '../folio/out'; export type PlaywrightTestArgs = CommonTestArgs & { browserType: BrowserType; diff --git a/tests/config/serverEnv.ts b/tests/config/serverEnv.ts index e3fa2ad944..35ee48d604 100644 --- a/tests/config/serverEnv.ts +++ b/tests/config/serverEnv.ts @@ -14,15 +14,17 @@ * limitations under the License. */ -import type { WorkerInfo, TestInfo } from '../folio/out'; +import type { WorkerInfo, TestInfo, Env } from '../folio/out'; import { TestServer } from '../../utils/testserver'; import * as path from 'path'; import socks from 'socksv5'; +import { ServerTestArgs } from './serverTest'; -export class ServerEnv { +export class ServerEnv implements Env { private _server: TestServer; private _httpsServer: TestServer; private _socksServer: any; + private _socksPort: number; async beforeAll(workerInfo: WorkerInfo) { const assetsPath = path.join(__dirname, '..', '..', 'test', 'assets'); @@ -52,8 +54,8 @@ export class ServerEnv { ].join('\r\n')); } }); - const socksPort = 9107 + workerInfo.workerIndex * 2; - this._socksServer.listen(socksPort, 'localhost'); + this._socksPort = 9107 + workerInfo.workerIndex * 2; + this._socksServer.listen(this._socksPort, 'localhost'); this._socksServer.useAuth(socks.auth.None()); } @@ -61,9 +63,10 @@ export class ServerEnv { this._server.reset(); this._httpsServer.reset(); return { - asset: (p: string) => path.join(__dirname, '..', 'assets', p), + asset: (p: string) => path.join(__dirname, '..', '..', 'test', 'assets', p), server: this._server, httpsServer: this._httpsServer, + socksPort: this._socksPort, }; } diff --git a/test/css-parser.spec.ts b/tests/css-parser.spec.ts similarity index 98% rename from test/css-parser.spec.ts rename to tests/css-parser.spec.ts index 0e956783dd..b973d8831d 100644 --- a/test/css-parser.spec.ts +++ b/tests/css-parser.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/playwrightTest'; import { parseCSS, serializeSelector as serialize } from '../src/server/common/cssParser'; const parse = (selector: string) => { diff --git a/test/defaultbrowsercontext-1.spec.ts b/tests/defaultbrowsercontext-1.spec.ts similarity index 96% rename from test/defaultbrowsercontext-1.spec.ts rename to tests/defaultbrowsercontext-1.spec.ts index 4499f1d780..774162a384 100644 --- a/test/defaultbrowsercontext-1.spec.ts +++ b/tests/defaultbrowsercontext-1.spec.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; -import { verifyViewport } from './utils'; +import { test as it, expect } from './config/playwrightTest'; +import { verifyViewport } from '../test/utils'; import fs from 'fs'; it('context.cookies() should work', async ({server, launchPersistent}) => { @@ -170,9 +170,9 @@ it('should support offline option', async ({server, launchPersistent}) => { expect(error).toBeTruthy(); }); -it('should support acceptDownloads option', (test, parameters) => { - test.skip('Unskip once we support downloads in persistent context.'); -}, async ({server, launchPersistent}) => { +it('should support acceptDownloads option', async ({server, launchPersistent}) => { + it.skip('Unskip once we support downloads in persistent context.'); + const {page} = await launchPersistent({acceptDownloads: true}); server.setRoute('/download', (req, res) => { res.setHeader('Content-Type', 'application/octet-stream'); diff --git a/test/defaultbrowsercontext-2.spec.ts b/tests/defaultbrowsercontext-2.spec.ts similarity index 85% rename from test/defaultbrowsercontext-2.spec.ts rename to tests/defaultbrowsercontext-2.spec.ts index db4c2430d6..cb1ff4674f 100644 --- a/test/defaultbrowsercontext-2.spec.ts +++ b/tests/defaultbrowsercontext-2.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, slowTest, expect } from './config/playwrightTest'; import fs from 'fs'; it('should support hasTouch option', async ({server, launchPersistent}) => { @@ -24,10 +24,9 @@ it('should support hasTouch option', async ({server, launchPersistent}) => { expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(true); }); -it('should work in persistent context', (test, { browserName }) => { - test.skip(browserName === 'firefox'); -}, async ({server, launchPersistent}) => { - // Firefox does not support mobile. +it('should work in persistent context', async ({server, launchPersistent, browserName}) => { + it.skip(browserName === 'firefox', 'Firefox does not support mobile'); + const {page} = await launchPersistent({viewport: {width: 320, height: 480}, isMobile: true}); await page.goto(server.PREFIX + '/empty.html'); expect(await page.evaluate(() => window.innerWidth)).toBe(980); @@ -83,9 +82,7 @@ it('should accept userDataDir', async ({createUserDataDir, browserType, browserO expect(fs.readdirSync(userDataDir).length).toBeGreaterThan(0); }); -it('should restore state from userDataDir', (test, { browserName }) => { - test.slow(); -}, async ({browserType, browserOptions, server, createUserDataDir}) => { +slowTest('should restore state from userDataDir', async ({browserType, browserOptions, server, createUserDataDir}) => { const userDataDir = await createUserDataDir(); const browserContext = await browserType.launchPersistentContext(userDataDir, browserOptions); const page = await browserContext.newPage(); @@ -107,10 +104,9 @@ it('should restore state from userDataDir', (test, { browserName }) => { await browserContext3.close(); }); -it('should restore cookies from userDataDir', (test, { platform, browserChannel }) => { - test.slow(); - test.fixme(platform === 'win32' && browserChannel === 'chrome'); -}, async ({browserType, browserOptions, server, createUserDataDir}) => { +slowTest('should restore cookies from userDataDir', async ({browserType, browserOptions, server, createUserDataDir, platform, browserChannel}) => { + slowTest.fixme(platform === 'win32' && browserChannel === 'chrome'); + const userDataDir = await createUserDataDir(); const browserContext = await browserType.launchPersistentContext(userDataDir, browserOptions); const page = await browserContext.newPage(); @@ -142,17 +138,17 @@ it('should have default URL when launching browser', async ({launchPersistent}) expect(urls).toEqual(['about:blank']); }); -it('should throw if page argument is passed', (test, { browserName }) => { - test.skip(browserName === 'firefox'); -}, async ({browserType, browserOptions, server, createUserDataDir}) => { +it('should throw if page argument is passed', async ({browserType, browserOptions, server, createUserDataDir, browserName}) => { + it.skip(browserName === 'firefox'); + const options = {...browserOptions, args: [server.EMPTY_PAGE] }; const error = await browserType.launchPersistentContext(await createUserDataDir(), options).catch(e => e); expect(error.message).toContain('can not specify page'); }); -it('should have passed URL when launching with ignoreDefaultArgs: true', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions, server, createUserDataDir, toImpl}) => { +it('should have passed URL when launching with ignoreDefaultArgs: true', async ({browserType, browserOptions, server, createUserDataDir, toImpl, mode}) => { + it.skip(mode !== 'default'); + const userDataDir = await createUserDataDir(); const args = toImpl(browserType)._defaultArgs(browserOptions, 'persistent', userDataDir, 0).filter(a => a !== 'about:blank'); const options = { @@ -169,17 +165,17 @@ it('should have passed URL when launching with ignoreDefaultArgs: true', (test, await browserContext.close(); }); -it('should handle timeout', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions, createUserDataDir}) => { +it('should handle timeout', async ({browserType, browserOptions, createUserDataDir, mode}) => { + it.skip(mode !== 'default'); + const options = { ...browserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) }; const error = await browserType.launchPersistentContext(await createUserDataDir(), options).catch(e => e); expect(error.message).toContain(`browserType.launchPersistentContext: Timeout 5000ms exceeded.`); }); -it('should handle exception', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions, createUserDataDir}) => { +it('should handle exception', async ({browserType, browserOptions, createUserDataDir, mode}) => { + it.skip(mode !== 'default'); + const e = new Error('Dummy'); const options = { ...browserOptions, __testHookBeforeCreateBrowser: () => { throw e; } }; const error = await browserType.launchPersistentContext(await createUserDataDir(), options).catch(e => e); @@ -194,9 +190,9 @@ it('should fire close event for a persistent context', async ({launchPersistent} expect(closed).toBe(true); }); -it('coverage should work', (test, { browserName }) => { - test.skip(browserName !== 'chromium'); -}, async ({server, launchPersistent}) => { +it('coverage should work', async ({server, launchPersistent, browserName}) => { + it.skip(browserName !== 'chromium'); + const {page} = await launchPersistent(); await page.coverage.startJSCoverage(); await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' }); @@ -224,9 +220,9 @@ it('should respect selectors', async ({playwright, launchPersistent}) => { expect(await page.innerHTML('defaultContextCSS=div')).toBe('hello'); }); -it('should connect to a browser with the default page', (test, { mode }) => { - test.skip(mode !== 'default'); -}, async ({browserType, browserOptions, createUserDataDir}) => { +it('should connect to a browser with the default page', async ({browserType, browserOptions, createUserDataDir, mode}) => { + it.skip(mode !== 'default'); + const options = { ...browserOptions, __testHookOnConnectToBrowser: () => new Promise(f => setTimeout(f, 3000)) }; const context = await browserType.launchPersistentContext(await createUserDataDir(), options); expect(context.pages().length).toBe(1); diff --git a/test/downloads-path.spec.ts b/tests/downloads-path.spec.ts similarity index 91% rename from test/downloads-path.spec.ts rename to tests/downloads-path.spec.ts index 059cb7e055..27112b9db2 100644 --- a/test/downloads-path.spec.ts +++ b/tests/downloads-path.spec.ts @@ -14,12 +14,11 @@ * limitations under the License. */ -import { folio } from './fixtures'; +import { test as it, expect } from './config/playwrightTest'; import fs from 'fs'; -const { it, expect, describe, beforeEach } = folio; -describe('downloads path', () => { - beforeEach(async ({server}) => { +it.describe('downloads path', () => { + it.beforeEach(async ({server}) => { server.setRoute('/download', (req, res) => { res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Disposition', 'attachment; filename=file.txt'); @@ -27,7 +26,7 @@ describe('downloads path', () => { }); }); - it('should keep downloadsPath folder', async ({browserType, browserOptions, testInfo, server}) => { + it('should keep downloadsPath folder', async ({browserType, browserOptions, server}, testInfo) => { const downloadsBrowser = await browserType.launch({ ...browserOptions, downloadsPath: testInfo.outputPath('') }); const page = await downloadsBrowser.newPage(); await page.setContent(`download`); @@ -43,7 +42,7 @@ describe('downloads path', () => { expect(fs.existsSync(testInfo.outputPath(''))).toBeTruthy(); }); - it('should delete downloads when context closes', async ({browserType, browserOptions, server, testInfo}) => { + it('should delete downloads when context closes', async ({browserType, browserOptions, server}, testInfo) => { const downloadsBrowser = await browserType.launch({ ...browserOptions, downloadsPath: testInfo.outputPath('') }); const page = await downloadsBrowser.newPage({ acceptDownloads: true }); await page.setContent(`download`); @@ -58,7 +57,7 @@ describe('downloads path', () => { await downloadsBrowser.close(); }); - it('should report downloads in downloadsPath folder', async ({browserType, browserOptions, testInfo, server}) => { + it('should report downloads in downloadsPath folder', async ({browserType, browserOptions, server}, testInfo) => { const downloadsBrowser = await browserType.launch({ ...browserOptions, downloadsPath: testInfo.outputPath('') }); const page = await downloadsBrowser.newPage({ acceptDownloads: true }); await page.setContent(`download`); @@ -72,7 +71,7 @@ describe('downloads path', () => { await downloadsBrowser.close(); }); - it('should accept downloads in persistent context', async ({launchPersistent, testInfo, server}) => { + it('should accept downloads in persistent context', async ({launchPersistent, server}, testInfo) => { const { context, page } = await launchPersistent({ acceptDownloads: true, downloadsPath: testInfo.outputPath('') }); await page.setContent(`download`); const [ download ] = await Promise.all([ @@ -86,7 +85,7 @@ describe('downloads path', () => { await context.close(); }); - it('should delete downloads when persistent context closes', async ({launchPersistent, server, testInfo}) => { + it('should delete downloads when persistent context closes', async ({launchPersistent, server}, testInfo) => { const { context, page } = await launchPersistent({ acceptDownloads: true, downloadsPath: testInfo.outputPath('') }); await page.setContent(`download`); const [ download ] = await Promise.all([ diff --git a/tests/elementhandle-scroll-into-view.spec.ts b/tests/elementhandle-scroll-into-view.spec.ts index 5742b5c863..21d41e2aef 100644 --- a/tests/elementhandle-scroll-into-view.spec.ts +++ b/tests/elementhandle-scroll-into-view.spec.ts @@ -18,7 +18,7 @@ import { test as it, expect } from './config/pageTest'; it('should work', async ({ page, server }) => { - it.fixme(process.env.PW_ANDROID_TESTS); + it.fixme(!!process.env.PW_ANDROID_TESTS); await page.goto(server.PREFIX + '/offscreenbuttons.html'); for (let i = 0; i < 11; ++i) { diff --git a/tests/folio/src/expect.ts b/tests/folio/src/expect.ts index c79161f89d..09cffa98d9 100644 --- a/tests/folio/src/expect.ts +++ b/tests/folio/src/expect.ts @@ -51,3 +51,8 @@ function toMatchSnapshot(received: Buffer | string, nameOrOptions?: string | { n } expectLibrary.extend({ toMatchSnapshot }); + +// TEMPORARY HACK: two folios currently fight for their own toMatchSnapshot. +export function extendAgain() { + expectLibrary.extend({ toMatchSnapshot }); +} diff --git a/tests/folio/src/workerRunner.ts b/tests/folio/src/workerRunner.ts index 3c456e95e6..0825ada8a5 100644 --- a/tests/folio/src/workerRunner.ts +++ b/tests/folio/src/workerRunner.ts @@ -24,6 +24,7 @@ import { Loader } from './loader'; import { Spec, Suite, Test } from './test'; import { TestInfo, WorkerInfo } from './types'; import { RunListDescription } from './spec'; +import { extendAgain } from './expect'; export class WorkerRunner extends EventEmitter { private _params: WorkerInitParams; @@ -128,6 +129,7 @@ export class WorkerRunner extends EventEmitter { return; this._loader.loadTestFile(this._file); + extendAgain(); const fileSuite = this._runList.fileSuites.get(this._file); if (fileSuite) { fileSuite._renumber(); diff --git a/test/geolocation.spec.ts b/tests/geolocation.spec.ts similarity index 86% rename from test/geolocation.spec.ts rename to tests/geolocation.spec.ts index 13f6c92362..66fc7b3287 100644 --- a/test/geolocation.spec.ts +++ b/tests/geolocation.spec.ts @@ -15,9 +15,11 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; -it('should work', async ({page, server, context}) => { +it('should work', async ({server, contextFactory}) => { + const context = await contextFactory(); + const page = await context.newPage(); await context.grantPermissions(['geolocation']); await page.goto(server.EMPTY_PAGE); await context.setGeolocation({longitude: 10, latitude: 10}); @@ -30,7 +32,8 @@ it('should work', async ({page, server, context}) => { }); }); -it('should throw when invalid longitude', async ({context}) => { +it('should throw when invalid longitude', async ({contextFactory}) => { + const context = await contextFactory(); let error = null; try { await context.setGeolocation({longitude: 200, latitude: 10}); @@ -40,7 +43,9 @@ it('should throw when invalid longitude', async ({context}) => { expect(error.message).toContain('geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed.'); }); -it('should isolate contexts', async ({page, server, context, browser}) => { +it('should isolate contexts', async ({server, contextFactory, browser}) => { + const context = await contextFactory(); + const page = await context.newPage(); await context.grantPermissions(['geolocation']); await context.setGeolocation({longitude: 10, latitude: 10}); await page.goto(server.EMPTY_PAGE); @@ -71,7 +76,8 @@ it('should isolate contexts', async ({page, server, context, browser}) => { await context2.close(); }); -it('should throw with missing latitude', async ({context}) => { +it('should throw with missing latitude', async ({contextFactory}) => { + const context = await contextFactory(); let error = null; try { // @ts-expect-error setGeolocation must have latitude @@ -119,7 +125,9 @@ it('should use context options', async ({browser, server}) => { await context.close(); }); -it('watchPosition should be notified', async ({page, server, context}) => { +it('watchPosition should be notified', async ({server, contextFactory}) => { + const context = await contextFactory(); + const page = await context.newPage(); await context.grantPermissions(['geolocation']); await page.goto(server.EMPTY_PAGE); const messages = []; @@ -145,7 +153,9 @@ it('watchPosition should be notified', async ({page, server, context}) => { expect(allMessages).toContain('lat=40 lng=50'); }); -it('should use context options for popup', async ({page, context, server}) => { +it('should use context options for popup', async ({contextFactory, server}) => { + const context = await contextFactory(); + const page = await context.newPage(); await context.grantPermissions(['geolocation']); await context.setGeolocation({ longitude: 10, latitude: 10 }); const [popup] = await Promise.all([ diff --git a/test/har.spec.ts b/tests/har.spec.ts similarity index 87% rename from test/har.spec.ts rename to tests/har.spec.ts index f0f07e3f75..50aab6b437 100644 --- a/test/har.spec.ts +++ b/tests/har.spec.ts @@ -15,13 +15,11 @@ * limitations under the License. */ -import { folio } from './fixtures'; +import { test as it, expect } from './config/browserTest'; import fs from 'fs'; import type { BrowserContext, BrowserContextOptions } from '../index'; -import { TestInfo } from 'folio'; -const { expect, it } = folio; -async function pageWithHar(contextFactory: (options?: BrowserContextOptions) => Promise, testInfo: TestInfo) { +async function pageWithHar(contextFactory: (options?: BrowserContextOptions) => Promise, testInfo: any) { const harPath = testInfo.outputPath('test.har'); const context = await contextFactory({ recordHar: { path: harPath }, ignoreHTTPSErrors: true }); const page = await context.newPage(); @@ -39,7 +37,7 @@ it('should throw without path', async ({ browser }) => { expect(error.message).toContain('recordHar.path: expected string, got undefined'); }); -it('should have version and creator', async ({ contextFactory, testInfo, server }) => { +it('should have version and creator', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); const log = await getLog(); @@ -48,7 +46,7 @@ it('should have version and creator', async ({ contextFactory, testInfo, server expect(log.creator.version).toBe(require('../package.json')['version']); }); -it('should have browser', async ({ browserName, browser, contextFactory, testInfo, server }) => { +it('should have browser', async ({ browserName, browser, contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); const log = await getLog(); @@ -56,7 +54,7 @@ it('should have browser', async ({ browserName, browser, contextFactory, testInf expect(log.browser.version).toBe(browser.version()); }); -it('should have pages', async ({ contextFactory, testInfo, server }) => { +it('should have pages', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto('data:text/html,Hello'); // For data: load comes before domcontentloaded... @@ -71,7 +69,7 @@ it('should have pages', async ({ contextFactory, testInfo, server }) => { expect(pageEntry.pageTimings.onLoad).toBeGreaterThan(0); }); -it('should have pages in persistent context', async ({ launchPersistent, testInfo }) => { +it('should have pages in persistent context', async ({ launchPersistent }, testInfo) => { const harPath = testInfo.outputPath('test.har'); const { context, page } = await launchPersistent({ recordHar: { path: harPath } }); await page.goto('data:text/html,Hello'); @@ -85,7 +83,7 @@ it('should have pages in persistent context', async ({ launchPersistent, testInf expect(pageEntry.title).toBe('Hello'); }); -it('should include request', async ({ contextFactory, testInfo, server }) => { +it('should include request', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); const log = await getLog(); @@ -99,7 +97,7 @@ it('should include request', async ({ contextFactory, testInfo, server }) => { expect(entry.request.headers.find(h => h.name.toLowerCase() === 'user-agent')).toBeTruthy(); }); -it('should include response', async ({ contextFactory, testInfo, server }) => { +it('should include response', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); const log = await getLog(); @@ -111,7 +109,7 @@ it('should include response', async ({ contextFactory, testInfo, server }) => { expect(entry.response.headers.find(h => h.name.toLowerCase() === 'content-type').value).toContain('text/html'); }); -it('should include redirectURL', async ({ contextFactory, testInfo, server }) => { +it('should include redirectURL', async ({ contextFactory, server }, testInfo) => { server.setRedirect('/foo.html', '/empty.html'); const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.PREFIX + '/foo.html'); @@ -122,14 +120,14 @@ it('should include redirectURL', async ({ contextFactory, testInfo, server }) => expect(entry.response.redirectURL).toBe(server.EMPTY_PAGE); }); -it('should include query params', async ({ contextFactory, testInfo, server }) => { +it('should include query params', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.PREFIX + '/har.html?name=value'); const log = await getLog(); expect(log.entries[0].request.queryString).toEqual([{ name: 'name', value: 'value' }]); }); -it('should include postData', async ({ contextFactory, testInfo, server }) => { +it('should include postData', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); await page.evaluate(() => fetch('./post', { method: 'POST', body: 'Hello' })); @@ -141,7 +139,7 @@ it('should include postData', async ({ contextFactory, testInfo, server }) => { }); }); -it('should include binary postData', async ({ contextFactory, testInfo, server }) => { +it('should include binary postData', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); await page.evaluate(async () => { @@ -155,7 +153,7 @@ it('should include binary postData', async ({ contextFactory, testInfo, server } }); }); -it('should include form params', async ({ contextFactory, testInfo, server }) => { +it('should include form params', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); await page.setContent(`
`); @@ -171,7 +169,7 @@ it('should include form params', async ({ contextFactory, testInfo, server }) => }); }); -it('should include cookies', async ({ contextFactory, testInfo, server }) => { +it('should include cookies', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); const context = page.context(); await context.addCookies([ @@ -190,9 +188,9 @@ it('should include cookies', async ({ contextFactory, testInfo, server }) => { ]); }); -it('should include set-cookies', (test, { browserName, platform }) => { - test.fail(browserName === 'webkit' && platform === 'darwin', 'Does not work yet'); -}, async ({ contextFactory, testInfo, server }) => { +it('should include set-cookies', async ({ contextFactory, server, browserName, platform }, testInfo) => { + it.fail(browserName === 'webkit' && platform === 'darwin', 'Does not work yet'); + const { page, getLog } = await pageWithHar(contextFactory, testInfo); server.setRoute('/empty.html', (req, res) => { res.setHeader('Set-Cookie', [ @@ -210,7 +208,7 @@ it('should include set-cookies', (test, { browserName, platform }) => { expect(new Date(cookies[2].expires).valueOf()).toBeGreaterThan(Date.now()); }); -it('should include set-cookies with comma', async ({ contextFactory, testInfo, server }) => { +it('should include set-cookies with comma', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); server.setRoute('/empty.html', (req, res) => { res.setHeader('Set-Cookie', [ @@ -224,7 +222,7 @@ it('should include set-cookies with comma', async ({ contextFactory, testInfo, s expect(cookies[0]).toEqual({ name: 'name1', value: 'val,ue1' }); }); -it('should include secure set-cookies', async ({ contextFactory, testInfo, httpsServer }) => { +it('should include secure set-cookies', async ({ contextFactory, httpsServer }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); httpsServer.setRoute('/empty.html', (req, res) => { res.setHeader('Set-Cookie', [ @@ -238,7 +236,7 @@ it('should include secure set-cookies', async ({ contextFactory, testInfo, https expect(cookies[0]).toEqual({ name: 'name1', value: 'value1', secure: true }); }); -it('should include content', async ({ contextFactory, testInfo, server }) => { +it('should include content', async ({ contextFactory, server }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.PREFIX + '/har.html'); const log = await getLog(); diff --git a/test/headful.spec.ts b/tests/headful.spec.ts similarity index 85% rename from test/headful.spec.ts rename to tests/headful.spec.ts index 7157daecd2..799e141443 100644 --- a/test/headful.spec.ts +++ b/tests/headful.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { it, expect, folio } from './fixtures'; +import { test as it, slowTest, expect } from './config/playwrightTest'; it('should have default url when launching browser', async ({browserType, browserOptions, createUserDataDir}) => { const browserContext = await browserType.launchPersistentContext(await createUserDataDir(), {...browserOptions, headless: false }); @@ -23,9 +23,7 @@ it('should have default url when launching browser', async ({browserType, browse await browserContext.close(); }); -it('headless should be able to read cookies written by headful', (test, { browserName, platform }) => { - test.slow(); -}, async ({browserType, browserOptions, server, createUserDataDir}) => { +slowTest('headless should be able to read cookies written by headful', async ({browserType, browserOptions, server, createUserDataDir}) => { // see https://github.com/microsoft/playwright/issues/717 const userDataDir = await createUserDataDir(); // Write a cookie in headful chrome @@ -43,9 +41,7 @@ it('headless should be able to read cookies written by headful', (test, { browse expect(cookie).toBe('foo=true'); }); -it('should close browser with beforeunload page', (test, parameters) => { - test.slow(); -}, async ({browserType, browserOptions, server, createUserDataDir}) => { +slowTest('should close browser with beforeunload page', async ({browserType, browserOptions, server, createUserDataDir}) => { const browserContext = await browserType.launchPersistentContext(await createUserDataDir(), {...browserOptions, headless: false}); const page = await browserContext.newPage(); await page.goto(server.PREFIX + '/beforeunload.html'); @@ -127,9 +123,9 @@ it('should(not) block third party cookies', async ({browserType, browserOptions, await browser.close(); }); -it('should not override viewport size when passed null', (test, { browserName }) => { - test.fixme(browserName === 'webkit'); -}, async function({browserType, browserOptions, server}) { +it('should not override viewport size when passed null', async function({browserType, browserOptions, server, browserName}) { + it.fixme(browserName === 'webkit'); + // Our WebKit embedder does not respect window features. const browser = await browserType.launch({...browserOptions, headless: false }); const context = await browser.newContext({ viewport: null }); @@ -167,16 +163,15 @@ it('Page.bringToFront should work', async ({browserType, browserOptions}) => { await browser.close(); }); -const fixtures = folio.extend(); -fixtures.testParametersPathSegment.override(async ({ browserName, platform }, run) => { - await run(browserName + '-' + platform); -}); -fixtures.build().it('focused input should produce the same screenshot', (test, { browserName, platform }) => { - test.fail(browserName === 'firefox' && platform === 'darwin', 'headless has thinner outline'); - test.fail(browserName === 'firefox' && platform === 'linux', 'headless has no outline'); - test.skip(browserName === 'webkit' && platform === 'linux', 'gtk vs wpe'); - test.skip(process.env.CRPATH); -}, async ({browserType, browserOptions}) => { +it('focused input should produce the same screenshot', async ({browserType, browserOptions, browserName, platform, browserChannel}, testInfo) => { + it.fail(browserName === 'firefox' && platform === 'darwin', 'headless has thinner outline'); + it.fail(browserName === 'firefox' && platform === 'linux', 'headless has no outline'); + it.skip(browserName === 'webkit' && platform === 'linux', 'gtk vs wpe'); + it.skip(!!process.env.CRPATH); + it.skip(!!browserChannel, 'Uncomment on roll'); + + testInfo.snapshotPathSegment = browserName + '-' + platform; + const headful = await browserType.launch({...browserOptions, headless: false }); const headfulPage = await headful.newPage(); await headfulPage.setContent(''); diff --git a/test/ignorehttpserrors.spec.ts b/tests/ignorehttpserrors.spec.ts similarity index 98% rename from test/ignorehttpserrors.spec.ts rename to tests/ignorehttpserrors.spec.ts index f4c083f59f..94e148d68d 100644 --- a/test/ignorehttpserrors.spec.ts +++ b/tests/ignorehttpserrors.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/browserTest'; it('should work', async ({browser, httpsServer}) => { let error = null; diff --git a/test/launcher.spec.ts b/tests/launcher.spec.ts similarity index 86% rename from test/launcher.spec.ts rename to tests/launcher.spec.ts index 912d42fd93..8bba10a14e 100644 --- a/test/launcher.spec.ts +++ b/tests/launcher.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/playwrightTest'; it('should require top-level Errors', async ({}) => { const Errors = require('../lib/utils/errors.js'); @@ -28,9 +28,9 @@ it('should require top-level DeviceDescriptors', async ({playwright}) => { expect(Devices['iPhone 6']).toEqual(playwright.devices['iPhone 6']); }); -it('should kill browser process on timeout after close', (test, { mode }) => { - test.skip(mode !== 'default', 'Test passes server hooks via options'); -}, async ({browserType, browserOptions}) => { +it('should kill browser process on timeout after close', async ({browserType, browserOptions, mode}) => { + it.skip(mode !== 'default', 'Test passes server hooks via options'); + const launchOptions = { ...browserOptions }; let stalled = false; (launchOptions as any).__testHookGracefullyClose = () => { diff --git a/test/logger.spec.ts b/tests/logger.spec.ts similarity index 97% rename from test/logger.spec.ts rename to tests/logger.spec.ts index b0f7223a30..919b5c780c 100644 --- a/test/logger.spec.ts +++ b/tests/logger.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { it, expect } from './fixtures'; +import { test as it, expect } from './config/playwrightTest'; it('should log', async ({browserType, browserOptions}) => { const log = []; diff --git a/tests/page-add-script-tag.spec.ts b/tests/page-add-script-tag.spec.ts index 184c4d9a14..ccc23e0a4c 100644 --- a/tests/page-add-script-tag.spec.ts +++ b/tests/page-add-script-tag.spec.ts @@ -99,7 +99,7 @@ it('should throw when added with content to the CSP page', async ({page, server} }); it('should throw when added with URL to the CSP page', async ({page, server}) => { - it.skip(process.env.PW_ANDROID_TESTS); + it.skip(!!process.env.PW_ANDROID_TESTS); await page.goto(server.PREFIX + '/csp.html'); let error = null; diff --git a/tests/page-add-style-tag.spec.ts b/tests/page-add-style-tag.spec.ts index 2bb22423f1..6e53a8431c 100644 --- a/tests/page-add-style-tag.spec.ts +++ b/tests/page-add-style-tag.spec.ts @@ -77,7 +77,7 @@ it('should throw when added with content to the CSP page', async ({page, server} }); it('should throw when added with URL to the CSP page', async ({page, server}) => { - it.skip(process.env.PW_ANDROID_TESTS); + it.skip(!!process.env.PW_ANDROID_TESTS); await page.goto(server.PREFIX + '/csp.html'); let error = null; diff --git a/tests/page-click-scroll.spec.ts b/tests/page-click-scroll.spec.ts index 1e9c781fc2..6972987086 100644 --- a/tests/page-click-scroll.spec.ts +++ b/tests/page-click-scroll.spec.ts @@ -18,7 +18,7 @@ import { test as it } from './config/pageTest'; it('should not hit scroll bar', async ({page, server, isWebKit, platform}) => { it.fixme(isWebKit && platform === 'darwin'); - it.skip(process.env.PW_ANDROID_TESTS); + it.skip(!!process.env.PW_ANDROID_TESTS); await page.setContent(`