From a2f9f15e3e2419d24b8b1deb87d304c363f93435 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 5 May 2022 13:26:56 -0800 Subject: [PATCH] chore: use plugins for component testing again (#13977) --- docs/src/test-components-js.md | 2 +- examples/components-vue/playwright.config.ts | 4 +- .../src/components/Counter.spec.ts | 2 +- .../src/components/Counter.spec.tsx | 2 +- .../src/components/HelloWorld.spec.ts | 2 +- .../src/components/HelloWorld.spec.tsx | 2 +- .../src/components/NamedSlots.spec.ts | 2 +- .../src/components/NamedSlots.spec.tsx | 2 +- .../src/components/WelcomeItem.spec.tsx | 2 +- examples/components-vue/tsconfig.json | 8 + packages/html-reporter/playwright.config.ts | 7 +- packages/html-reporter/playwright.d.ts | 17 ++ packages/html-reporter/src/chip.spec.tsx | 2 +- .../html-reporter/src/headerView.spec.tsx | 2 +- .../html-reporter/src/imageDiffView.spec.tsx | 2 +- .../html-reporter/src/testCaseView.spec.tsx | 2 +- packages/html-reporter/tsconfig.json | 2 +- packages/playwright-ct-react/index.d.ts | 28 +--- packages/playwright-ct-react/index.js | 44 +----- packages/playwright-ct-svelte/index.d.ts | 36 ++--- packages/playwright-ct-svelte/index.js | 44 +----- packages/playwright-ct-vue/index.d.ts | 38 ++--- packages/playwright-ct-vue/index.js | 44 +----- packages/playwright-test/package.json | 1 - packages/playwright-test/src/loader.ts | 10 +- .../playwright-test/src/plugins/vitePlugin.ts | 148 +++++------------- .../src/plugins/vitePluginSetup.ts | 129 +++++++++++++++ packages/playwright-test/types/test.d.ts | 15 +- packages/web/playwright.config.ts | 7 +- packages/web/playwright.d.ts | 17 ++ .../web/src/components/expandable.spec.tsx | 2 +- packages/web/src/components/source.spec.tsx | 2 +- .../web/src/components/splitView.spec.tsx | 2 +- packages/web/tsconfig.json | 8 + tests/components/.gitignore | 3 +- .../ct-react-vite/playwright.config.ts | 4 +- .../components/ct-react-vite/playwright.d.ts | 17 ++ .../components/ct-react-vite/src/App.spec.tsx | 2 +- tests/components/ct-react-vite/tsconfig.json | 2 +- .../components/ct-react/playwright.config.ts | 4 +- tests/components/ct-react/playwright.d.ts | 17 ++ tests/components/ct-react/src/App.spec.tsx | 2 +- tests/components/ct-react/tsconfig.json | 3 +- .../ct-svelte-kit/playwright.config.ts | 4 +- .../components/ct-svelte-kit/playwright.d.ts | 17 ++ .../ct-svelte-kit/src/lib/Counter.spec.ts | 2 +- tests/components/ct-svelte-kit/svelte.d.ts | 4 + tests/components/ct-svelte-kit/tsconfig.json | 8 + .../ct-svelte-vite/playwright.config.ts | 4 +- .../components/ct-svelte-vite/playwright.d.ts | 17 ++ .../ct-svelte-vite/src/lib/Counter.spec.ts | 2 +- tests/components/ct-svelte-vite/tsconfig.json | 2 +- .../components/ct-svelte/playwright.config.ts | 4 +- tests/components/ct-svelte/playwright.d.ts | 17 ++ tests/components/ct-svelte/src/App.spec.ts | 2 +- tests/components/ct-svelte/tsconfig.json | 8 + .../ct-vue-cli/playwright.config.ts | 4 +- tests/components/ct-vue-cli/playwright.d.ts | 17 ++ .../ct-vue-cli/src/notation-jsx.spec.tsx | 2 +- .../ct-vue-cli/src/notation-vue.spec.ts | 2 +- .../ct-vue-vite/playwright.config.ts | 4 +- tests/components/ct-vue-vite/playwright.d.ts | 17 ++ .../ct-vue-vite/src/notation-jsx.spec.tsx | 2 +- .../ct-vue-vite/src/notation-vue.spec.ts | 2 +- tests/components/ct-vue-vite/tsconfig.json | 8 + tests/config/experimental.d.ts | 9 +- utils/generate_types/index.js | 3 +- utils/generate_types/overrides-test.d.ts | 13 +- 68 files changed, 516 insertions(+), 349 deletions(-) create mode 100644 examples/components-vue/tsconfig.json create mode 100644 packages/html-reporter/playwright.d.ts create mode 100644 packages/playwright-test/src/plugins/vitePluginSetup.ts create mode 100644 packages/web/playwright.d.ts create mode 100644 packages/web/tsconfig.json create mode 100644 tests/components/ct-react-vite/playwright.d.ts create mode 100644 tests/components/ct-react/playwright.d.ts create mode 100644 tests/components/ct-svelte-kit/playwright.d.ts create mode 100644 tests/components/ct-svelte-kit/svelte.d.ts create mode 100644 tests/components/ct-svelte-kit/tsconfig.json create mode 100644 tests/components/ct-svelte-vite/playwright.d.ts create mode 100644 tests/components/ct-svelte/playwright.d.ts create mode 100644 tests/components/ct-svelte/tsconfig.json create mode 100644 tests/components/ct-vue-cli/playwright.d.ts create mode 100644 tests/components/ct-vue-vite/playwright.d.ts create mode 100644 tests/components/ct-vue-vite/tsconfig.json diff --git a/docs/src/test-components-js.md b/docs/src/test-components-js.md index dabaffd0f9..be88eb2f54 100644 --- a/docs/src/test-components-js.md +++ b/docs/src/test-components-js.md @@ -62,7 +62,7 @@ npm i @playwright/experimental-ct-react ### Create a test `src/App.spec.tsx` ```js -import { test, expect } from '@playwright/experimental-ct-react'; +import { test, expect } from '@playwright/test'; import App from './App'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/examples/components-vue/playwright.config.ts b/examples/components-vue/playwright.config.ts index 2ea0e59130..da94fee7ed 100644 --- a/examples/components-vue/playwright.config.ts +++ b/examples/components-vue/playwright.config.ts @@ -1,10 +1,12 @@ -import { type PlaywrightTestConfig, devices } from '@playwright/experimental-ct-vue'; +import { type PlaywrightTestConfig, devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-vue'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/examples/components-vue/src/components/Counter.spec.ts b/examples/components-vue/src/components/Counter.spec.ts index 9c5613215e..11d1c6c0cb 100644 --- a/examples/components-vue/src/components/Counter.spec.ts +++ b/examples/components-vue/src/components/Counter.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import Counter from './Counter.vue' diff --git a/examples/components-vue/src/components/Counter.spec.tsx b/examples/components-vue/src/components/Counter.spec.tsx index 60e18b1bf9..f35c482d32 100644 --- a/examples/components-vue/src/components/Counter.spec.tsx +++ b/examples/components-vue/src/components/Counter.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import Counter from './Counter.vue' diff --git a/examples/components-vue/src/components/HelloWorld.spec.ts b/examples/components-vue/src/components/HelloWorld.spec.ts index b041f7c258..f15b6924e7 100644 --- a/examples/components-vue/src/components/HelloWorld.spec.ts +++ b/examples/components-vue/src/components/HelloWorld.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import HelloWorld from './HelloWorld.vue' diff --git a/examples/components-vue/src/components/HelloWorld.spec.tsx b/examples/components-vue/src/components/HelloWorld.spec.tsx index 8340a011f5..695d7a48ec 100644 --- a/examples/components-vue/src/components/HelloWorld.spec.tsx +++ b/examples/components-vue/src/components/HelloWorld.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import HelloWorld from './HelloWorld.vue' diff --git a/examples/components-vue/src/components/NamedSlots.spec.ts b/examples/components-vue/src/components/NamedSlots.spec.ts index b230b7d038..815e79ec27 100644 --- a/examples/components-vue/src/components/NamedSlots.spec.ts +++ b/examples/components-vue/src/components/NamedSlots.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import NamedSlots from './NamedSlots.vue' diff --git a/examples/components-vue/src/components/NamedSlots.spec.tsx b/examples/components-vue/src/components/NamedSlots.spec.tsx index 891f8e4f1b..7d5b5cc9e6 100644 --- a/examples/components-vue/src/components/NamedSlots.spec.tsx +++ b/examples/components-vue/src/components/NamedSlots.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import NamedSlots from './NamedSlots.vue' diff --git a/examples/components-vue/src/components/WelcomeItem.spec.tsx b/examples/components-vue/src/components/WelcomeItem.spec.tsx index dfddb71dfe..8598f56fb2 100644 --- a/examples/components-vue/src/components/WelcomeItem.spec.tsx +++ b/examples/components-vue/src/components/WelcomeItem.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import DocumentationIcon from './icons/IconDocumentation.vue' import WelcomeItem from './WelcomeItem.vue' diff --git a/examples/components-vue/tsconfig.json b/examples/components-vue/tsconfig.json new file mode 100644 index 0000000000..9fab5a8f8b --- /dev/null +++ b/examples/components-vue/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "include": ["src", "playwright.d.ts", "vue.d.ts"], +} diff --git a/packages/html-reporter/playwright.config.ts b/packages/html-reporter/playwright.config.ts index cb1ed7b480..baa0c2e80c 100644 --- a/packages/html-reporter/playwright.config.ts +++ b/packages/html-reporter/playwright.config.ts @@ -15,16 +15,17 @@ */ import path from 'path'; -import type { PlaywrightTestConfig } from '@playwright/experimental-ct-react'; -import { devices } from '@playwright/experimental-ct-react'; +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-react'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct({ vitePort: 3101 })], use: { - vitePort: 3101, trace: 'on-first-retry', }, projects: [ ], diff --git a/packages/html-reporter/playwright.d.ts b/packages/html-reporter/playwright.d.ts new file mode 100644 index 0000000000..e288a40e04 --- /dev/null +++ b/packages/html-reporter/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-react'; diff --git a/packages/html-reporter/src/chip.spec.tsx b/packages/html-reporter/src/chip.spec.tsx index 4306a5182f..6dfe480eac 100644 --- a/packages/html-reporter/src/chip.spec.tsx +++ b/packages/html-reporter/src/chip.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { expect, test } from '@playwright/experimental-ct-react'; +import { expect, test } from '@playwright/test'; import { AutoChip, Chip as LocalChip } from './chip'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/packages/html-reporter/src/headerView.spec.tsx b/packages/html-reporter/src/headerView.spec.tsx index 12ac7b903c..c853d45801 100644 --- a/packages/html-reporter/src/headerView.spec.tsx +++ b/packages/html-reporter/src/headerView.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { test, expect } from '@playwright/experimental-ct-react'; +import { test, expect } from '@playwright/test'; import { HeaderView } from './headerView'; test.use({ viewport: { width: 720, height: 200 } }); diff --git a/packages/html-reporter/src/imageDiffView.spec.tsx b/packages/html-reporter/src/imageDiffView.spec.tsx index bfd622d45d..317ceb30d6 100644 --- a/packages/html-reporter/src/imageDiffView.spec.tsx +++ b/packages/html-reporter/src/imageDiffView.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { test, expect } from '@playwright/experimental-ct-react'; +import { test, expect } from '@playwright/test'; import type { ImageDiff } from './imageDiffView'; import { ImageDiffView } from './imageDiffView'; diff --git a/packages/html-reporter/src/testCaseView.spec.tsx b/packages/html-reporter/src/testCaseView.spec.tsx index 4dedfecc0a..1274977d9b 100644 --- a/packages/html-reporter/src/testCaseView.spec.tsx +++ b/packages/html-reporter/src/testCaseView.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { test, expect } from '@playwright/experimental-ct-react'; +import { test, expect } from '@playwright/test'; import { TestCaseView } from './testCaseView'; import type { TestCase, TestResult } from '../../playwright-test/src/reporters/html'; diff --git a/packages/html-reporter/tsconfig.json b/packages/html-reporter/tsconfig.json index 31c2e167d1..75c92a2ca8 100644 --- a/packages/html-reporter/tsconfig.json +++ b/packages/html-reporter/tsconfig.json @@ -24,6 +24,6 @@ "playwright-test/lib/*": ["../playwright-test/src/*"], } }, - "include": ["src"], + "include": ["src", "playwright.d.ts"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/packages/playwright-ct-react/index.d.ts b/packages/playwright-ct-react/index.d.ts index 76f294a34f..1f34f7bebf 100644 --- a/packages/playwright-ct-react/index.d.ts +++ b/packages/playwright-ct-react/index.d.ts @@ -14,27 +14,15 @@ * limitations under the License. */ -import type { - TestType, - PlaywrightTestArgs, - PlaywrightTestConfig as BasePlaywrightTestConfig, - PlaywrightTestOptions, - PlaywrightWorkerArgs, - PlaywrightWorkerOptions, - Locator, -} from '@playwright/test'; +import type { Locator, TestPlugin } from '@playwright/test'; import type { InlineConfig } from 'vite'; -export type PlaywrightTestConfig = Omit & { - use?: BasePlaywrightTestConfig['use'] & { vitePort?: number, viteConfig?: InlineConfig } -}; - -interface ComponentFixtures { - mount(component: JSX.Element): Promise; +declare global { + export namespace PlaywrightTest { + export interface TestArgs { + mount(component: JSX.Element): Promise; + } + } } -export const test: TestType< - PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures, - PlaywrightWorkerArgs & PlaywrightWorkerOptions>; - -export { expect, devices } from '@playwright/test'; +export default function(options?: { vitePort?: number, viteConfig?: InlineConfig }): TestPlugin; diff --git a/packages/playwright-ct-react/index.js b/packages/playwright-ct-react/index.js index 1cfa5de35b..421ba4ff9b 100644 --- a/packages/playwright-ct-react/index.js +++ b/packages/playwright-ct-react/index.js @@ -14,42 +14,14 @@ * limitations under the License. */ -const { test: baseTest, expect, devices, _addRunnerPlugin } = require('@playwright/test'); -const { mount } = require('@playwright/test/lib/mount'); const path = require('path'); -_addRunnerPlugin(() => { - // Only fetch upon request to avoid resolution in workers. - const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin'); - return createPlugin( +module.exports = ({ viteConfig, vitePort } = {}) => { + const { vitePlugin } = require('@playwright/test/lib/plugins/vitePlugin'); + return vitePlugin( + 'playwright:experimental-ct-react', path.join(__dirname, 'registerSource.mjs'), - () => require('@vitejs/plugin-react')()); -}); - -const test = baseTest.extend({ - _workerPage: [async ({ browser }, use) => { - const page = await browser._wrapApiCall(async () => { - const page = await browser.newPage(); - await page.addInitScript('navigator.serviceWorker.register = () => {}'); - return page; - }); - await use(page); - }, { scope: 'worker' }], - - context: async ({ page }, use) => { - await use(page.context()); - }, - - page: async ({ _workerPage }, use) => { - await use(_workerPage); - }, - - mount: async ({ page, baseURL, viewport }, use) => { - await use(async (component, options) => { - const selector = await mount(page, component, options, baseURL, viewport); - return page.locator(selector); - }); - }, -}); - -module.exports = { test, expect, devices }; + () => require('@vitejs/plugin-react')(), + viteConfig, + vitePort); +}; diff --git a/packages/playwright-ct-svelte/index.d.ts b/packages/playwright-ct-svelte/index.d.ts index 479d70de17..bc9eac0c8a 100644 --- a/packages/playwright-ct-svelte/index.d.ts +++ b/packages/playwright-ct-svelte/index.d.ts @@ -14,31 +14,19 @@ * limitations under the License. */ -import type { - TestType, - PlaywrightTestArgs, - PlaywrightTestConfig as BasePlaywrightTestConfig, - PlaywrightTestOptions, - PlaywrightWorkerArgs, - PlaywrightWorkerOptions, - Locator, -} from '@playwright/test'; +import type { Locator, TestPlugin } from '@playwright/test'; import type { InlineConfig } from 'vite'; -export type PlaywrightTestConfig = Omit & { - use?: BasePlaywrightTestConfig['use'] & { vitePort?: number, viteConfig?: InlineConfig } -}; - -interface ComponentFixtures { - mount(component: any, options?: { - props?: { [key: string]: any }, - slots?: { [key: string]: any }, - on?: { [key: string]: Function }, - }): Promise; +declare global { + export namespace PlaywrightTest { + export interface TestArgs { + mount(component: any, options?: { + props?: { [key: string]: any }, + slots?: { [key: string]: any }, + on?: { [key: string]: Function }, + }): Promise; + } + } } -export const test: TestType< - PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures, - PlaywrightWorkerArgs & PlaywrightWorkerOptions>; - -export { expect, devices } from '@playwright/test'; +export default function(options?: { vitePort?: number, viteConfig?: InlineConfig }): TestPlugin; diff --git a/packages/playwright-ct-svelte/index.js b/packages/playwright-ct-svelte/index.js index ebdf48a25e..82cb766cdd 100644 --- a/packages/playwright-ct-svelte/index.js +++ b/packages/playwright-ct-svelte/index.js @@ -14,42 +14,14 @@ * limitations under the License. */ -const { test: baseTest, expect, devices, _addRunnerPlugin } = require('@playwright/test'); -const { mount } = require('@playwright/test/lib/mount'); const path = require('path'); -_addRunnerPlugin(() => { - // Only fetch upon request to avoid resolution in workers. - const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin'); - return createPlugin( +module.exports = ({ viteConfig, vitePort } = {}) => { + const { vitePlugin } = require('@playwright/test/lib/plugins/vitePlugin'); + return vitePlugin( + 'playwright:experimental-ct-svelte', path.join(__dirname, 'registerSource.mjs'), - () => require('@sveltejs/vite-plugin-svelte').svelte()); -}); - -const test = baseTest.extend({ - _workerPage: [async ({ browser }, use) => { - const page = await browser._wrapApiCall(async () => { - const page = await browser.newPage(); - await page.addInitScript('navigator.serviceWorker.register = () => {}'); - return page; - }); - await use(page); - }, { scope: 'worker' }], - - context: async ({ page }, use) => { - await use(page.context()); - }, - - page: async ({ _workerPage }, use) => { - await use(_workerPage); - }, - - mount: async ({ page, baseURL, viewport }, use) => { - await use(async (component, options) => { - const selector = await mount(page, component, options, baseURL, viewport); - return page.locator(selector); - }); - }, -}); - -module.exports = { test, expect, devices }; + () => require('@sveltejs/vite-plugin-svelte').svelte(), + viteConfig, + vitePort); +}; diff --git a/packages/playwright-ct-vue/index.d.ts b/packages/playwright-ct-vue/index.d.ts index 71adb2e133..58660bc85b 100644 --- a/packages/playwright-ct-vue/index.d.ts +++ b/packages/playwright-ct-vue/index.d.ts @@ -14,32 +14,20 @@ * limitations under the License. */ -import type { - TestType, - PlaywrightTestArgs, - PlaywrightTestConfig as BasePlaywrightTestConfig, - PlaywrightTestOptions, - PlaywrightWorkerArgs, - PlaywrightWorkerOptions, - Locator, -} from '@playwright/test'; +import type { Locator, TestPlugin } from '@playwright/test'; import type { InlineConfig } from 'vite'; -export type PlaywrightTestConfig = Omit & { - use?: BasePlaywrightTestConfig['use'] & { vitePort?: number, viteConfig?: InlineConfig } -}; - -interface ComponentFixtures { - mount(component: JSX.Element): Promise; - mount(component: any, options?: { - props?: { [key: string]: any }, - slots?: { [key: string]: any }, - on?: { [key: string]: Function }, - }): Promise; +declare global { + export namespace PlaywrightTest { + export interface TestArgs { + mount(component: JSX.Element): Promise; + mount(component: any, options?: { + props?: { [key: string]: any }, + slots?: { [key: string]: any }, + on?: { [key: string]: Function }, + }): Promise; + } + } } -export const test: TestType< - PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures, - PlaywrightWorkerArgs & PlaywrightWorkerOptions>; - -export { expect, devices } from '@playwright/test'; +export default function(options?: { vitePort?: number, viteConfig?: InlineConfig }): TestPlugin; diff --git a/packages/playwright-ct-vue/index.js b/packages/playwright-ct-vue/index.js index f69856f172..645b0622fa 100644 --- a/packages/playwright-ct-vue/index.js +++ b/packages/playwright-ct-vue/index.js @@ -14,42 +14,14 @@ * limitations under the License. */ -const { test: baseTest, expect, devices, _addRunnerPlugin } = require('@playwright/test'); -const { mount } = require('@playwright/test/lib/mount'); const path = require('path'); -_addRunnerPlugin(() => { - // Only fetch upon request to avoid resolution in workers. - const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin'); - return createPlugin( +module.exports = ({ viteConfig, vitePort } = {}) => { + const { vitePlugin } = require('@playwright/test/lib/plugins/vitePlugin'); + return vitePlugin( + 'playwright:experimental-ct-vue', path.join(__dirname, 'registerSource.mjs'), - () => require('@vitejs/plugin-vue')()); -}); - -const test = baseTest.extend({ - _workerPage: [async ({ browser }, use) => { - const page = await browser._wrapApiCall(async () => { - const page = await browser.newPage(); - await page.addInitScript('navigator.serviceWorker.register = () => {}'); - return page; - }); - await use(page); - }, { scope: 'worker' }], - - context: async ({ page }, use) => { - await use(page.context()); - }, - - page: async ({ _workerPage }, use) => { - await use(_workerPage); - }, - - mount: async ({ page, baseURL, viewport }, use) => { - await use(async (component, options) => { - const selector = await mount(page, component, options, baseURL, viewport); - return page.locator(selector); - }); - }, -}); - -module.exports = { test, expect, devices }; + () => require('@vitejs/plugin-vue')(), + viteConfig, + vitePort); +}; diff --git a/packages/playwright-test/package.json b/packages/playwright-test/package.json index 798e24989d..fc29b82f72 100644 --- a/packages/playwright-test/package.json +++ b/packages/playwright-test/package.json @@ -18,7 +18,6 @@ "./lib/ci": "./lib/ci.js", "./lib/cli": "./lib/cli.js", "./lib/experimentalLoader": "./lib/experimentalLoader.js", - "./lib/mount": "./lib/mount.js", "./lib/plugins": "./lib/plugins/index.js", "./lib/plugins/vitePlugin": "./lib/plugins/vitePlugin.js", "./reporter": "./reporter.js" diff --git a/packages/playwright-test/src/loader.ts b/packages/playwright-test/src/loader.ts index 46b967b4d6..e51d48025d 100644 --- a/packages/playwright-test/src/loader.ts +++ b/packages/playwright-test/src/loader.ts @@ -123,13 +123,17 @@ export class Loader { if (config.snapshotDir !== undefined) config.snapshotDir = path.resolve(configDir, config.snapshotDir); - config.plugins = await Promise.all((config.plugins || []).map(async plugin => { + const resolvedPlugins = await Promise.all((config.plugins || []).map(async plugin => { if (typeof plugin === 'string') return (await this._requireOrImportDefaultObject(resolveScript(plugin, configDir))) as TestPlugin; + if (Array.isArray(plugin)) { + const func = await this._requireOrImportDefaultFunction(resolveScript(plugin[0], configDir), false); + plugin = func(plugin[1]) as TestPlugin; + } return plugin; })); - for (const plugin of config.plugins || []) { + for (const plugin of resolvedPlugins) { if (!plugin.fixtures) continue; if (typeof plugin.fixtures === 'string') @@ -155,7 +159,7 @@ export class Loader { this._fullConfig.updateSnapshots = takeFirst(config.updateSnapshots, baseFullConfig.updateSnapshots); this._fullConfig.workers = takeFirst(config.workers, baseFullConfig.workers); this._fullConfig.webServer = takeFirst(config.webServer, baseFullConfig.webServer); - this._fullConfig._plugins = takeFirst(config.plugins, baseFullConfig._plugins); + this._fullConfig._plugins = takeFirst(resolvedPlugins, baseFullConfig._plugins); this._fullConfig.metadata = takeFirst(config.metadata, baseFullConfig.metadata); this._fullConfig.projects = (config.projects || [config]).map(p => this._resolveProject(config, this._fullConfig, p, throwawayArtifactsPath)); } diff --git a/packages/playwright-test/src/plugins/vitePlugin.ts b/packages/playwright-test/src/plugins/vitePlugin.ts index 5708fbc835..49b69f0d77 100644 --- a/packages/playwright-test/src/plugins/vitePlugin.ts +++ b/packages/playwright-test/src/plugins/vitePlugin.ts @@ -14,131 +14,57 @@ * limitations under the License. */ -import fs from 'fs'; +import type { InlineConfig, Plugin } from 'vite'; import type { Suite } from '../../types/testReporter'; -import path from 'path'; -import type { InlineConfig, Plugin, PreviewServer } from 'vite'; -import type { TestRunnerPlugin } from '.'; -import { parse, traverse, types as t } from '../babelBundle'; -import type { ComponentInfo } from '../tsxTransform'; -import { collectComponentUsages, componentInfo } from '../tsxTransform'; -import type { FullConfig } from '../types'; +import type { Fixtures, FullConfig, Locator, Page, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, TestPlugin } from '../types'; -let previewServer: PreviewServer; +import { mount } from '../mount'; -export function createPlugin( +export function vitePlugin( + name: string, registerSourceFile: string, - frameworkPluginFactory: () => Plugin): TestRunnerPlugin { - let configDir: string; + frameworkPluginFactory: () => Plugin, + viteConfig: InlineConfig = {}, + vitePort: number = 3100): TestPlugin { + + let teardownVite: () => Promise; return { - name: 'playwright-vite-plugin', + name, setup: async (config: FullConfig, configDirectory: string, suite: Suite) => { - const use = config.projects[0].use as any; - const viteConfig: InlineConfig = use.viteConfig || {}; - const port = use.vitePort || 3100; - - configDir = configDirectory; - - process.env.PLAYWRIGHT_TEST_BASE_URL = `http://localhost:${port}/playwright/index.html`; - - viteConfig.root = viteConfig.root || configDir; - viteConfig.plugins = viteConfig.plugins || [ - frameworkPluginFactory() - ]; - const files = new Set(); - for (const project of suite.suites) { - for (const file of project.suites) - files.add(file.location!.file); - } - const registerSource = await fs.promises.readFile(registerSourceFile, 'utf-8'); - viteConfig.plugins.push(vitePlugin(registerSource, [...files])); - viteConfig.configFile = viteConfig.configFile || false; - viteConfig.define = viteConfig.define || {}; - viteConfig.define.__VUE_PROD_DEVTOOLS__ = true; - viteConfig.css = viteConfig.css || {}; - viteConfig.css.devSourcemap = true; - viteConfig.preview = { port }; - viteConfig.build = { - target: 'esnext', - minify: false, - rollupOptions: { - treeshake: false, - input: { - index: path.join(viteConfig.root, 'playwright', 'index.html') - }, - }, - sourcemap: true, - outDir: viteConfig?.build?.outDir || path.join(viteConfig.root, './dist-pw/') - }; - const { build, preview } = require('vite'); - await build(viteConfig); - previewServer = await preview(viteConfig); + teardownVite = await require('./vitePluginSetup').setup(registerSourceFile, frameworkPluginFactory, configDirectory, suite, viteConfig, vitePort); }, teardown: async () => { - await new Promise((f, r) => previewServer.httpServer.close(err => { - if (err) - r(err); - else - f(); - })); + await teardownVite(); }, + + fixtures }; } -const imports: Map = new Map(); +const fixtures: Fixtures Promise }, PlaywrightWorkerArgs & { _workerPage: Page }> = { + _workerPage: [async ({ browser }, use) => { + const page = await (browser as any)._wrapApiCall(async () => { + const page = await browser.newPage(); + await page.addInitScript('navigator.serviceWorker.register = () => {}'); + return page; + }); + await use(page); + }, { scope: 'worker' }], -function vitePlugin(registerSource: string, files: string[]): Plugin { - return { - name: 'playwright:component-index', + context: async ({ page }, use) => { + await use(page.context()); + }, - configResolved: async config => { + page: async ({ _workerPage }, use) => { + await use(_workerPage); + }, - for (const file of files) { - const text = await fs.promises.readFile(file, 'utf-8'); - const ast = parse(text, { errorRecovery: true, plugins: ['typescript', 'jsx'], sourceType: 'module' }); - const components = collectComponentUsages(ast); - - traverse(ast, { - enter: p => { - if (t.isImportDeclaration(p.node)) { - const importNode = p.node; - if (!t.isStringLiteral(importNode.source)) - return; - - for (const specifier of importNode.specifiers) { - if (!components.names.has(specifier.local.name)) - continue; - if (t.isImportNamespaceSpecifier(specifier)) - continue; - const info = componentInfo(specifier, importNode.source.value, file); - imports.set(info.fullName, info); - } - } - } - }); - } - }, - - transform: async (content, id) => { - if (!id.endsWith('playwright/index.ts') && !id.endsWith('playwright/index.tsx') && !id.endsWith('playwright/index.js')) - return; - - const folder = path.dirname(id); - const lines = [content, '']; - lines.push(registerSource); - - for (const [alias, value] of imports) { - const importPath = value.isModuleOrAlias ? value.importPath : './' + path.relative(folder, value.importPath).replace(/\\/g, '/'); - if (value.importedName) - lines.push(`import { ${value.importedName} as ${alias} } from '${importPath}';`); - else - lines.push(`import ${alias} from '${importPath}';`); - } - - lines.push(`register({ ${[...imports.keys()].join(',\n ')} });`); - return lines.join('\n'); - }, - }; -} + mount: async ({ page, viewport }, use) => { + await use(async (component, options) => { + const selector = await mount(page, component, options, process.env.PLAYWRIGHT_VITE_PLUGIN_GALLERY!, viewport || { width: 1280, height: 720 }); + return page.locator(selector); + }); + }, +}; diff --git a/packages/playwright-test/src/plugins/vitePluginSetup.ts b/packages/playwright-test/src/plugins/vitePluginSetup.ts new file mode 100644 index 0000000000..6a699b3b7a --- /dev/null +++ b/packages/playwright-test/src/plugins/vitePluginSetup.ts @@ -0,0 +1,129 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 type { Suite } from '../../types/testReporter'; +import type { InlineConfig, Plugin } from 'vite'; +import type { ComponentInfo } from '../tsxTransform'; + +import fs from 'fs'; +import path from 'path'; +import { parse, traverse, types as t } from '../babelBundle'; +import { collectComponentUsages, componentInfo } from '../tsxTransform'; + +const { build, preview } = require('vite') as typeof import('vite'); + +export const setup = async (registerSourceFile: string, frameworkPluginFactory: () => Plugin, configDirectory: string, suite: Suite, viteConfig: InlineConfig, vitePort: number) => { + process.env.PLAYWRIGHT_VITE_PLUGIN_GALLERY = `http://localhost:${vitePort}/playwright/index.html`; + + viteConfig.root = viteConfig.root || configDirectory; + viteConfig.plugins = viteConfig.plugins || [ + frameworkPluginFactory() + ]; + const files = new Set(); + for (const project of suite.suites) { + for (const file of project.suites) + files.add(file.location!.file); + } + const registerSource = await fs.promises.readFile(registerSourceFile, 'utf-8'); + viteConfig.plugins.push(generateGalleryPlugin(registerSource, [...files])); + viteConfig.configFile = viteConfig.configFile || false; + viteConfig.define = viteConfig.define || {}; + viteConfig.define.__VUE_PROD_DEVTOOLS__ = true; + viteConfig.css = viteConfig.css || {}; + viteConfig.css.devSourcemap = true; + viteConfig.preview = { port: vitePort }; + viteConfig.build = { + target: 'esnext', + minify: false, + rollupOptions: { + treeshake: false, + input: { + index: path.join(viteConfig.root, 'playwright', 'index.html') + }, + }, + sourcemap: true, + outDir: viteConfig?.build?.outDir || path.join(viteConfig.root, './dist-pw/') + }; + + await build(viteConfig); + const previewServer = await preview(viteConfig); + + const teardown = async () => { + await new Promise((f, r) => previewServer.httpServer.close(err => { + if (err) + r(err); + else + f(); + })); + }; + return teardown; +}; + +const imports: Map = new Map(); + +function generateGalleryPlugin(registerSource: string, files: string[]): Plugin { + return { + name: 'playwright:component-index', + + configResolved: async config => { + + for (const file of files) { + const text = await fs.promises.readFile(file, 'utf-8'); + const ast = parse(text, { errorRecovery: true, plugins: ['typescript', 'jsx'], sourceType: 'module' }); + const components = collectComponentUsages(ast); + + traverse(ast, { + enter: p => { + if (t.isImportDeclaration(p.node)) { + const importNode = p.node; + if (!t.isStringLiteral(importNode.source)) + return; + + for (const specifier of importNode.specifiers) { + if (!components.names.has(specifier.local.name)) + continue; + if (t.isImportNamespaceSpecifier(specifier)) + continue; + const info = componentInfo(specifier, importNode.source.value, file); + imports.set(info.fullName, info); + } + } + } + }); + } + }, + + transform: async (content, id) => { + if (!id.endsWith('playwright/index.ts') && !id.endsWith('playwright/index.tsx') && !id.endsWith('playwright/index.js')) + return; + + const folder = path.dirname(id); + const lines = [content, '']; + lines.push(registerSource); + + for (const [alias, value] of imports) { + const importPath = value.isModuleOrAlias ? value.importPath : './' + path.relative(folder, value.importPath).replace(/\\/g, '/'); + if (value.importedName) + lines.push(`import { ${value.importedName} as ${alias} } from '${importPath}';`); + else + lines.push(`import ${alias} from '${importPath}';`); + } + + lines.push(`register({ ${[...imports.keys()].join(',\n ')} });`); + return lines.join('\n'); + }, + }; +} diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index 785601d556..a85df37363 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -370,9 +370,8 @@ type LiteralUnion = T | (U & { zz_IGNORE_ME?: never }); * */ export interface TestPlugin { - fixtures?: Fixtures; name: string; - + fixtures?: Fixtures; /** * @param config * @param configDir @@ -475,7 +474,7 @@ interface TestConfig { * */ webServer?: TestConfigWebServer; - plugins?: TestPlugin[], + plugins?: (TestPlugin | string | [string, any])[], /** * Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts). * @@ -2620,7 +2619,7 @@ export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; * ``` * */ -export interface PlaywrightTestOptions { +export interface PlaywrightTestOptions extends PlaywrightTest.TestOptions { /** * Whether to automatically download all the attachments. Defaults to `true` where all the downloads are accepted. */ @@ -2808,7 +2807,7 @@ export interface PlaywrightWorkerArgs { * [fixtures.context](https://playwright.dev/docs/api/class-fixtures#fixtures-context) and * [fixtures.page](https://playwright.dev/docs/api/class-fixtures#fixtures-page). */ -export interface PlaywrightTestArgs { +export interface PlaywrightTestArgs extends PlaywrightTest.TestArgs { /** * Isolated [BrowserContext] instance, created for each test. Since contexts are isolated between each other, every test * gets a fresh environment, even when multiple tests run in a single [Browser] for maximum efficiency. @@ -2926,6 +2925,12 @@ declare global { export namespace PlaywrightTest { export interface Matchers { } + + export interface TestArgs { + } + + export interface TestOptions { + } } } // --- ENDGLOBAL --- diff --git a/packages/web/playwright.config.ts b/packages/web/playwright.config.ts index 19c070ef95..098099fb80 100644 --- a/packages/web/playwright.config.ts +++ b/packages/web/playwright.config.ts @@ -14,16 +14,17 @@ * limitations under the License. */ -import type { PlaywrightTestConfig } from '@playwright/experimental-ct-react'; -import { devices } from '@playwright/experimental-ct-react'; +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-react'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct({ vitePort: 3102 })], use: { - vitePort: 3102, trace: 'on-first-retry', }, projects: [ diff --git a/packages/web/playwright.d.ts b/packages/web/playwright.d.ts new file mode 100644 index 0000000000..e288a40e04 --- /dev/null +++ b/packages/web/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-react'; diff --git a/packages/web/src/components/expandable.spec.tsx b/packages/web/src/components/expandable.spec.tsx index ad69f33aed..1c260cb25e 100644 --- a/packages/web/src/components/expandable.spec.tsx +++ b/packages/web/src/components/expandable.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { expect, test } from '@playwright/experimental-ct-react'; +import { expect, test } from '@playwright/test'; import { Expandable } from './expandable'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/packages/web/src/components/source.spec.tsx b/packages/web/src/components/source.spec.tsx index ee2f8b2f18..4b5bc95559 100644 --- a/packages/web/src/components/source.spec.tsx +++ b/packages/web/src/components/source.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { expect, test } from '@playwright/experimental-ct-react'; +import { expect, test } from '@playwright/test'; import { Source } from './source'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/packages/web/src/components/splitView.spec.tsx b/packages/web/src/components/splitView.spec.tsx index 1a302b93dd..0d5c6db04d 100644 --- a/packages/web/src/components/splitView.spec.tsx +++ b/packages/web/src/components/splitView.spec.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { expect, test } from '@playwright/experimental-ct-react'; +import { expect, test } from '@playwright/test'; import { SplitView } from './splitView'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json new file mode 100644 index 0000000000..349790399c --- /dev/null +++ b/packages/web/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "include": ["src", "playwright.d.ts"], +} diff --git a/tests/components/.gitignore b/tests/components/.gitignore index 483a9c42c3..cb47598978 100644 --- a/tests/components/.gitignore +++ b/tests/components/.gitignore @@ -1 +1,2 @@ -package-lock.json \ No newline at end of file +package-lock.json +dist-pw \ No newline at end of file diff --git a/tests/components/ct-react-vite/playwright.config.ts b/tests/components/ct-react-vite/playwright.config.ts index 44fa94f4fa..26e983b40b 100644 --- a/tests/components/ct-react-vite/playwright.config.ts +++ b/tests/components/ct-react-vite/playwright.config.ts @@ -14,13 +14,15 @@ * limitations under the License. */ -import { type PlaywrightTestConfig, devices } from '@playwright/experimental-ct-react'; +import { type PlaywrightTestConfig, devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-react'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-react-vite/playwright.d.ts b/tests/components/ct-react-vite/playwright.d.ts new file mode 100644 index 0000000000..e288a40e04 --- /dev/null +++ b/tests/components/ct-react-vite/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-react'; diff --git a/tests/components/ct-react-vite/src/App.spec.tsx b/tests/components/ct-react-vite/src/App.spec.tsx index e920f642b9..f15e7c1a03 100644 --- a/tests/components/ct-react-vite/src/App.spec.tsx +++ b/tests/components/ct-react-vite/src/App.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-react'; +import { test, expect } from '@playwright/test'; import App from './App'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/tests/components/ct-react-vite/tsconfig.json b/tests/components/ct-react-vite/tsconfig.json index c8bdc64082..56e54524ca 100644 --- a/tests/components/ct-react-vite/tsconfig.json +++ b/tests/components/ct-react-vite/tsconfig.json @@ -16,6 +16,6 @@ "noEmit": true, "jsx": "react-jsx" }, - "include": ["src"], + "include": ["src", "playwright.d.ts"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/tests/components/ct-react/playwright.config.ts b/tests/components/ct-react/playwright.config.ts index 44fa94f4fa..26e983b40b 100644 --- a/tests/components/ct-react/playwright.config.ts +++ b/tests/components/ct-react/playwright.config.ts @@ -14,13 +14,15 @@ * limitations under the License. */ -import { type PlaywrightTestConfig, devices } from '@playwright/experimental-ct-react'; +import { type PlaywrightTestConfig, devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-react'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-react/playwright.d.ts b/tests/components/ct-react/playwright.d.ts new file mode 100644 index 0000000000..e288a40e04 --- /dev/null +++ b/tests/components/ct-react/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-react'; diff --git a/tests/components/ct-react/src/App.spec.tsx b/tests/components/ct-react/src/App.spec.tsx index 9d7c57d828..94287e831b 100644 --- a/tests/components/ct-react/src/App.spec.tsx +++ b/tests/components/ct-react/src/App.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-react'; +import { test, expect } from '@playwright/test'; import App from './App'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/tests/components/ct-react/tsconfig.json b/tests/components/ct-react/tsconfig.json index a273b0cfc0..30f74da124 100644 --- a/tests/components/ct-react/tsconfig.json +++ b/tests/components/ct-react/tsconfig.json @@ -21,6 +21,7 @@ "jsx": "react-jsx" }, "include": [ - "src" + "src", + "playwright.d.ts" ] } diff --git a/tests/components/ct-svelte-kit/playwright.config.ts b/tests/components/ct-svelte-kit/playwright.config.ts index ce93c2efee..abae147417 100644 --- a/tests/components/ct-svelte-kit/playwright.config.ts +++ b/tests/components/ct-svelte-kit/playwright.config.ts @@ -14,14 +14,16 @@ * limitations under the License. */ -import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte'; +import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-svelte'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-svelte-kit/playwright.d.ts b/tests/components/ct-svelte-kit/playwright.d.ts new file mode 100644 index 0000000000..5133cc9329 --- /dev/null +++ b/tests/components/ct-svelte-kit/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-svelte'; diff --git a/tests/components/ct-svelte-kit/src/lib/Counter.spec.ts b/tests/components/ct-svelte-kit/src/lib/Counter.spec.ts index 1e863cd250..66b335924b 100644 --- a/tests/components/ct-svelte-kit/src/lib/Counter.spec.ts +++ b/tests/components/ct-svelte-kit/src/lib/Counter.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from '@playwright/experimental-ct-svelte'; +import { test, expect } from '@playwright/test'; import Counter from './Counter.svelte'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/tests/components/ct-svelte-kit/svelte.d.ts b/tests/components/ct-svelte-kit/svelte.d.ts new file mode 100644 index 0000000000..0fdb59facc --- /dev/null +++ b/tests/components/ct-svelte-kit/svelte.d.ts @@ -0,0 +1,4 @@ +declare module '*.svelte' { + const value: any; // Add better type definitions here if desired. + export default value; +} diff --git a/tests/components/ct-svelte-kit/tsconfig.json b/tests/components/ct-svelte-kit/tsconfig.json new file mode 100644 index 0000000000..596b463db6 --- /dev/null +++ b/tests/components/ct-svelte-kit/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "include": ["src", "playwright.d.ts", "selte.d.ts"], +} diff --git a/tests/components/ct-svelte-vite/playwright.config.ts b/tests/components/ct-svelte-vite/playwright.config.ts index ce93c2efee..abae147417 100644 --- a/tests/components/ct-svelte-vite/playwright.config.ts +++ b/tests/components/ct-svelte-vite/playwright.config.ts @@ -14,14 +14,16 @@ * limitations under the License. */ -import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte'; +import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-svelte'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-svelte-vite/playwright.d.ts b/tests/components/ct-svelte-vite/playwright.d.ts new file mode 100644 index 0000000000..5133cc9329 --- /dev/null +++ b/tests/components/ct-svelte-vite/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-svelte'; diff --git a/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts b/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts index 35a4a7dd81..1dbfef4f8c 100644 --- a/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts +++ b/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from '@playwright/experimental-ct-svelte'; +import { test, expect } from '@playwright/test'; import Counter from './Counter.svelte'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/tests/components/ct-svelte-vite/tsconfig.json b/tests/components/ct-svelte-vite/tsconfig.json index 4d6c04cf0a..c67ff894e8 100644 --- a/tests/components/ct-svelte-vite/tsconfig.json +++ b/tests/components/ct-svelte-vite/tsconfig.json @@ -15,6 +15,6 @@ "allowJs": true, "checkJs": true }, - "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte", "playwright.d.ts"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/tests/components/ct-svelte/playwright.config.ts b/tests/components/ct-svelte/playwright.config.ts index ce93c2efee..abae147417 100644 --- a/tests/components/ct-svelte/playwright.config.ts +++ b/tests/components/ct-svelte/playwright.config.ts @@ -14,14 +14,16 @@ * limitations under the License. */ -import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte'; +import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-svelte'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-svelte/playwright.d.ts b/tests/components/ct-svelte/playwright.d.ts new file mode 100644 index 0000000000..5133cc9329 --- /dev/null +++ b/tests/components/ct-svelte/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-svelte'; diff --git a/tests/components/ct-svelte/src/App.spec.ts b/tests/components/ct-svelte/src/App.spec.ts index 68223ddc06..dc3d71bfdb 100644 --- a/tests/components/ct-svelte/src/App.spec.ts +++ b/tests/components/ct-svelte/src/App.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from '@playwright/experimental-ct-svelte'; +import { test, expect } from '@playwright/test'; import App from './App.svelte'; test.use({ viewport: { width: 500, height: 500 } }); diff --git a/tests/components/ct-svelte/tsconfig.json b/tests/components/ct-svelte/tsconfig.json new file mode 100644 index 0000000000..7cc2aae6ce --- /dev/null +++ b/tests/components/ct-svelte/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "include": ["src", "playwright.d.ts", "svelte.d.ts"], +} diff --git a/tests/components/ct-vue-cli/playwright.config.ts b/tests/components/ct-vue-cli/playwright.config.ts index dbf9c593bd..4192cff1d5 100644 --- a/tests/components/ct-vue-cli/playwright.config.ts +++ b/tests/components/ct-vue-cli/playwright.config.ts @@ -14,13 +14,15 @@ * limitations under the License. */ -import { type PlaywrightTestConfig, devices } from '@playwright/experimental-ct-vue'; +import { type PlaywrightTestConfig, devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-vue'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-vue-cli/playwright.d.ts b/tests/components/ct-vue-cli/playwright.d.ts new file mode 100644 index 0000000000..8e069208e7 --- /dev/null +++ b/tests/components/ct-vue-cli/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-vue'; diff --git a/tests/components/ct-vue-cli/src/notation-jsx.spec.tsx b/tests/components/ct-vue-cli/src/notation-jsx.spec.tsx index 3ecea3cac2..6de506735b 100644 --- a/tests/components/ct-vue-cli/src/notation-jsx.spec.tsx +++ b/tests/components/ct-vue-cli/src/notation-jsx.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import Button from './components/Button.vue' import DefaultSlot from './components/DefaultSlot.vue' import NamedSlots from './components/NamedSlots.vue' diff --git a/tests/components/ct-vue-cli/src/notation-vue.spec.ts b/tests/components/ct-vue-cli/src/notation-vue.spec.ts index ae611bcdaf..756b1201a3 100644 --- a/tests/components/ct-vue-cli/src/notation-vue.spec.ts +++ b/tests/components/ct-vue-cli/src/notation-vue.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import Button from './components/Button.vue' import DefaultSlot from './components/DefaultSlot.vue' diff --git a/tests/components/ct-vue-vite/playwright.config.ts b/tests/components/ct-vue-vite/playwright.config.ts index dbf9c593bd..4192cff1d5 100644 --- a/tests/components/ct-vue-vite/playwright.config.ts +++ b/tests/components/ct-vue-vite/playwright.config.ts @@ -14,13 +14,15 @@ * limitations under the License. */ -import { type PlaywrightTestConfig, devices } from '@playwright/experimental-ct-vue'; +import { type PlaywrightTestConfig, devices } from '@playwright/test'; +import ct from '@playwright/experimental-ct-vue'; const config: PlaywrightTestConfig = { testDir: 'src', forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: 'html', + plugins: [ct()], use: { trace: 'on-first-retry', }, diff --git a/tests/components/ct-vue-vite/playwright.d.ts b/tests/components/ct-vue-vite/playwright.d.ts new file mode 100644 index 0000000000..8e069208e7 --- /dev/null +++ b/tests/components/ct-vue-vite/playwright.d.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * 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 '@playwright/experimental-ct-vue'; diff --git a/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx b/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx index 4d604f5362..a11d9fa9cf 100644 --- a/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx +++ b/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import Button from './components/Button.vue' import DefaultSlot from './components/DefaultSlot.vue' import NamedSlots from './components/NamedSlots.vue' diff --git a/tests/components/ct-vue-vite/src/notation-vue.spec.ts b/tests/components/ct-vue-vite/src/notation-vue.spec.ts index ae611bcdaf..756b1201a3 100644 --- a/tests/components/ct-vue-vite/src/notation-vue.spec.ts +++ b/tests/components/ct-vue-vite/src/notation-vue.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/experimental-ct-vue' +import { test, expect } from '@playwright/test' import Button from './components/Button.vue' import DefaultSlot from './components/DefaultSlot.vue' diff --git a/tests/components/ct-vue-vite/tsconfig.json b/tests/components/ct-vue-vite/tsconfig.json new file mode 100644 index 0000000000..53199e3d4a --- /dev/null +++ b/tests/components/ct-vue-vite/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "include": ["src", "vue.d.ts", "playwright.d.ts"], +} diff --git a/tests/config/experimental.d.ts b/tests/config/experimental.d.ts index 8e48c6f8a3..7eff0f5b6a 100644 --- a/tests/config/experimental.d.ts +++ b/tests/config/experimental.d.ts @@ -17030,9 +17030,8 @@ type LiteralUnion = T | (U & { zz_IGNORE_ME?: never }); * */ export interface TestPlugin { - fixtures?: Fixtures; name: string; - + fixtures?: Fixtures; /** * @param config * @param configDir @@ -17135,7 +17134,7 @@ interface TestConfig { * */ webServer?: TestConfigWebServer; - plugins?: TestPlugin[], + plugins?: (TestPlugin | string | [string, any])[], /** * Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts). * @@ -19365,7 +19364,7 @@ export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; * ``` * */ -export interface PlaywrightTestOptions { +export interface PlaywrightTestOptions extends PlaywrightTest.TestOptions { /** * Whether to automatically download all the attachments. Defaults to `true` where all the downloads are accepted. */ @@ -19553,7 +19552,7 @@ export interface PlaywrightWorkerArgs { * [fixtures.context](https://playwright.dev/docs/api/class-fixtures#fixtures-context) and * [fixtures.page](https://playwright.dev/docs/api/class-fixtures#fixtures-page). */ -export interface PlaywrightTestArgs { +export interface PlaywrightTestArgs extends PlaywrightTest.TestArgs { /** * Isolated [BrowserContext] instance, created for each test. Since contexts are isolated between each other, every test * gets a fresh environment, even when multiple tests run in a single [Browser] for maximum efficiency. diff --git a/utils/generate_types/index.js b/utils/generate_types/index.js index 1775b0e235..53d13a6c88 100644 --- a/utils/generate_types/index.js +++ b/utils/generate_types/index.js @@ -93,7 +93,7 @@ class TypesGenerator { let overrides = await parseOverrides(overridesFile, className => { const docClass = this.docClassForName(className); - if (!docClass) + if (!docClass || !this.shouldGenerate(className)) return ''; handledClasses.add(className); return this.writeComment(docClass.comment) + '\n'; @@ -573,6 +573,7 @@ class TypesGenerator { 'PlaywrightWorkerOptions.defaultBrowserType', 'PlaywrightWorkerArgs.playwright', 'Matchers', + 'TestArgs', ]), doNotExportClassNames: new Set([...assertionClasses, 'TestProject']), includeExperimental, diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 40f6621fa7..4231987127 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -57,13 +57,14 @@ export interface FullProject { type LiteralUnion = T | (U & { zz_IGNORE_ME?: never }); export interface TestPlugin { + name: string; fixtures?: Fixtures; } interface TestConfig { reporter?: LiteralUnion<'list'|'dot'|'line'|'github'|'json'|'junit'|'null'|'html', string> | ReporterDescription[]; webServer?: TestConfigWebServer; - plugins?: TestPlugin[], + plugins?: (TestPlugin | string | [string, any])[], } export interface Config extends TestConfig { @@ -212,7 +213,7 @@ export interface PlaywrightWorkerOptions { export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; -export interface PlaywrightTestOptions { +export interface PlaywrightTestOptions extends PlaywrightTest.TestOptions { acceptDownloads: boolean | undefined; bypassCSP: boolean | undefined; colorScheme: ColorScheme | undefined; @@ -244,7 +245,7 @@ export interface PlaywrightWorkerArgs { browser: Browser; } -export interface PlaywrightTestArgs { +export interface PlaywrightTestArgs extends PlaywrightTest.TestArgs { context: BrowserContext; page: Page; request: APIRequestContext; @@ -317,6 +318,12 @@ declare global { export namespace PlaywrightTest { export interface Matchers { } + + export interface TestArgs { + } + + export interface TestOptions { + } } } // --- ENDGLOBAL ---