chore: add experimental mount (#12657)
This commit is contained in:
parent
d7c1a57565
commit
af55f48754
30
package-lock.json
generated
30
package-lock.json
generated
|
|
@ -1117,6 +1117,18 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@playwright/ct-react": {
|
||||||
|
"resolved": "packages/playwright-ct-react",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
|
"node_modules/@playwright/ct-svelte": {
|
||||||
|
"resolved": "packages/playwright-ct-svelte",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
|
"node_modules/@playwright/ct-vue": {
|
||||||
|
"resolved": "packages/playwright-ct-vue",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@playwright/test": {
|
"node_modules/@playwright/test": {
|
||||||
"resolved": "packages/playwright-test",
|
"resolved": "packages/playwright-test",
|
||||||
"link": true
|
"link": true
|
||||||
|
|
@ -7364,6 +7376,15 @@
|
||||||
"node": ">= 12"
|
"node": ">= 12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"packages/playwright-ct-react": {
|
||||||
|
"name": "@playwright/ct-react"
|
||||||
|
},
|
||||||
|
"packages/playwright-ct-svelte": {
|
||||||
|
"name": "@playwright/ct-svelte"
|
||||||
|
},
|
||||||
|
"packages/playwright-ct-vue": {
|
||||||
|
"name": "@playwright/ct-vue"
|
||||||
|
},
|
||||||
"packages/playwright-firefox": {
|
"packages/playwright-firefox": {
|
||||||
"version": "1.21.0-next",
|
"version": "1.21.0-next",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
|
|
@ -8195,6 +8216,15 @@
|
||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@playwright/ct-react": {
|
||||||
|
"version": "file:packages/playwright-ct-react"
|
||||||
|
},
|
||||||
|
"@playwright/ct-svelte": {
|
||||||
|
"version": "file:packages/playwright-ct-svelte"
|
||||||
|
},
|
||||||
|
"@playwright/ct-vue": {
|
||||||
|
"version": "file:packages/playwright-ct-vue"
|
||||||
|
},
|
||||||
"@playwright/test": {
|
"@playwright/test": {
|
||||||
"version": "file:packages/playwright-test",
|
"version": "file:packages/playwright-test",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
|
|
||||||
1
packages/html-reporter/.gitignore
vendored
Normal file
1
packages/html-reporter/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
out-ct/
|
||||||
28
packages/html-reporter/playwright-ct/index.html
Normal file
28
packages/html-reporter/playwright-ct/index.html
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset='UTF-8'>
|
||||||
|
<meta name='color-scheme' content='dark light'>
|
||||||
|
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||||
|
<title>Playwright CT</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id=root></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -14,11 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AutoChip, Chip } from './src/chip';
|
import { AutoChip, Chip } from '../src/chip';
|
||||||
import { HeaderView } from './src/headerView';
|
import { HeaderView } from '../src/headerView';
|
||||||
import { TestCaseView } from './src/testCaseView';
|
import { TestCaseView } from '../src/testCaseView';
|
||||||
import './src/theme.css';
|
import '../src/theme.css';
|
||||||
import { registerComponent } from './test/component';
|
|
||||||
|
import { registerComponent } from '@playwright/ct-react/render';
|
||||||
|
|
||||||
registerComponent('HeaderView', HeaderView);
|
registerComponent('HeaderView', HeaderView);
|
||||||
registerComponent('Chip', Chip);
|
registerComponent('Chip', Chip);
|
||||||
62
packages/html-reporter/playwright-ct/webpack.config.js
Normal file
62
packages/html-reporter/playwright-ct/webpack.config.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||||
|
|
||||||
|
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode,
|
||||||
|
entry: {
|
||||||
|
index: path.join(__dirname, 'index.ts'),
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.js', '.tsx', '.jsx']
|
||||||
|
},
|
||||||
|
devtool: mode === 'production' ? false : 'source-map',
|
||||||
|
output: {
|
||||||
|
globalObject: 'self',
|
||||||
|
filename: '[name].bundle.js',
|
||||||
|
path: path.resolve(__dirname, '..', 'out-ct')
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(j|t)sx?$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
"@babel/preset-typescript",
|
||||||
|
"@babel/preset-react"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ['style-loader', 'css-loader']
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebPackPlugin({
|
||||||
|
title: 'Playwright CT',
|
||||||
|
template: path.join(__dirname, 'index.html'),
|
||||||
|
inject: true,
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
@ -15,10 +15,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
||||||
|
import path from 'path';
|
||||||
|
import url from 'url';
|
||||||
|
|
||||||
const config: PlaywrightTestConfig = {
|
const config: PlaywrightTestConfig = {
|
||||||
testDir: 'src',
|
testDir: 'src',
|
||||||
snapshotDir: 'snapshots',
|
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
retries: process.env.CI ? 2 : 0,
|
retries: process.env.CI ? 2 : 0,
|
||||||
reporter: process.env.CI ? [
|
reporter: process.env.CI ? [
|
||||||
|
|
@ -27,6 +28,7 @@ const config: PlaywrightTestConfig = {
|
||||||
['html', { open: 'on-failure' }]
|
['html', { open: 'on-failure' }]
|
||||||
],
|
],
|
||||||
use: {
|
use: {
|
||||||
|
baseURL: url.pathToFileURL(path.join(__dirname, 'out-ct', 'index.html')).toString(),
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
},
|
},
|
||||||
projects: [
|
projects: [
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { expect, test } from '../test/componentTest';
|
import { expect, test } from '@playwright/ct-react/test';
|
||||||
import { AutoChip, Chip } from './chip';
|
import { AutoChip, Chip } from './chip';
|
||||||
|
|
||||||
test.use({ webpack: require.resolve('../webpack.config.js') });
|
|
||||||
test.use({ viewport: { width: 500, height: 500 } });
|
test.use({ viewport: { width: 500, height: 500 } });
|
||||||
|
|
||||||
test('expand collapse', async ({ mount }) => {
|
test('expand collapse', async ({ mount }) => {
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { test, expect } from '../test/componentTest';
|
import { test, expect } from '@playwright/ct-react/test';
|
||||||
import { HeaderView } from './headerView';
|
import { HeaderView } from './headerView';
|
||||||
|
|
||||||
test.use({ webpack: require.resolve('../webpack.config.js') });
|
|
||||||
test.use({ viewport: { width: 720, height: 200 } });
|
test.use({ viewport: { width: 720, height: 200 } });
|
||||||
|
|
||||||
test('should render counters', async ({ mount }) => {
|
test('should render counters', async ({ mount }) => {
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { test, expect } from '../test/componentTest';
|
import { test, expect } from '@playwright/ct-react/test';
|
||||||
import { TestCaseView } from './testCaseView';
|
import { TestCaseView } from './testCaseView';
|
||||||
import type { TestCase, TestResult } from '../../playwright-test/src/reporters/html';
|
import type { TestCase, TestResult } from '../../playwright-test/src/reporters/html';
|
||||||
|
|
||||||
test.use({ webpack: require.resolve('../webpack.config.js') });
|
|
||||||
test.use({ viewport: { width: 800, height: 600 } });
|
test.use({ viewport: { width: 800, height: 600 } });
|
||||||
|
|
||||||
const result: TestResult = {
|
const result: TestResult = {
|
||||||
|
|
|
||||||
|
|
@ -1,77 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const React = require('react');
|
|
||||||
const ReactDOM = require('react-dom');
|
|
||||||
|
|
||||||
const fillStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkerboardCommon = {
|
|
||||||
...fillStyle,
|
|
||||||
backgroundSize: '50px 50px',
|
|
||||||
backgroundPosition: '0 0, 25px 25px',
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkerboardLight = {
|
|
||||||
...checkerboardCommon,
|
|
||||||
backgroundColor: '#FFF',
|
|
||||||
backgroundImage: `linear-gradient(45deg, #00000008 25%, transparent 25%, transparent 75%, #00000008 75%, #00000008),
|
|
||||||
linear-gradient(45deg, #00000008 25%, transparent 25%, transparent 75%, #00000008 75%, #00000008)`
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkerboardDark = {
|
|
||||||
...checkerboardCommon,
|
|
||||||
backgroundColor: '#000',
|
|
||||||
backgroundImage: `linear-gradient(45deg, #FFFFFF12 25%, transparent 25%, transparent 75%, #FFFFFF12 75%, #FFFFFF12),
|
|
||||||
linear-gradient(45deg, #FFFFFF12 25%, transparent 25%, transparent 75%, #FFFFFF12 75%, #FFFFFF12)`
|
|
||||||
};
|
|
||||||
|
|
||||||
const Component = ({ style, children }) => {
|
|
||||||
const checkerboard = window.matchMedia('(prefers-color-scheme: dark)').matches ? checkerboardDark : checkerboardLight;
|
|
||||||
const bgStyle = { ...checkerboard };
|
|
||||||
const fgStyle = { ...fillStyle, ...style };
|
|
||||||
return React.createElement(
|
|
||||||
React.Fragment, null,
|
|
||||||
React.createElement('div', { style: bgStyle }),
|
|
||||||
React.createElement('div', { style: fgStyle, id: 'pw-root' }, children));
|
|
||||||
};
|
|
||||||
|
|
||||||
const registry = new Map();
|
|
||||||
|
|
||||||
export const registerComponent = (name, componentFunc) => {
|
|
||||||
registry.set(name, componentFunc);
|
|
||||||
};
|
|
||||||
|
|
||||||
function render(component) {
|
|
||||||
const componentFunc = registry.get(component.type) || component.type;
|
|
||||||
return React.createElement(componentFunc, component.props, ...component.children.map(child => {
|
|
||||||
if (typeof child === 'string')
|
|
||||||
return child;
|
|
||||||
return render(child);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
window.__playwright_render = component => {
|
|
||||||
ReactDOM.render(
|
|
||||||
React.createElement(Component, null, render(component)),
|
|
||||||
document.getElementById('root'));
|
|
||||||
};
|
|
||||||
|
|
@ -1,79 +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 * as path from 'path';
|
|
||||||
import { test as baseTest, Locator } from '@playwright/test';
|
|
||||||
|
|
||||||
type Component = {
|
|
||||||
type: string;
|
|
||||||
props: Object;
|
|
||||||
children: Object[];
|
|
||||||
};
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
__playwright_render: (component: Component) => void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestFixtures = {
|
|
||||||
mount: (component: any) => Promise<Locator>;
|
|
||||||
webpack: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const test = baseTest.extend<TestFixtures>({
|
|
||||||
webpack: '',
|
|
||||||
mount: async ({ page, webpack }, use) => {
|
|
||||||
const webpackConfig = require(webpack);
|
|
||||||
const outputPath = webpackConfig.output.path;
|
|
||||||
const filename = webpackConfig.output.filename.replace('[name]', 'playwright');
|
|
||||||
await use(async (component: Component) => {
|
|
||||||
await page.route('http://component/index.html', route => {
|
|
||||||
route.fulfill({
|
|
||||||
body: `<html>
|
|
||||||
<meta name='color-scheme' content='dark light'>
|
|
||||||
<style>html, body { padding: 0; margin: 0; background: #aaa; }</style>
|
|
||||||
<div id='root' style='width: 100%; height: 100%;'></div>
|
|
||||||
</html>`,
|
|
||||||
contentType: 'text/html'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
await page.goto('http://component/index.html');
|
|
||||||
|
|
||||||
await page.addScriptTag({ path: path.resolve(__dirname, outputPath, filename) });
|
|
||||||
|
|
||||||
const props = { ...component.props };
|
|
||||||
for (const [key, value] of Object.entries(props)) {
|
|
||||||
if (typeof value === 'function') {
|
|
||||||
const functionName = '__pw_func_' + key;
|
|
||||||
await page.exposeFunction(functionName, value);
|
|
||||||
(props as any)[key] = functionName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await page.evaluate(v => {
|
|
||||||
const props = v.props;
|
|
||||||
for (const [key, value] of Object.entries(props)) {
|
|
||||||
if (typeof value === 'string' && (value as string).startsWith('__pw_func_'))
|
|
||||||
(props as any)[key] = (window as any)[value];
|
|
||||||
}
|
|
||||||
window.__playwright_render({ ...v, props });
|
|
||||||
}, { ...component, props });
|
|
||||||
return page.locator('#pw-root');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export { expect } from '@playwright/test';
|
|
||||||
|
|
@ -25,7 +25,6 @@ module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
zip: require.resolve('@zip.js/zip.js/dist/zip-no-worker-inflate.min.js'),
|
zip: require.resolve('@zip.js/zip.js/dist/zip-no-worker-inflate.min.js'),
|
||||||
app: path.join(__dirname, 'src', 'index.tsx'),
|
app: path.join(__dirname, 'src', 'index.tsx'),
|
||||||
playwright: path.join(__dirname, 'playwright.components.tsx'),
|
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.ts', '.js', '.tsx', '.jsx']
|
extensions: ['.ts', '.js', '.tsx', '.jsx']
|
||||||
|
|
@ -60,7 +59,6 @@ module.exports = {
|
||||||
title: 'Playwright Test Report',
|
title: 'Playwright Test Report',
|
||||||
template: path.join(__dirname, 'src', 'index.html'),
|
template: path.join(__dirname, 'src', 'index.html'),
|
||||||
inject: true,
|
inject: true,
|
||||||
excludeChunks: ['playwright'],
|
|
||||||
}),
|
}),
|
||||||
new BundleJsPlugin(),
|
new BundleJsPlugin(),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
8
packages/playwright-ct-react/package.json
Normal file
8
packages/playwright-ct-react/package.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "@playwright/ct-react",
|
||||||
|
"private": true,
|
||||||
|
"exports": {
|
||||||
|
"./render": "./render.mjs",
|
||||||
|
"./test": "./test.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
packages/playwright-ct-react/render.d.ts
vendored
Normal file
17
packages/playwright-ct-react/render.d.ts
vendored
Normal file
|
|
@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const registerComponent: (name: string, componentFunc: any) => void;
|
||||||
38
packages/playwright-ct-react/render.mjs
Normal file
38
packages/playwright-ct-react/render.mjs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* 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 React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
|
const registry = new Map();
|
||||||
|
|
||||||
|
export const registerComponent = (name, componentFunc) => {
|
||||||
|
registry.set(name, componentFunc);
|
||||||
|
};
|
||||||
|
|
||||||
|
function render(component) {
|
||||||
|
const componentFunc = registry.get(component.type) || component.type;
|
||||||
|
return React.createElement(componentFunc, component.props, ...component.children.map(child => {
|
||||||
|
if (typeof child === 'string')
|
||||||
|
return child;
|
||||||
|
return render(child);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
window.playwrightMount = component => {
|
||||||
|
ReactDOM.render(render(component), document.getElementById('root'));
|
||||||
|
return '#root';
|
||||||
|
};
|
||||||
34
packages/playwright-ct-react/test.d.ts
vendored
Normal file
34
packages/playwright-ct-react/test.d.ts
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
TestType,
|
||||||
|
PlaywrightTestArgs,
|
||||||
|
PlaywrightTestOptions,
|
||||||
|
PlaywrightWorkerArgs,
|
||||||
|
PlaywrightWorkerOptions,
|
||||||
|
Locator,
|
||||||
|
} from '@playwright/test';
|
||||||
|
|
||||||
|
interface ComponentFixtures {
|
||||||
|
mount(component: JSX.Element): Promise<Locator>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const test: TestType<
|
||||||
|
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
|
||||||
|
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
|
||||||
|
|
||||||
|
export { expect } from '@playwright/test';
|
||||||
30
packages/playwright-ct-react/test.js
Normal file
30
packages/playwright-ct-react/test.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { test: baseTest, expect } = require('@playwright/test');
|
||||||
|
const { mount } = require('@playwright/test/lib/mount');
|
||||||
|
|
||||||
|
const test = baseTest.extend({
|
||||||
|
mount: async ({ page, baseURL }, use) => {
|
||||||
|
await use(async (component, options) => {
|
||||||
|
await page.goto(baseURL);
|
||||||
|
const selector = await mount(page, component, options);
|
||||||
|
return page.locator(selector);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = { test, expect };
|
||||||
8
packages/playwright-ct-svelte/package.json
Normal file
8
packages/playwright-ct-svelte/package.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "@playwright/ct-svelte",
|
||||||
|
"private": true,
|
||||||
|
"exports": {
|
||||||
|
"./render": "./render.mjs",
|
||||||
|
"./test": "./test.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
packages/playwright-ct-svelte/render.d.ts
vendored
Normal file
17
packages/playwright-ct-svelte/render.d.ts
vendored
Normal file
|
|
@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const registerComponent: (name: string, componentFunc: any) => void;
|
||||||
34
packages/playwright-ct-svelte/render.mjs
Normal file
34
packages/playwright-ct-svelte/render.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const registry = new Map();
|
||||||
|
|
||||||
|
export const registerComponent = (name, componentClass) => {
|
||||||
|
registry.set(name, componentClass);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.playwrightMount = component => {
|
||||||
|
const componentCtor = registry.get(component.type);
|
||||||
|
|
||||||
|
const wrapper = new componentCtor({
|
||||||
|
target: document.getElementById('app'),
|
||||||
|
props: component.options.props,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [key, listener] of Object.entries(component.options.on || {}))
|
||||||
|
wrapper.$on(key, event => listener(event.detail));
|
||||||
|
return '#app';
|
||||||
|
};
|
||||||
38
packages/playwright-ct-svelte/test.d.ts
vendored
Normal file
38
packages/playwright-ct-svelte/test.d.ts
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
TestType,
|
||||||
|
PlaywrightTestArgs,
|
||||||
|
PlaywrightTestOptions,
|
||||||
|
PlaywrightWorkerArgs,
|
||||||
|
PlaywrightWorkerOptions,
|
||||||
|
Locator,
|
||||||
|
} from '@playwright/test';
|
||||||
|
|
||||||
|
interface ComponentFixtures {
|
||||||
|
mount(component: any, options?: {
|
||||||
|
props?: { [key: string]: any },
|
||||||
|
slots?: { [key: string]: any },
|
||||||
|
on?: { [key: string]: Function },
|
||||||
|
}): Promise<Locator>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const test: TestType<
|
||||||
|
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
|
||||||
|
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
|
||||||
|
|
||||||
|
export { expect } from '@playwright/test';
|
||||||
30
packages/playwright-ct-svelte/test.js
Normal file
30
packages/playwright-ct-svelte/test.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { test: baseTest, expect } = require('@playwright/test');
|
||||||
|
const { mount } = require('@playwright/test/lib/mount');
|
||||||
|
|
||||||
|
const test = baseTest.extend({
|
||||||
|
mount: async ({ page, baseURL }, use) => {
|
||||||
|
await use(async (component, options) => {
|
||||||
|
await page.goto(baseURL);
|
||||||
|
const selector = await mount(page, component, options);
|
||||||
|
return page.locator(selector);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = { test, expect };
|
||||||
8
packages/playwright-ct-vue/package.json
Normal file
8
packages/playwright-ct-vue/package.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "@playwright/ct-vue",
|
||||||
|
"private": true,
|
||||||
|
"exports": {
|
||||||
|
"./render": "./render.mjs",
|
||||||
|
"./test": "./test.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
18
packages/playwright-ct-vue/render.d.ts
vendored
Normal file
18
packages/playwright-ct-vue/render.d.ts
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const initVueTest: (vue: any) => void;
|
||||||
|
export const registerComponent: (name: string, componentFunc: any) => void;
|
||||||
113
packages/playwright-ct-vue/render.mjs
Normal file
113
packages/playwright-ct-vue/render.mjs
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* 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 { createApp, setDevtoolsHook, h } from 'vue';
|
||||||
|
|
||||||
|
const registry = new Map();
|
||||||
|
let instance = { createApp, setDevtoolsHook, h };
|
||||||
|
|
||||||
|
export const initVueTest = vue => {
|
||||||
|
instance = vue;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const registerComponent = (name, vueComponent) => {
|
||||||
|
registry.set(name, vueComponent);
|
||||||
|
};
|
||||||
|
|
||||||
|
const allListeners = [];
|
||||||
|
|
||||||
|
function render(component) {
|
||||||
|
if (typeof component === 'string')
|
||||||
|
return component;
|
||||||
|
const componentFunc = registry.get(component.type) || component.type;
|
||||||
|
|
||||||
|
const children = [];
|
||||||
|
const slots = {};
|
||||||
|
const listeners = {};
|
||||||
|
let props = {};
|
||||||
|
|
||||||
|
if (component.kind === 'jsx') {
|
||||||
|
for (const child of component.children || []) {
|
||||||
|
if (child.type === 'template') {
|
||||||
|
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
||||||
|
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
||||||
|
slots[slot] = child.children.map(render);
|
||||||
|
} else {
|
||||||
|
children.push(render(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(component.props)) {
|
||||||
|
if (key.startsWith('v-on:'))
|
||||||
|
listeners[key.substring('v-on:'.length)] = value;
|
||||||
|
else
|
||||||
|
props[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.kind === 'object') {
|
||||||
|
// Vue test util syntax.
|
||||||
|
for (const [key, value] of Object.entries(component.options.slots || {})) {
|
||||||
|
if (key === 'default')
|
||||||
|
children.push(value);
|
||||||
|
else
|
||||||
|
slots[key] = value;
|
||||||
|
}
|
||||||
|
props = component.options.props || {};
|
||||||
|
for (const [key, value] of Object.entries(component.options.on || {}))
|
||||||
|
listeners[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastArg;
|
||||||
|
if (Object.entries(slots).length) {
|
||||||
|
lastArg = slots;
|
||||||
|
if (children.length)
|
||||||
|
slots.default = children;
|
||||||
|
} else if (children.length) {
|
||||||
|
lastArg = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapper = instance.h(componentFunc, props, lastArg);
|
||||||
|
allListeners.push([wrapper, listeners]);
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDevTools() {
|
||||||
|
return {
|
||||||
|
emit(eventType, ...payload) {
|
||||||
|
if (eventType === 'component:emit') {
|
||||||
|
const [, componentVM, event, eventArgs] = payload;
|
||||||
|
for (const [wrapper, listeners] of allListeners) {
|
||||||
|
if (wrapper.component !== componentVM)
|
||||||
|
continue;
|
||||||
|
const listener = listeners[event];
|
||||||
|
if (!listener)
|
||||||
|
return;
|
||||||
|
listener(...eventArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.playwrightMount = async component => {
|
||||||
|
const app = instance.createApp({
|
||||||
|
render: () => render(component)
|
||||||
|
});
|
||||||
|
instance.setDevtoolsHook(createDevTools(), {});
|
||||||
|
app.mount('#app');
|
||||||
|
return '#app';
|
||||||
|
};
|
||||||
39
packages/playwright-ct-vue/test.d.ts
vendored
Normal file
39
packages/playwright-ct-vue/test.d.ts
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
TestType,
|
||||||
|
PlaywrightTestArgs,
|
||||||
|
PlaywrightTestOptions,
|
||||||
|
PlaywrightWorkerArgs,
|
||||||
|
PlaywrightWorkerOptions,
|
||||||
|
Locator,
|
||||||
|
} from '@playwright/test';
|
||||||
|
|
||||||
|
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 const test: TestType<
|
||||||
|
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
|
||||||
|
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
|
||||||
|
|
||||||
|
export { expect } from '@playwright/test';
|
||||||
30
packages/playwright-ct-vue/test.js
Normal file
30
packages/playwright-ct-vue/test.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { test: baseTest, expect } = require('@playwright/test');
|
||||||
|
const { mount } = require('@playwright/test/lib/mount');
|
||||||
|
|
||||||
|
const test = baseTest.extend({
|
||||||
|
mount: async ({ page, baseURL }, use) => {
|
||||||
|
await use(async (component, options) => {
|
||||||
|
await page.goto(baseURL);
|
||||||
|
const selector = await mount(page, component, options);
|
||||||
|
return page.locator(selector);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = { test, expect };
|
||||||
1
packages/playwright-test/index.d.ts
vendored
1
packages/playwright-test/index.d.ts
vendored
|
|
@ -17,4 +17,3 @@
|
||||||
export * from 'playwright-core';
|
export * from 'playwright-core';
|
||||||
export * from './types/test';
|
export * from './types/test';
|
||||||
export { default } from './types/test';
|
export { default } from './types/test';
|
||||||
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
"./package.json": "./package.json",
|
"./package.json": "./package.json",
|
||||||
"./lib/cli": "./lib/cli.js",
|
"./lib/cli": "./lib/cli.js",
|
||||||
"./lib/experimentalLoader": "./lib/experimentalLoader.js",
|
"./lib/experimentalLoader": "./lib/experimentalLoader.js",
|
||||||
|
"./lib/mount": "./lib/mount.js",
|
||||||
"./reporter": "./reporter.js"
|
"./reporter": "./reporter.js"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
68
packages/playwright-test/src/mount.ts
Normal file
68
packages/playwright-test/src/mount.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* 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 { Page } from '@playwright/test';
|
||||||
|
import { createGuid } from 'playwright-core/lib/utils/utils';
|
||||||
|
|
||||||
|
export async function mount(page: Page, jsxOrType: any, options: any): Promise<string> {
|
||||||
|
let component;
|
||||||
|
if (typeof jsxOrType === 'string')
|
||||||
|
component = { kind: 'object', type: jsxOrType, options };
|
||||||
|
else
|
||||||
|
component = jsxOrType;
|
||||||
|
|
||||||
|
const callbacks: Function[] = [];
|
||||||
|
wrapFunctions(component, page, callbacks);
|
||||||
|
|
||||||
|
|
||||||
|
const dispatchMethod = `__pw_dispatch_${createGuid}`;
|
||||||
|
|
||||||
|
await page.exposeFunction(dispatchMethod, (ordinal: number, args: any[]) => {
|
||||||
|
callbacks[ordinal](...args);
|
||||||
|
});
|
||||||
|
|
||||||
|
const selector = await page.evaluate(async ({ component, dispatchMethod }) => {
|
||||||
|
const unwrapFunctions = (object: any) => {
|
||||||
|
for (const [key, value] of Object.entries(object)) {
|
||||||
|
if (typeof value === 'string' && (value as string).startsWith('__pw_func_')) {
|
||||||
|
const ordinal = +value.substring('__pw_func_'.length);
|
||||||
|
object[key] = (...args: any[]) => {
|
||||||
|
(window as any)[dispatchMethod](ordinal, args);
|
||||||
|
};
|
||||||
|
} else if (typeof value === 'object' && value) {
|
||||||
|
unwrapFunctions(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
unwrapFunctions(component);
|
||||||
|
return await (window as any).playwrightMount(component);
|
||||||
|
}, { component, dispatchMethod });
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapFunctions(object: any, page: Page, callbacks: Function[]) {
|
||||||
|
for (const [key, value] of Object.entries(object)) {
|
||||||
|
const type = typeof value;
|
||||||
|
if (type === 'function') {
|
||||||
|
const functionName = '__pw_func_' + callbacks.length;
|
||||||
|
callbacks.push(value as Function);
|
||||||
|
object[key] = functionName;
|
||||||
|
} else if (type === 'object' && value) {
|
||||||
|
wrapFunctions(value, page, callbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ import type { Location } from './types';
|
||||||
import { tsConfigLoader, TsConfigLoaderResult } from './third_party/tsconfig-loader';
|
import { tsConfigLoader, TsConfigLoaderResult } from './third_party/tsconfig-loader';
|
||||||
import Module from 'module';
|
import Module from 'module';
|
||||||
|
|
||||||
const version = 7;
|
const version = 8;
|
||||||
const cacheDir = process.env.PWTEST_CACHE_DIR || path.join(os.tmpdir(), 'playwright-transform-cache');
|
const cacheDir = process.env.PWTEST_CACHE_DIR || path.join(os.tmpdir(), 'playwright-transform-cache');
|
||||||
const sourceMaps: Map<string, string> = new Map();
|
const sourceMaps: Map<string, string> = new Map();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { types as t } from '@babel/core';
|
import { types as t, NodePath } from '@babel/core';
|
||||||
import { declare } from '@babel/helper-plugin-utils';
|
import { declare } from '@babel/helper-plugin-utils';
|
||||||
|
|
||||||
export default declare(api => {
|
export default declare(api => {
|
||||||
|
|
@ -23,6 +23,44 @@ export default declare(api => {
|
||||||
return {
|
return {
|
||||||
name: 'playwright-debug-transform',
|
name: 'playwright-debug-transform',
|
||||||
visitor: {
|
visitor: {
|
||||||
|
Program(path) {
|
||||||
|
path.setData('pw-components', new Map());
|
||||||
|
},
|
||||||
|
|
||||||
|
ImportDeclaration(path) {
|
||||||
|
// Non-JSX transform, replace
|
||||||
|
// import Button from './ButtonVue.vue'
|
||||||
|
// import { Card as MyCard } from './Card.vue'
|
||||||
|
// with
|
||||||
|
// const Button 'Button', MyCard = 'Card';
|
||||||
|
const importNode = path.node;
|
||||||
|
if (!t.isStringLiteral(importNode.source)) {
|
||||||
|
flushConst(path, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!importNode.source.value.endsWith('.vue') && !importNode.source.value.endsWith('.svelte')) {
|
||||||
|
flushConst(path, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const components = path.parentPath.getData('pw-components');
|
||||||
|
for (const specifier of importNode.specifiers) {
|
||||||
|
if (t.isImportDefaultSpecifier(specifier)) {
|
||||||
|
components.set(specifier.local.name, specifier.local.name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (t.isImportSpecifier(specifier)) {
|
||||||
|
if (t.isIdentifier(specifier.imported))
|
||||||
|
components.set(specifier.local.name, specifier.imported.name);
|
||||||
|
else
|
||||||
|
components.set(specifier.local.name, specifier.imported.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flushConst(path, false);
|
||||||
|
},
|
||||||
|
|
||||||
JSXElement(path) {
|
JSXElement(path) {
|
||||||
const jsxElement = path.node;
|
const jsxElement = path.node;
|
||||||
const jsxName = jsxElement.openingElement.name;
|
const jsxName = jsxElement.openingElement.name;
|
||||||
|
|
@ -34,9 +72,17 @@ export default declare(api => {
|
||||||
|
|
||||||
for (const jsxAttribute of jsxElement.openingElement.attributes) {
|
for (const jsxAttribute of jsxElement.openingElement.attributes) {
|
||||||
if (t.isJSXAttribute(jsxAttribute)) {
|
if (t.isJSXAttribute(jsxAttribute)) {
|
||||||
if (!t.isJSXIdentifier(jsxAttribute.name))
|
let namespace: t.JSXIdentifier | undefined;
|
||||||
|
let name: t.JSXIdentifier | undefined;
|
||||||
|
if (t.isJSXNamespacedName(jsxAttribute.name)) {
|
||||||
|
namespace = jsxAttribute.name.namespace;
|
||||||
|
name = jsxAttribute.name.name;
|
||||||
|
} else if (t.isJSXIdentifier(jsxAttribute.name)) {
|
||||||
|
name = jsxAttribute.name;
|
||||||
|
}
|
||||||
|
if (!name)
|
||||||
continue;
|
continue;
|
||||||
const attrName = jsxAttribute.name.name;
|
const attrName = (namespace ? namespace.name + ':' : '') + name.name;
|
||||||
if (t.isStringLiteral(jsxAttribute.value))
|
if (t.isStringLiteral(jsxAttribute.value))
|
||||||
props.push(t.objectProperty(t.stringLiteral(attrName), jsxAttribute.value));
|
props.push(t.objectProperty(t.stringLiteral(attrName), jsxAttribute.value));
|
||||||
else if (t.isJSXExpressionContainer(jsxAttribute.value) && t.isExpression(jsxAttribute.value.expression))
|
else if (t.isJSXExpressionContainer(jsxAttribute.value) && t.isExpression(jsxAttribute.value.expression))
|
||||||
|
|
@ -58,10 +104,10 @@ export default declare(api => {
|
||||||
children.push(child.expression);
|
children.push(child.expression);
|
||||||
else if (t.isJSXSpreadChild(child))
|
else if (t.isJSXSpreadChild(child))
|
||||||
children.push(t.spreadElement(child.expression));
|
children.push(t.spreadElement(child.expression));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path.replaceWith(t.objectExpression([
|
path.replaceWith(t.objectExpression([
|
||||||
|
t.objectProperty(t.identifier('kind'), t.stringLiteral('jsx')),
|
||||||
t.objectProperty(t.identifier('type'), t.stringLiteral(name)),
|
t.objectProperty(t.identifier('type'), t.stringLiteral(name)),
|
||||||
t.objectProperty(t.identifier('props'), t.objectExpression(props)),
|
t.objectProperty(t.identifier('props'), t.objectExpression(props)),
|
||||||
t.objectProperty(t.identifier('children'), t.arrayExpression(children)),
|
t.objectProperty(t.identifier('children'), t.arrayExpression(children)),
|
||||||
|
|
@ -70,3 +116,26 @@ export default declare(api => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function flushConst(importPath: NodePath<t.ImportDeclaration>, keepPath: boolean) {
|
||||||
|
const importNode = importPath.node;
|
||||||
|
const importNodes = (importPath.parentPath.node as t.Program).body.filter(i => t.isImportDeclaration(i));
|
||||||
|
const isLast = importNodes.indexOf(importNode) === importNodes.length - 1;
|
||||||
|
if (!isLast) {
|
||||||
|
if (!keepPath)
|
||||||
|
importPath.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const components = importPath.parentPath.getData('pw-components');
|
||||||
|
if (!components.size)
|
||||||
|
return;
|
||||||
|
const variables = [];
|
||||||
|
for (const [key, value] of components)
|
||||||
|
variables.push(t.variableDeclarator(t.identifier(key), t.stringLiteral(value)));
|
||||||
|
importPath.skip();
|
||||||
|
if (keepPath)
|
||||||
|
importPath.replaceWithMultiple([importNode, t.variableDeclaration('const', variables)]);
|
||||||
|
else
|
||||||
|
importPath.replaceWith(t.variableDeclaration('const', variables));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ const webPackFiles = [
|
||||||
'packages/playwright-core/src/web/traceViewer/webpack-sw.config.js',
|
'packages/playwright-core/src/web/traceViewer/webpack-sw.config.js',
|
||||||
'packages/playwright-core/src/web/recorder/webpack.config.js',
|
'packages/playwright-core/src/web/recorder/webpack.config.js',
|
||||||
'packages/html-reporter/webpack.config.js',
|
'packages/html-reporter/webpack.config.js',
|
||||||
|
'packages/html-reporter/playwright-ct/webpack.config.js',
|
||||||
];
|
];
|
||||||
for (const file of webPackFiles) {
|
for (const file of webPackFiles) {
|
||||||
steps.push({
|
steps.push({
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,21 @@ const workspace = new Workspace(ROOT_PATH, [
|
||||||
path: path.join(ROOT_PATH, 'packages', 'html-reporter'),
|
path: path.join(ROOT_PATH, 'packages', 'html-reporter'),
|
||||||
files: [],
|
files: [],
|
||||||
}),
|
}),
|
||||||
|
new PWPackage({
|
||||||
|
name: '@playwright/ct-react',
|
||||||
|
path: path.join(ROOT_PATH, 'packages', 'playwright-ct-react'),
|
||||||
|
files: [],
|
||||||
|
}),
|
||||||
|
new PWPackage({
|
||||||
|
name: '@playwright/ct-svelte',
|
||||||
|
path: path.join(ROOT_PATH, 'packages', 'playwright-ct-svelte'),
|
||||||
|
files: [],
|
||||||
|
}),
|
||||||
|
new PWPackage({
|
||||||
|
name: '@playwright/ct-vue',
|
||||||
|
path: path.join(ROOT_PATH, 'packages', 'playwright-ct-vue'),
|
||||||
|
files: [],
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue