From cef27d620b93cc68e25c54607f139daec49cc4f2 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 25 Sep 2020 23:30:46 -0700 Subject: [PATCH] chore: split playwright.fixtures into files (3) (#3984) --- package-lock.json | 12 +- package.json | 2 +- test/browsercontext-basic.spec.ts | 3 +- test/browsercontext-csp.spec.ts | 3 +- test/browsercontext-user-agent.spec.ts | 3 +- test/browsercontext-viewport.spec.ts | 3 +- test/channels.spec.ts | 11 +- test/chromium/oopif.spec.ts | 2 +- test/chromium/tracing.spec.ts | 3 +- test/click.spec.ts | 3 +- test/defaultbrowsercontext-1.spec.ts | 3 +- test/downloads-path.spec.ts | 4 +- test/electron/electron.fixture.ts | 4 +- test/elementhandle-content-frame.spec.ts | 3 +- test/elementhandle-owner-frame.spec.ts | 3 +- test/elementhandle-screenshot.spec.ts | 3 +- test/emulation-focus.spec.ts | 3 +- test/frame-evaluate.spec.ts | 3 +- test/frame-frame-element.spec.ts | 3 +- test/frame-goto.spec.ts | 3 +- test/frame-hierarchy.spec.ts | 3 +- test/http.fixtures.ts | 2 - test/impl.fixtures.ts | 29 ++++ test/keyboard.spec.ts | 3 +- test/network-request.spec.ts | 3 +- test/page-emulate-media.spec.ts | 3 +- test/page-event-request.spec.ts | 3 +- test/page-goto.spec.ts | 12 +- test/page-screenshot.spec.ts | 3 +- test/page-wait-for-navigation.spec.ts | 5 +- test/playwright.fixtures.ts | 181 +++-------------------- test/remoteServer.fixture.ts | 4 +- test/screencast.spec.ts | 2 +- test/slowmo.spec.ts | 3 +- test/upstream.fixtures.ts | 153 +++++++++++++++++++ test/utils.ts | 60 ++++++++ test/wait-for-selector-1.spec.ts | 3 +- test/wait-for-selector-2.spec.ts | 3 +- 38 files changed, 341 insertions(+), 211 deletions(-) create mode 100644 test/impl.fixtures.ts create mode 100644 test/upstream.fixtures.ts create mode 100644 test/utils.ts diff --git a/package-lock.json b/package-lock.json index 4c5b73f9d8..e3f4b75098 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1200,9 +1200,9 @@ } }, "@playwright/test-runner": { - "version": "0.9.14", - "resolved": "https://registry.npmjs.org/@playwright/test-runner/-/test-runner-0.9.14.tgz", - "integrity": "sha512-pzNxoJbc51JHUyb9WnoIa9bS2NwL81G7ZbeFoj+TwwhzEghQ2c/2iAmzqEDpzgFDdXKlNPtIVRZLuevWRkv/bg==", + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/@playwright/test-runner/-/test-runner-0.9.15.tgz", + "integrity": "sha512-1ilbB+ZDDmr4GnT/7omtGUTthcdAOLvMSOqqUd11OhNOo0IgYn3T6Iu8lwO+gdWYyALwyzk5OKIHldRV33ULXw==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", @@ -2993,9 +2993,9 @@ } }, "electron-to-chromium": { - "version": "1.3.572", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.572.tgz", - "integrity": "sha512-TKqdEukCCl7JC20SwEoWTbtnGt4YjfHWAv4tcNky0a9qGo0WdM+Lrd60tps+nkaJCmktKBJjr99fLtEBU1ipWQ==", + "version": "1.3.573", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.573.tgz", + "integrity": "sha512-oypaNmexr8w0m2GX67fGLQ0Xgsd7uXz7GcwaHZ9eW3ZdQ8uA2+V/wXmLdMTk3gcacbqQGAN7CXWG3fOkfKYftw==", "dev": true }, "elliptic": { diff --git a/package.json b/package.json index 63ab95fa67..a65751805a 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ }, "devDependencies": { "@playwright/test": "^0.9.6", - "@playwright/test-runner": "^0.9.14", + "@playwright/test-runner": "^0.9.15", "@types/debug": "^4.1.5", "@types/extract-zip": "^1.6.2", "@types/mime": "^2.0.3", diff --git a/test/browsercontext-basic.spec.ts b/test/browsercontext-basic.spec.ts index 3efd814a77..26841ca222 100644 --- a/test/browsercontext-basic.spec.ts +++ b/test/browsercontext-basic.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, verifyViewport } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { verifyViewport } from './utils'; it('should create new context', async function({browser}) { expect(browser.contexts().length).toBe(0); diff --git a/test/browsercontext-csp.spec.ts b/test/browsercontext-csp.spec.ts index 8e1efbac3f..bdb3c87be1 100644 --- a/test/browsercontext-csp.spec.ts +++ b/test/browsercontext-csp.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should bypass CSP meta tag', async ({browser, server}) => { // Make sure CSP prohibits addScriptTag. diff --git a/test/browsercontext-user-agent.spec.ts b/test/browsercontext-user-agent.spec.ts index 83cffcc930..ab434e690a 100644 --- a/test/browsercontext-user-agent.spec.ts +++ b/test/browsercontext-user-agent.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should work', async ({browser, server}) => { { diff --git a/test/browsercontext-viewport.spec.ts b/test/browsercontext-viewport.spec.ts index 6e6231d7a7..aea0fed499 100644 --- a/test/browsercontext-viewport.spec.ts +++ b/test/browsercontext-viewport.spec.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { it, expect, verifyViewport } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { verifyViewport } from './utils'; it('should get the proper default viewport size', async ({page, server}) => { await verifyViewport(page, 1280, 720); diff --git a/test/channels.spec.ts b/test/channels.spec.ts index 73a815ffb8..7214bccc2b 100644 --- a/test/channels.spec.ts +++ b/test/channels.spec.ts @@ -16,10 +16,15 @@ */ import domain from 'domain'; -import { it, expect, options, playwrightFixtures } from './playwright.fixtures'; +import { options, fixtures as baseFixtures } from './playwright.fixtures'; import type { ChromiumBrowser } from '..'; -playwrightFixtures.defineWorkerFixture('domain', async ({ }, test) => { +type DomainFixtures = { + domain: any; +}; + +const fixtures = baseFixtures.declareWorkerFixtures(); +fixtures.defineWorkerFixture('domain', async ({ }, test) => { const local = domain.create(); local.run(() => { }); let err; @@ -29,6 +34,8 @@ playwrightFixtures.defineWorkerFixture('domain', async ({ }, test) => { throw err; }); +const { it, expect } = fixtures; + it('should work', async ({browser}) => { expect(!!browser['_connection']).toBeTruthy(); }); diff --git a/test/chromium/oopif.spec.ts b/test/chromium/oopif.spec.ts index d7ab4613ee..eaddee41e5 100644 --- a/test/chromium/oopif.spec.ts +++ b/test/chromium/oopif.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { options, playwrightFixtures } from '../playwright.fixtures'; +import { options, fixtures as playwrightFixtures } from '../playwright.fixtures'; const { it, expect, describe, overrideWorkerFixture } = playwrightFixtures; overrideWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => { diff --git a/test/chromium/tracing.spec.ts b/test/chromium/tracing.spec.ts index 39e3224485..fbde6bcf6c 100644 --- a/test/chromium/tracing.spec.ts +++ b/test/chromium/tracing.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { options, playwrightFixtures } from '../playwright.fixtures'; +import { options, fixtures as playwrightFixtures } from '../playwright.fixtures'; import fs from 'fs'; import path from 'path'; import type { ChromiumBrowser } from '../..'; @@ -25,7 +25,6 @@ type TestState = { const fixtures = playwrightFixtures.declareTestFixtures(); const { it, expect, describe, defineTestFixture } = fixtures; - defineTestFixture('outputTraceFile', async ({testOutputDir}, test) => { await test(path.join(testOutputDir, `trace.json`)); }); diff --git a/test/click.spec.ts b/test/click.spec.ts index 2bb80d33ec..57de0ea4be 100644 --- a/test/click.spec.ts +++ b/test/click.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame } from './utils'; async function giveItAChanceToClick(page) { for (let i = 0; i < 5; i++) diff --git a/test/defaultbrowsercontext-1.spec.ts b/test/defaultbrowsercontext-1.spec.ts index 18538d9d5c..5fc72f56f9 100644 --- a/test/defaultbrowsercontext-1.spec.ts +++ b/test/defaultbrowsercontext-1.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, verifyViewport } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { verifyViewport } from './utils'; import fs from 'fs'; it('context.cookies() should work', async ({server, launchPersistent}) => { diff --git a/test/downloads-path.spec.ts b/test/downloads-path.spec.ts index 1198c365ec..8be7b8a816 100644 --- a/test/downloads-path.spec.ts +++ b/test/downloads-path.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { playwrightFixtures } from './playwright.fixtures'; +import { fixtures as baseFixtures } from './playwright.fixtures'; import fs from 'fs'; import type { Browser, BrowserContext } from '..'; @@ -23,7 +23,7 @@ type TestState = { downloadsBrowser: Browser; persistentDownloadsContext: BrowserContext; }; -const fixtures = playwrightFixtures.declareTestFixtures(); +const fixtures = baseFixtures.declareTestFixtures(); const { it, expect, defineTestFixture } = fixtures; defineTestFixture('downloadsBrowser', async ({server, browserType, defaultBrowserOptions, testOutputDir}, test) => { diff --git a/test/electron/electron.fixture.ts b/test/electron/electron.fixture.ts index e9320623e5..007ce394df 100644 --- a/test/electron/electron.fixture.ts +++ b/test/electron/electron.fixture.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { playwrightFixtures } from '../playwright.fixtures'; +import { fixtures as baseFixtures } from '../playwright.fixtures'; import type {ElectronApplication, ElectronLauncher, ElectronPage} from '../../electron-types'; import path from 'path'; @@ -25,7 +25,7 @@ type TestState = { window: ElectronPage; }; -export const electronFixtures = playwrightFixtures.declareTestFixtures(); +export const electronFixtures = baseFixtures.declareTestFixtures(); const { defineTestFixture } = electronFixtures; declare module '../../index' { diff --git a/test/elementhandle-content-frame.spec.ts b/test/elementhandle-content-frame.spec.ts index c09c952836..8b6175be83 100644 --- a/test/elementhandle-content-frame.spec.ts +++ b/test/elementhandle-content-frame.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should work', async ({ page, server }) => { await page.goto(server.EMPTY_PAGE); diff --git a/test/elementhandle-owner-frame.spec.ts b/test/elementhandle-owner-frame.spec.ts index 31a7241f55..958fbe771c 100644 --- a/test/elementhandle-owner-frame.spec.ts +++ b/test/elementhandle-owner-frame.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should work', async ({ page, server }) => { await page.goto(server.EMPTY_PAGE); diff --git a/test/elementhandle-screenshot.spec.ts b/test/elementhandle-screenshot.spec.ts index e516356ebc..6bf74100d2 100644 --- a/test/elementhandle-screenshot.spec.ts +++ b/test/elementhandle-screenshot.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, describe, options, verifyViewport } from './playwright.fixtures'; +import { it, expect, describe, options } from './playwright.fixtures'; +import { verifyViewport } from './utils'; import {PNG} from 'pngjs'; import path from 'path'; diff --git a/test/emulation-focus.spec.ts b/test/emulation-focus.spec.ts index b3319e38d4..f59c7331aa 100644 --- a/test/emulation-focus.spec.ts +++ b/test/emulation-focus.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should think that it is focused by default', async ({page}) => { expect(await page.evaluate('document.hasFocus()')).toBe(true); diff --git a/test/frame-evaluate.spec.ts b/test/frame-evaluate.spec.ts index a0d68130cc..6c2a40ae6f 100644 --- a/test/frame-evaluate.spec.ts +++ b/test/frame-evaluate.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame, detachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame, detachFrame } from './utils'; import type { Frame } from '../src/client/frame'; diff --git a/test/frame-frame-element.spec.ts b/test/frame-frame-element.spec.ts index 335451cc3d..cd8f5dd64d 100644 --- a/test/frame-frame-element.spec.ts +++ b/test/frame-frame-element.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should work', async ({page, server}) => { await page.goto(server.EMPTY_PAGE); diff --git a/test/frame-goto.spec.ts b/test/frame-goto.spec.ts index 530a3558ef..8b91b3338b 100644 --- a/test/frame-goto.spec.ts +++ b/test/frame-goto.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should navigate subframes', async ({page, server}) => { await page.goto(server.PREFIX + '/frames/one-frame.html'); diff --git a/test/frame-hierarchy.spec.ts b/test/frame-hierarchy.spec.ts index cc0ccbf442..06c7dc3300 100644 --- a/test/frame-hierarchy.spec.ts +++ b/test/frame-hierarchy.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame, detachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame, detachFrame } from './utils'; import type { Frame } from '../index'; function dumpFrames(frame: Frame, indentation: string = ''): string[] { diff --git a/test/http.fixtures.ts b/test/http.fixtures.ts index c60f6ff096..988161453b 100644 --- a/test/http.fixtures.ts +++ b/test/http.fixtures.ts @@ -17,8 +17,6 @@ import { fixtures as baseFixtures } from '@playwright/test-runner'; import path from 'path'; import { TestServer } from '../utils/testserver'; -export { expect } from '@playwright/test'; -export { config } from '@playwright/test-runner'; type HttpWorkerFixtures = { asset: (path: string) => string; diff --git a/test/impl.fixtures.ts b/test/impl.fixtures.ts new file mode 100644 index 0000000000..d413cdc304 --- /dev/null +++ b/test/impl.fixtures.ts @@ -0,0 +1,29 @@ +/** + * Copyright Microsoft Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { fixtures as playwrightFixtures } from './upstream.fixtures'; + +type ImplWorkerFixtures = { + toImpl: (rpcObject: any) => any; +}; + +export const fixtures = playwrightFixtures + .declareWorkerFixtures(); +const { defineWorkerFixture } = fixtures; + +defineWorkerFixture('toImpl', async ({ playwright }, test) => { + await test((playwright as any)._toImpl); +}); diff --git a/test/keyboard.spec.ts b/test/keyboard.spec.ts index 9932c61e50..5abce1a867 100644 --- a/test/keyboard.spec.ts +++ b/test/keyboard.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should type into a textarea', async ({page}) => { await page.evaluate(() => { diff --git a/test/network-request.spec.ts b/test/network-request.spec.ts index 02147bfad0..4f4b229311 100644 --- a/test/network-request.spec.ts +++ b/test/network-request.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, options, attachFrame } from './playwright.fixtures'; +import { it, expect, options } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should work for main frame navigation request', async ({page, server}) => { const requests = []; diff --git a/test/page-emulate-media.spec.ts b/test/page-emulate-media.spec.ts index 96599b8870..2f6d0b05f1 100644 --- a/test/page-emulate-media.spec.ts +++ b/test/page-emulate-media.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should emulate type', async ({page, server}) => { expect(await page.evaluate(() => matchMedia('screen').matches)).toBe(true); diff --git a/test/page-event-request.spec.ts b/test/page-event-request.spec.ts index 06e728c88d..6948d5d182 100644 --- a/test/page-event-request.spec.ts +++ b/test/page-event-request.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame } from './utils'; it('should fire for navigation requests', async ({page, server}) => { const requests = []; diff --git a/test/page-goto.spec.ts b/test/page-goto.spec.ts index 587cc4627e..78253f743e 100644 --- a/test/page-goto.spec.ts +++ b/test/page-goto.spec.ts @@ -15,10 +15,10 @@ * limitations under the License. */ -import { it, expect, options } from './playwright.fixtures'; - import path from 'path'; import url from 'url'; +import { expect, it, options } from './playwright.fixtures'; +import { expectedSSLError } from './utils'; it('should work', async ({page, server}) => { await page.goto(server.EMPTY_PAGE); @@ -173,7 +173,7 @@ it('should fail when navigating to bad url', async ({page, isChromium, isWebKit} expect(error.message).toContain('Invalid url'); }); -it('should fail when navigating to bad SSL', async ({page, httpsServer, expectedSSLError}) => { +it('should fail when navigating to bad SSL', async ({page, browserName, httpsServer}) => { // Make sure that network events do not emit 'undefined'. // @see https://crbug.com/750469 page.on('request', request => expect(request).toBeTruthy()); @@ -181,15 +181,15 @@ it('should fail when navigating to bad SSL', async ({page, httpsServer, expected page.on('requestfailed', request => expect(request).toBeTruthy()); let error = null; await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e); - expect(error.message).toContain(expectedSSLError); + expect(error.message).toContain(expectedSSLError(browserName)); }); -it('should fail when navigating to bad SSL after redirects', async ({page, server, httpsServer, expectedSSLError}) => { +it('should fail when navigating to bad SSL after redirects', async ({page, browserName, server, httpsServer}) => { server.setRedirect('/redirect/1.html', '/redirect/2.html'); server.setRedirect('/redirect/2.html', '/empty.html'); let error = null; await page.goto(httpsServer.PREFIX + '/redirect/1.html').catch(e => error = e); - expect(error.message).toContain(expectedSSLError); + expect(error.message).toContain(expectedSSLError(browserName)); }); it('should not crash when navigating to bad SSL after a cross origin navigation', async ({page, server, httpsServer}) => { diff --git a/test/page-screenshot.spec.ts b/test/page-screenshot.spec.ts index 8f38f7e166..29d33d8dd1 100644 --- a/test/page-screenshot.spec.ts +++ b/test/page-screenshot.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, describe, options, verifyViewport } from './playwright.fixtures'; +import { it, expect, describe, options } from './playwright.fixtures'; +import { verifyViewport } from './utils'; import path from 'path'; import fs from 'fs'; diff --git a/test/page-wait-for-navigation.spec.ts b/test/page-wait-for-navigation.spec.ts index a7abd2c717..dd9e89f47e 100644 --- a/test/page-wait-for-navigation.spec.ts +++ b/test/page-wait-for-navigation.spec.ts @@ -17,6 +17,7 @@ import { it, expect } from './playwright.fixtures'; import type { Frame } from '../index'; +import { expectedSSLError } from './utils'; it('should work', async ({page, server}) => { await page.goto(server.EMPTY_PAGE); @@ -70,14 +71,14 @@ it('should work with clicking on anchor links', async ({page, server}) => { expect(page.url()).toBe(server.EMPTY_PAGE + '#foobar'); }); -it('should work with clicking on links which do not commit navigation', async ({page, server, httpsServer, expectedSSLError}) => { +it('should work with clicking on links which do not commit navigation', async ({page, server, httpsServer, browserName}) => { await page.goto(server.EMPTY_PAGE); await page.setContent(`foobar`); const [error] = await Promise.all([ page.waitForNavigation().catch(e => e), page.click('a'), ]); - expect(error.message).toContain(expectedSSLError); + expect(error.message).toContain(expectedSSLError(browserName)); }); it('should work with history.pushState()', async ({page, server}) => { diff --git a/test/playwright.fixtures.ts b/test/playwright.fixtures.ts index 51f02cca3b..fca655d455 100644 --- a/test/playwright.fixtures.ts +++ b/test/playwright.fixtures.ts @@ -14,61 +14,47 @@ * limitations under the License. */ -import { expect } from '@playwright/test'; import { config } from '@playwright/test-runner'; -import { fixtures as httpFixtures } from './http.fixtures'; -import { fixtures as platformFixtures, options as platformOptions } from './platform.fixtures'; import assert from 'assert'; import childProcess from 'child_process'; import fs from 'fs'; -import os from 'os'; import path from 'path'; import util from 'util'; -import type { Browser, BrowserContext, BrowserContextOptions, BrowserServer, BrowserType, Frame, LaunchOptions, Page } from '../index'; +import type { Browser, BrowserContext, BrowserType, Page } from '../index'; import { Connection } from '../lib/client/connection'; import { Transport } from '../lib/protocol/transport'; import { installCoverageHooks } from './coverage'; -export { expect } from '@playwright/test'; +import { fixtures as httpFixtures } from './http.fixtures'; +import { fixtures as implFixtures } from './impl.fixtures'; +import { fixtures as platformFixtures, options as platformOptions } from './platform.fixtures'; +import { fixtures as playwrightFixtures, options as playwrightOptions, PlaywrightParameters } from './upstream.fixtures'; +export { expect } from '@playwright/test/out/matcher.fixtures'; export { config } from '@playwright/test-runner'; -const mkdtempAsync = util.promisify(fs.mkdtemp); const removeFolderAsync = util.promisify(require('rimraf')); -type PlaywrightParameters = { +type AllParameters = { browserName: string; }; -type PlaywrightWorkerFixtures = { - defaultBrowserOptions: LaunchOptions; +type AllWorkerFixtures = { golden: (path: string) => string; - playwright: typeof import('../index'); - browserType: BrowserType; - browser: Browser; - domain: void; - toImpl: (rpcObject: any) => any; - isChromium: boolean; - isFirefox: boolean; - isWebKit: boolean; - expectedSSLError: string; }; -type PlaywrightTestFixtures = { - context: BrowserContext; - page: Page; - browserServer: BrowserServer; - testOutputDir: string; - tmpDir: string; +type AllTestFixtures = { createUserDataDir: () => Promise; launchPersistent: (options?: Parameters['launchPersistentContext']>[1]) => Promise<{context: BrowserContext, page: Page}>; }; -const fixtures = httpFixtures.union(platformFixtures) - .declareParameters() - .declareWorkerFixtures() - .declareTestFixtures(); -const { defineTestFixture, defineWorkerFixture, defineParameter, generateParametrizedTests } = fixtures; +export const fixtures = playwrightFixtures + .union(httpFixtures) + .union(platformFixtures) + .union(implFixtures) + .declareParameters() + .declareWorkerFixtures() + .declareTestFixtures(); +const { defineTestFixture, defineWorkerFixture, overrideWorkerFixture } = fixtures; -export const playwrightFixtures = fixtures; export const it = fixtures.it; export const fit = fixtures.fit; export const xit = fixtures.xit; @@ -81,14 +67,12 @@ export const beforeAll = fixtures.beforeAll; export const afterAll = fixtures.afterAll; export const options = { + ...platformOptions, + ...playwrightOptions, CHROMIUM: (parameters: PlaywrightParameters) => parameters.browserName === 'chromium', FIREFOX: (parameters: PlaywrightParameters) => parameters.browserName === 'firefox', WEBKIT: (parameters: PlaywrightParameters) => parameters.browserName === 'webkit', - HEADLESS: !!valueFromEnv('HEADLESS', true), WIRE: !!process.env.PWWIRE, - SLOW_MO: valueFromEnv('SLOW_MO', 0), - TRACING: valueFromEnv('TRACING', false), - ...platformOptions, }; const getExecutablePath = browserName => { @@ -100,7 +84,7 @@ const getExecutablePath = browserName => { return process.env.WKPATH; }; -defineWorkerFixture('defaultBrowserOptions', async ({ browserName }, runTest) => { +overrideWorkerFixture('defaultBrowserOptions', async ({browserName}, runTest) => { const executablePath = getExecutablePath(browserName); if (executablePath) console.error(`Using executable at ${executablePath}`); @@ -113,7 +97,7 @@ defineWorkerFixture('defaultBrowserOptions', async ({ browserName }, runTest) => }); }); -defineWorkerFixture('playwright', async ({browserName, testWorkerIndex, platform}, test) => { +overrideWorkerFixture('playwright', async ({browserName, testWorkerIndex, platform}, test) => { assert(platform); // Depend on platform to generate all tests. const {coverage, uninstall} = installCoverageHooks(browserName); if (options.WIRE) { @@ -153,96 +137,10 @@ defineWorkerFixture('playwright', async ({browserName, testWorkerIndex, platform } }); -defineWorkerFixture('toImpl', async ({playwright}, test) => { - await test((playwright as any)._toImpl); -}); - -defineWorkerFixture('browserType', async ({playwright, browserName}, test) => { - const browserType = playwright[browserName]; - await test(browserType); -}); - -defineParameter('browserName', 'Browser type name', ''); - -generateParametrizedTests( - 'browserName', - process.env.BROWSER ? [process.env.BROWSER] : ['chromium', 'webkit', 'firefox']); - -defineWorkerFixture('isChromium', async ({browserName}, test) => { - await test(browserName === 'chromium'); -}); - -defineWorkerFixture('isFirefox', async ({browserName}, test) => { - await test(browserName === 'firefox'); -}); - -defineWorkerFixture('isWebKit', async ({browserName}, test) => { - await test(browserName === 'webkit'); -}); - -defineWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => { - const browser = await browserType.launch(defaultBrowserOptions); - await test(browser); - if (browser.contexts().length !== 0) { - console.warn(`\nWARNING: test did not close all created contexts! ${new Error().stack}\n`); - await Promise.all(browser.contexts().map(context => context.close())).catch(e => void 0); - } - await browser.close(); -}); - defineWorkerFixture('golden', async ({browserName}, test) => { await test(p => path.join(browserName, p)); }); -defineWorkerFixture('expectedSSLError', async ({ browserName, platform }, runTest) => { - let expectedSSLError: string; - if (browserName === 'chromium') { - expectedSSLError = 'net::ERR_CERT_AUTHORITY_INVALID'; - } else if (browserName === 'webkit') { - if (platform === 'darwin') - expectedSSLError = 'The certificate for this server is invalid'; - else if (platform === 'win32') - expectedSSLError = 'SSL peer certificate or SSH remote key was not OK'; - else - expectedSSLError = 'Unacceptable TLS certificate'; - } else { - expectedSSLError = 'SSL_ERROR_UNKNOWN'; - } - await runTest(expectedSSLError); -}); - -defineTestFixture('testOutputDir', async ({ testInfo }, runTest) => { - const relativePath = path.relative(config.testDir, testInfo.file).replace(/\.spec\.[jt]s/, ''); - const sanitizedTitle = testInfo.title.replace(/[^\w\d]+/g, '_'); - const testOutputDir = path.join(config.outputDir, relativePath, sanitizedTitle); - await fs.promises.mkdir(testOutputDir, { recursive: true }); - await runTest(testOutputDir); - const files = await fs.promises.readdir(testOutputDir); - if (!files.length) { - // Do not leave an empty useless directory. - // This might throw. See https://github.com/GoogleChrome/puppeteer/issues/2778 - await removeFolderAsync(testOutputDir).catch(e => {}); - } -}); - -defineTestFixture('context', async ({ browser, testOutputDir }, runTest) => { - const contextOptions: BrowserContextOptions = { - relativeArtifactsPath: path.relative(config.outputDir, testOutputDir), - recordTrace: !!options.TRACING, - recordVideos: !!options.TRACING, - }; - const context = await browser.newContext(contextOptions); - await runTest(context); - await context.close(); -}); - -defineTestFixture('page', async ({ context, testOutputDir, testInfo }, runTest) => { - const page = await context.newPage(); - await runTest(page); - if (testInfo.status === 'failed' || testInfo.status === 'timedOut') - await page.screenshot({ timeout: 5000, path: path.join(testOutputDir, 'test-failed.png') }); -}); - defineTestFixture('createUserDataDir', async ({testOutputDir}, runTest) => { let counter = 0; const dirs: string[] = []; @@ -273,40 +171,3 @@ defineTestFixture('launchPersistent', async ({createUserDataDir, defaultBrowserO if (context) await context.close(); }); - -defineTestFixture('tmpDir', async ({}, test) => { - const tmpDir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-')); - await test(tmpDir); - await removeFolderAsync(tmpDir).catch(e => {}); -}); - -function valueFromEnv(name, defaultValue) { - if (!(name in process.env)) - return defaultValue; - return JSON.parse(process.env[name]); -} - -export async function attachFrame(page: Page, frameId: string, url: string): Promise { - const handle = await page.evaluateHandle(async ({ frameId, url }) => { - const frame = document.createElement('iframe'); - frame.src = url; - frame.id = frameId; - document.body.appendChild(frame); - await new Promise(x => frame.onload = x); - return frame; - }, { frameId, url }); - return handle.asElement().contentFrame(); -} - -export async function detachFrame(page: Page, frameId: string) { - await page.evaluate(frameId => { - document.getElementById(frameId).remove(); - }, frameId); -} - -export async function verifyViewport(page: Page, width: number, height: number) { - expect(page.viewportSize().width).toBe(width); - expect(page.viewportSize().height).toBe(height); - expect(await page.evaluate('window.innerWidth')).toBe(width); - expect(await page.evaluate('window.innerHeight')).toBe(height); -} diff --git a/test/remoteServer.fixture.ts b/test/remoteServer.fixture.ts index ea39725f44..703ee5ce19 100644 --- a/test/remoteServer.fixture.ts +++ b/test/remoteServer.fixture.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { playwrightFixtures } from './playwright.fixtures'; +import { fixtures as baseFixtures } from './playwright.fixtures'; import path from 'path'; import { spawn } from 'child_process'; @@ -24,7 +24,7 @@ type ServerFixtures = { remoteServer: RemoteServer; stallingRemoteServer: RemoteServer; }; -export const serverFixtures = playwrightFixtures.declareTestFixtures(); +export const serverFixtures = baseFixtures.declareTestFixtures(); const { defineTestFixture } = serverFixtures; const playwrightPath = path.join(__dirname, '..'); diff --git a/test/screencast.spec.ts b/test/screencast.spec.ts index 188469a03d..872942aaee 100644 --- a/test/screencast.spec.ts +++ b/test/screencast.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { options, playwrightFixtures, config } from './playwright.fixtures'; +import { options, fixtures as playwrightFixtures, config } from './playwright.fixtures'; import type { Page, Browser } from '..'; import fs from 'fs'; diff --git a/test/slowmo.spec.ts b/test/slowmo.spec.ts index 2300529a70..ceaeb92551 100644 --- a/test/slowmo.spec.ts +++ b/test/slowmo.spec.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { it, expect, describe, options, attachFrame } from './playwright.fixtures'; +import { it, expect, describe, options } from './playwright.fixtures'; +import { attachFrame } from './utils'; async function checkSlowMo(toImpl, page, task) { let didSlowMo = false; diff --git a/test/upstream.fixtures.ts b/test/upstream.fixtures.ts new file mode 100644 index 0000000000..533abda24d --- /dev/null +++ b/test/upstream.fixtures.ts @@ -0,0 +1,153 @@ +/** + * Copyright Microsoft Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { config, fixtures as baseFixtures } from '@playwright/test-runner'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; +import util from 'util'; +import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from '../index'; + +const mkdtempAsync = util.promisify(fs.mkdtemp); +const removeFolderAsync = util.promisify(require('rimraf')); + +export type PlaywrightParameters = { + browserName: string; +}; + +type PlaywrightWorkerFixtures = { + defaultBrowserOptions: LaunchOptions; + playwright: typeof import('../index'); + browserType: BrowserType; + browser: Browser; + isChromium: boolean; + isFirefox: boolean; + isWebKit: boolean; +}; + +type PlaywrightTestFixtures = { + context: BrowserContext; + page: Page; + testOutputDir: string; + tmpDir: string; +}; + +export const fixtures = baseFixtures + .declareParameters() + .declareWorkerFixtures() + .declareTestFixtures(); + +const { defineTestFixture, defineWorkerFixture, defineParameter, generateParametrizedTests } = fixtures; + +export const options = { + CHROMIUM: (parameters: PlaywrightParameters) => parameters.browserName === 'chromium', + FIREFOX: (parameters: PlaywrightParameters) => parameters.browserName === 'firefox', + WEBKIT: (parameters: PlaywrightParameters) => parameters.browserName === 'webkit', + HEADLESS: !!valueFromEnv('HEADLESS', true), + SLOW_MO: valueFromEnv('SLOW_MO', 0), + TRACING: valueFromEnv('TRACING', false), +}; + +defineWorkerFixture('defaultBrowserOptions', async ({}, runTest) => { + await runTest({ + handleSIGINT: false, + slowMo: options.SLOW_MO, + headless: options.HEADLESS, + artifactsPath: config.outputDir, + }); +}); + +defineWorkerFixture('playwright', async ({}, test) => { + const playwright = require('../index'); + await test(playwright); +}); + +defineWorkerFixture('browserType', async ({playwright, browserName}, test) => { + const browserType = playwright[browserName]; + await test(browserType); +}); + +defineParameter('browserName', 'Browser type name', ''); + +generateParametrizedTests( + 'browserName', + process.env.BROWSER ? [process.env.BROWSER] : ['chromium', 'webkit', 'firefox']); + +defineWorkerFixture('isChromium', async ({browserName}, test) => { + await test(browserName === 'chromium'); +}); + +defineWorkerFixture('isFirefox', async ({browserName}, test) => { + await test(browserName === 'firefox'); +}); + +defineWorkerFixture('isWebKit', async ({browserName}, test) => { + await test(browserName === 'webkit'); +}); + +defineWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => { + const browser = await browserType.launch(defaultBrowserOptions); + await test(browser); + if (browser.contexts().length !== 0) { + console.warn(`\nWARNING: test did not close all created contexts! ${new Error().stack}\n`); + await Promise.all(browser.contexts().map(context => context.close())).catch(e => void 0); + } + await browser.close(); +}); + +defineTestFixture('testOutputDir', async ({ testInfo }, runTest) => { + const relativePath = path.relative(config.testDir, testInfo.file).replace(/\.spec\.[jt]s/, ''); + const sanitizedTitle = testInfo.title.replace(/[^\w\d]+/g, '_'); + const testOutputDir = path.join(config.outputDir, relativePath, sanitizedTitle); + await fs.promises.mkdir(testOutputDir, { recursive: true }); + await runTest(testOutputDir); + const files = await fs.promises.readdir(testOutputDir); + if (!files.length) { + // Do not leave an empty useless directory. + // This might throw. See https://github.com/GoogleChrome/puppeteer/issues/2778 + await removeFolderAsync(testOutputDir).catch(e => {}); + } +}); + +defineTestFixture('context', async ({ browser, testOutputDir }, runTest) => { + const contextOptions: BrowserContextOptions = { + relativeArtifactsPath: path.relative(config.outputDir, testOutputDir), + recordTrace: !!options.TRACING, + recordVideos: !!options.TRACING, + }; + const context = await browser.newContext(contextOptions); + await runTest(context); + await context.close(); +}); + +defineTestFixture('page', async ({ context, testOutputDir, testInfo }, runTest) => { + const page = await context.newPage(); + await runTest(page); + if (testInfo.status === 'failed' || testInfo.status === 'timedOut') + await page.screenshot({ timeout: 5000, path: path.join(testOutputDir, 'test-failed.png') }); +}); + +defineTestFixture('tmpDir', async ({}, test) => { + const tmpDir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-')); + await test(tmpDir); + await removeFolderAsync(tmpDir).catch(e => {}); +}); + +function valueFromEnv(name, defaultValue) { + if (!(name in process.env)) + return defaultValue; + return JSON.parse(process.env[name]); +} diff --git a/test/utils.ts b/test/utils.ts new file mode 100644 index 0000000000..0bd8885fa7 --- /dev/null +++ b/test/utils.ts @@ -0,0 +1,60 @@ +/** + * Copyright Microsoft Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from './playwright.fixtures'; +import type { Frame, Page } from '../index'; + +export async function attachFrame(page: Page, frameId: string, url: string): Promise { + const handle = await page.evaluateHandle(async ({ frameId, url }) => { + const frame = document.createElement('iframe'); + frame.src = url; + frame.id = frameId; + document.body.appendChild(frame); + await new Promise(x => frame.onload = x); + return frame; + }, { frameId, url }); + return handle.asElement().contentFrame(); +} + +export async function detachFrame(page: Page, frameId: string) { + await page.evaluate(frameId => { + document.getElementById(frameId).remove(); + }, frameId); +} + +export async function verifyViewport(page: Page, width: number, height: number) { + expect(page.viewportSize().width).toBe(width); + expect(page.viewportSize().height).toBe(height); + expect(await page.evaluate('window.innerWidth')).toBe(width); + expect(await page.evaluate('window.innerHeight')).toBe(height); +} + +export function expectedSSLError(browserName: string): string { + let expectedSSLError: string; + if (browserName === 'chromium') { + expectedSSLError = 'net::ERR_CERT_AUTHORITY_INVALID'; + } else if (browserName === 'webkit') { + if (process.platform === 'darwin') + expectedSSLError = 'The certificate for this server is invalid'; + else if (process.platform === 'win32') + expectedSSLError = 'SSL peer certificate or SSH remote key was not OK'; + else + expectedSSLError = 'Unacceptable TLS certificate'; + } else { + expectedSSLError = 'SSL_ERROR_UNKNOWN'; + } + return expectedSSLError; +} diff --git a/test/wait-for-selector-1.spec.ts b/test/wait-for-selector-1.spec.ts index ff0dc2a966..34ed18fde0 100644 --- a/test/wait-for-selector-1.spec.ts +++ b/test/wait-for-selector-1.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame, detachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame, detachFrame } from './utils'; async function giveItTimeToLog(frame) { await frame.evaluate(() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))); diff --git a/test/wait-for-selector-2.spec.ts b/test/wait-for-selector-2.spec.ts index 8457998027..d1477cfb43 100644 --- a/test/wait-for-selector-2.spec.ts +++ b/test/wait-for-selector-2.spec.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { it, expect, attachFrame, detachFrame } from './playwright.fixtures'; +import { it, expect } from './playwright.fixtures'; +import { attachFrame, detachFrame } from './utils'; const addElement = tag => document.body.appendChild(document.createElement(tag));