Revert "chore: use plugins for component testing again (#13977)" (#13998)

This reverts commit a2f9f15e3e.
This commit is contained in:
Pavel Feldman 2022-05-06 11:02:07 -08:00 committed by GitHub
parent a1cda41cfd
commit 1bbefce9af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 349 additions and 516 deletions

View File

@ -74,7 +74,7 @@ This file makes sure `mount` fixture is typed in your tests.
### Step 2. Create a test file `src/App.spec.tsx`
```js
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-react';
import App from './App';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -1,12 +1,10 @@
import { type PlaywrightTestConfig, devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-vue';
import { type PlaywrightTestConfig, devices } 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',
},

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import Counter from './Counter.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import Counter from './Counter.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import HelloWorld from './HelloWorld.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import HelloWorld from './HelloWorld.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import NamedSlots from './NamedSlots.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import NamedSlots from './NamedSlots.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import DocumentationIcon from './icons/IconDocumentation.vue'
import WelcomeItem from './WelcomeItem.vue'

View File

@ -1,8 +0,0 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src", "playwright.d.ts", "vue.d.ts"],
}

View File

@ -15,17 +15,16 @@
*/
import path from 'path';
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-react';
import type { PlaywrightTestConfig } from '@playwright/experimental-ct-react';
import { devices } 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: [ ],

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { expect, test } from '@playwright/test';
import { expect, test } from '@playwright/experimental-ct-react';
import { AutoChip, Chip as LocalChip } from './chip';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-react';
import { HeaderView } from './headerView';
test.use({ viewport: { width: 720, height: 200 } });

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-react';
import type { ImageDiff } from './imageDiffView';
import { ImageDiffView } from './imageDiffView';

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-react';
import { TestCaseView } from './testCaseView';
import type { TestCase, TestResult } from '../../playwright-test/src/reporters/html';

View File

@ -24,6 +24,6 @@
"playwright-test/lib/*": ["../playwright-test/src/*"],
}
},
"include": ["src", "playwright.d.ts"],
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -14,15 +14,27 @@
* limitations under the License.
*/
import type { Locator, TestPlugin } from '@playwright/test';
import type {
TestType,
PlaywrightTestArgs,
PlaywrightTestConfig as BasePlaywrightTestConfig,
PlaywrightTestOptions,
PlaywrightWorkerArgs,
PlaywrightWorkerOptions,
Locator,
} from '@playwright/test';
import type { InlineConfig } from 'vite';
declare global {
export namespace PlaywrightTest {
export interface TestArgs {
export type PlaywrightTestConfig = Omit<BasePlaywrightTestConfig, 'use'> & {
use?: BasePlaywrightTestConfig['use'] & { vitePort?: number, viteConfig?: InlineConfig }
};
interface ComponentFixtures {
mount(component: JSX.Element): Promise<Locator>;
}
}
}
export default function(options?: { vitePort?: number, viteConfig?: InlineConfig }): TestPlugin;
export const test: TestType<
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
export { expect, devices } from '@playwright/test';

View File

@ -14,14 +14,42 @@
* limitations under the License.
*/
const { test: baseTest, expect, devices, _addRunnerPlugin } = require('@playwright/test');
const { mount } = require('@playwright/test/lib/mount');
const path = require('path');
module.exports = ({ viteConfig, vitePort } = {}) => {
const { vitePlugin } = require('@playwright/test/lib/plugins/vitePlugin');
return vitePlugin(
'playwright:experimental-ct-react',
_addRunnerPlugin(() => {
// Only fetch upon request to avoid resolution in workers.
const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin');
return createPlugin(
path.join(__dirname, 'registerSource.mjs'),
() => require('@vitejs/plugin-react')(),
viteConfig,
vitePort);
};
() => 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 };

View File

@ -14,19 +14,31 @@
* limitations under the License.
*/
import type { Locator, TestPlugin } from '@playwright/test';
import type {
TestType,
PlaywrightTestArgs,
PlaywrightTestConfig as BasePlaywrightTestConfig,
PlaywrightTestOptions,
PlaywrightWorkerArgs,
PlaywrightWorkerOptions,
Locator,
} from '@playwright/test';
import type { InlineConfig } from 'vite';
declare global {
export namespace PlaywrightTest {
export interface TestArgs {
export type PlaywrightTestConfig = Omit<BasePlaywrightTestConfig, 'use'> & {
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<Locator>;
}
}
}
export default function(options?: { vitePort?: number, viteConfig?: InlineConfig }): TestPlugin;
export const test: TestType<
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
export { expect, devices } from '@playwright/test';

View File

@ -14,14 +14,42 @@
* limitations under the License.
*/
const { test: baseTest, expect, devices, _addRunnerPlugin } = require('@playwright/test');
const { mount } = require('@playwright/test/lib/mount');
const path = require('path');
module.exports = ({ viteConfig, vitePort } = {}) => {
const { vitePlugin } = require('@playwright/test/lib/plugins/vitePlugin');
return vitePlugin(
'playwright:experimental-ct-svelte',
_addRunnerPlugin(() => {
// Only fetch upon request to avoid resolution in workers.
const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin');
return createPlugin(
path.join(__dirname, 'registerSource.mjs'),
() => require('@sveltejs/vite-plugin-svelte').svelte(),
viteConfig,
vitePort);
};
() => 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 };

View File

@ -14,20 +14,32 @@
* limitations under the License.
*/
import type { Locator, TestPlugin } from '@playwright/test';
import type {
TestType,
PlaywrightTestArgs,
PlaywrightTestConfig as BasePlaywrightTestConfig,
PlaywrightTestOptions,
PlaywrightWorkerArgs,
PlaywrightWorkerOptions,
Locator,
} from '@playwright/test';
import type { InlineConfig } from 'vite';
declare global {
export namespace PlaywrightTest {
export interface TestArgs {
export type PlaywrightTestConfig = Omit<BasePlaywrightTestConfig, 'use'> & {
use?: BasePlaywrightTestConfig['use'] & { vitePort?: number, viteConfig?: InlineConfig }
};
interface ComponentFixtures {
mount(component: JSX.Element): Promise<Locator>;
mount(component: any, options?: {
props?: { [key: string]: any },
slots?: { [key: string]: any },
on?: { [key: string]: Function },
}): Promise<Locator>;
}
}
}
export default function(options?: { vitePort?: number, viteConfig?: InlineConfig }): TestPlugin;
export const test: TestType<
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
export { expect, devices } from '@playwright/test';

View File

@ -14,14 +14,42 @@
* limitations under the License.
*/
const { test: baseTest, expect, devices, _addRunnerPlugin } = require('@playwright/test');
const { mount } = require('@playwright/test/lib/mount');
const path = require('path');
module.exports = ({ viteConfig, vitePort } = {}) => {
const { vitePlugin } = require('@playwright/test/lib/plugins/vitePlugin');
return vitePlugin(
'playwright:experimental-ct-vue',
_addRunnerPlugin(() => {
// Only fetch upon request to avoid resolution in workers.
const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin');
return createPlugin(
path.join(__dirname, 'registerSource.mjs'),
() => require('@vitejs/plugin-vue')(),
viteConfig,
vitePort);
};
() => 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 };

View File

@ -18,6 +18,7 @@
"./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"

View File

@ -123,17 +123,13 @@ export class Loader {
if (config.snapshotDir !== undefined)
config.snapshotDir = path.resolve(configDir, config.snapshotDir);
const resolvedPlugins = await Promise.all((config.plugins || []).map(async plugin => {
config.plugins = 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 resolvedPlugins) {
for (const plugin of config.plugins || []) {
if (!plugin.fixtures)
continue;
if (typeof plugin.fixtures === 'string')
@ -159,7 +155,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(resolvedPlugins, baseFullConfig._plugins);
this._fullConfig._plugins = takeFirst(config.plugins, 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));
}

View File

@ -14,57 +14,131 @@
* limitations under the License.
*/
import type { InlineConfig, Plugin } from 'vite';
import fs from 'fs';
import type { Suite } from '../../types/testReporter';
import type { Fixtures, FullConfig, Locator, Page, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, TestPlugin } from '../types';
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 { mount } from '../mount';
let previewServer: PreviewServer;
export function vitePlugin(
name: string,
export function createPlugin(
registerSourceFile: string,
frameworkPluginFactory: () => Plugin,
viteConfig: InlineConfig = {},
vitePort: number = 3100): TestPlugin {
let teardownVite: () => Promise<void>;
frameworkPluginFactory: () => Plugin): TestRunnerPlugin {
let configDir: string;
return {
name,
name: 'playwright-vite-plugin',
setup: async (config: FullConfig, configDirectory: string, suite: Suite) => {
teardownVite = await require('./vitePluginSetup').setup(registerSourceFile, frameworkPluginFactory, configDirectory, suite, viteConfig, vitePort);
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<string>();
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);
},
teardown: async () => {
await teardownVite();
await new Promise<void>((f, r) => previewServer.httpServer.close(err => {
if (err)
r(err);
else
f();
}));
},
fixtures
};
}
const fixtures: Fixtures<PlaywrightTestArgs & PlaywrightTestOptions & { mount: (component: any, options: any) => Promise<Locator> }, 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;
const imports: Map<string, ComponentInfo> = new Map();
function vitePlugin(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);
}
}
}
});
await use(page);
}, { scope: 'worker' }],
context: async ({ page }, use) => {
await use(page.context());
}
},
page: async ({ _workerPage }, use) => {
await use(_workerPage);
},
transform: async (content, id) => {
if (!id.endsWith('playwright/index.ts') && !id.endsWith('playwright/index.tsx') && !id.endsWith('playwright/index.js'))
return;
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);
});
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');
},
};
};
}

View File

@ -1,129 +0,0 @@
/**
* 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<string>();
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<void>((f, r) => previewServer.httpServer.close(err => {
if (err)
r(err);
else
f();
}));
};
return teardown;
};
const imports: Map<string, ComponentInfo> = 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');
},
};
}

View File

@ -370,8 +370,9 @@ type LiteralUnion<T extends U, U = string> = T | (U & { zz_IGNORE_ME?: never });
*
*/
export interface TestPlugin {
name: string;
fixtures?: Fixtures;
name: string;
/**
* @param config
* @param configDir
@ -474,7 +475,7 @@ interface TestConfig {
*
*/
webServer?: TestConfigWebServer;
plugins?: (TestPlugin | string | [string, any])[],
plugins?: TestPlugin[],
/**
* Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts).
*
@ -2619,7 +2620,7 @@ export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';
* ```
*
*/
export interface PlaywrightTestOptions extends PlaywrightTest.TestOptions {
export interface PlaywrightTestOptions {
/**
* Whether to automatically download all the attachments. Defaults to `true` where all the downloads are accepted.
*/
@ -2807,7 +2808,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 extends PlaywrightTest.TestArgs {
export interface PlaywrightTestArgs {
/**
* 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.
@ -2925,12 +2926,6 @@ declare global {
export namespace PlaywrightTest {
export interface Matchers<R, T = unknown> {
}
export interface TestArgs {
}
export interface TestOptions {
}
}
}
// --- ENDGLOBAL ---

View File

@ -14,17 +14,16 @@
* limitations under the License.
*/
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-react';
import type { PlaywrightTestConfig } from '@playwright/experimental-ct-react';
import { devices } 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: [

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { expect, test } from '@playwright/test';
import { expect, test } from '@playwright/experimental-ct-react';
import { Expandable } from './expandable';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { expect, test } from '@playwright/test';
import { expect, test } from '@playwright/experimental-ct-react';
import { Source } from './source';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -15,7 +15,7 @@
*/
import React from 'react';
import { expect, test } from '@playwright/test';
import { expect, test } from '@playwright/experimental-ct-react';
import { SplitView } from './splitView';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -1,8 +0,0 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src", "playwright.d.ts"],
}

View File

@ -1,2 +1 @@
package-lock.json
dist-pw

View File

@ -14,15 +14,13 @@
* limitations under the License.
*/
import { type PlaywrightTestConfig, devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-react';
import { type PlaywrightTestConfig, devices } 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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-react';
import App from './App';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -16,6 +16,6 @@
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src", "playwright.d.ts"],
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -14,15 +14,13 @@
* limitations under the License.
*/
import { type PlaywrightTestConfig, devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-react';
import { type PlaywrightTestConfig, devices } 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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-react';
import App from './App';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -21,7 +21,6 @@
"jsx": "react-jsx"
},
"include": [
"src",
"playwright.d.ts"
"src"
]
}

View File

@ -14,16 +14,14 @@
* limitations under the License.
*/
import type { PlaywrightTestConfig } from '@playwright/test';
import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte';
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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-svelte';
import Counter from './Counter.svelte';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -1,4 +0,0 @@
declare module '*.svelte' {
const value: any; // Add better type definitions here if desired.
export default value;
}

View File

@ -1,8 +0,0 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src", "playwright.d.ts", "selte.d.ts"],
}

View File

@ -14,16 +14,14 @@
* limitations under the License.
*/
import type { PlaywrightTestConfig } from '@playwright/test';
import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte';
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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-svelte';
import Counter from './Counter.svelte';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -15,6 +15,6 @@
"allowJs": true,
"checkJs": true
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte", "playwright.d.ts"],
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -14,16 +14,14 @@
* limitations under the License.
*/
import type { PlaywrightTestConfig } from '@playwright/test';
import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte';
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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { test, expect } from '@playwright/test';
import { test, expect } from '@playwright/experimental-ct-svelte';
import App from './App.svelte';
test.use({ viewport: { width: 500, height: 500 } });

View File

@ -1,8 +0,0 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src", "playwright.d.ts", "svelte.d.ts"],
}

View File

@ -14,15 +14,13 @@
* limitations under the License.
*/
import { type PlaywrightTestConfig, devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-vue';
import { type PlaywrightTestConfig, devices } 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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import Button from './components/Button.vue'
import DefaultSlot from './components/DefaultSlot.vue'
import NamedSlots from './components/NamedSlots.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import Button from './components/Button.vue'
import DefaultSlot from './components/DefaultSlot.vue'

View File

@ -14,15 +14,13 @@
* limitations under the License.
*/
import { type PlaywrightTestConfig, devices } from '@playwright/test';
import ct from '@playwright/experimental-ct-vue';
import { type PlaywrightTestConfig, devices } 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',
},

View File

@ -1,17 +0,0 @@
/**
* 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';

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import Button from './components/Button.vue'
import DefaultSlot from './components/DefaultSlot.vue'
import NamedSlots from './components/NamedSlots.vue'

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { test, expect } from '@playwright/experimental-ct-vue'
import Button from './components/Button.vue'
import DefaultSlot from './components/DefaultSlot.vue'

View File

@ -1,8 +0,0 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src", "vue.d.ts", "playwright.d.ts"],
}

View File

@ -17030,8 +17030,9 @@ type LiteralUnion<T extends U, U = string> = T | (U & { zz_IGNORE_ME?: never });
*
*/
export interface TestPlugin {
name: string;
fixtures?: Fixtures;
name: string;
/**
* @param config
* @param configDir
@ -17134,7 +17135,7 @@ interface TestConfig {
*
*/
webServer?: TestConfigWebServer;
plugins?: (TestPlugin | string | [string, any])[],
plugins?: TestPlugin[],
/**
* Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts).
*
@ -19364,7 +19365,7 @@ export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';
* ```
*
*/
export interface PlaywrightTestOptions extends PlaywrightTest.TestOptions {
export interface PlaywrightTestOptions {
/**
* Whether to automatically download all the attachments. Defaults to `true` where all the downloads are accepted.
*/
@ -19552,7 +19553,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 extends PlaywrightTest.TestArgs {
export interface PlaywrightTestArgs {
/**
* 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.

View File

@ -93,7 +93,7 @@ class TypesGenerator {
let overrides = await parseOverrides(overridesFile, className => {
const docClass = this.docClassForName(className);
if (!docClass || !this.shouldGenerate(className))
if (!docClass)
return '';
handledClasses.add(className);
return this.writeComment(docClass.comment) + '\n';
@ -573,7 +573,6 @@ class TypesGenerator {
'PlaywrightWorkerOptions.defaultBrowserType',
'PlaywrightWorkerArgs.playwright',
'Matchers',
'TestArgs',
]),
doNotExportClassNames: new Set([...assertionClasses, 'TestProject']),
includeExperimental,

View File

@ -57,14 +57,13 @@ export interface FullProject<TestArgs = {}, WorkerArgs = {}> {
type LiteralUnion<T extends U, U = string> = 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 | string | [string, any])[],
plugins?: TestPlugin[],
}
export interface Config<TestArgs = {}, WorkerArgs = {}> extends TestConfig {
@ -213,7 +212,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 extends PlaywrightTest.TestOptions {
export interface PlaywrightTestOptions {
acceptDownloads: boolean | undefined;
bypassCSP: boolean | undefined;
colorScheme: ColorScheme | undefined;
@ -245,7 +244,7 @@ export interface PlaywrightWorkerArgs {
browser: Browser;
}
export interface PlaywrightTestArgs extends PlaywrightTest.TestArgs {
export interface PlaywrightTestArgs {
context: BrowserContext;
page: Page;
request: APIRequestContext;
@ -318,12 +317,6 @@ declare global {
export namespace PlaywrightTest {
export interface Matchers<R, T = unknown> {
}
export interface TestArgs {
}
export interface TestOptions {
}
}
}
// --- ENDGLOBAL ---