feat(ct): support Vue2 (#14600)
This commit is contained in:
parent
94a0d669b6
commit
74b846270b
2060
package-lock.json
generated
2060
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,13 +13,20 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
// This file is injected into the registry as text, no dependencies are allowed.
|
// This file is injected into the registry as text, no dependencies are allowed.
|
||||||
|
|
||||||
import { createApp, setDevtoolsHook, h } from 'vue';
|
import { createApp, setDevtoolsHook, h } from 'vue';
|
||||||
|
|
||||||
|
/** @typedef {import('../playwright-test/types/component').Component} Component */
|
||||||
|
|
||||||
|
/** @type { Map<string, import('vue').Component> } */
|
||||||
const registry = new Map();
|
const registry = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{[key: string]: import('vue').Component}} components
|
||||||
|
*/
|
||||||
export function register(components) {
|
export function register(components) {
|
||||||
for (const [name, value] of Object.entries(components))
|
for (const [name, value] of Object.entries(components))
|
||||||
registry.set(name, value);
|
registry.set(name, value);
|
||||||
|
|
@ -27,10 +34,25 @@ export function register(components) {
|
||||||
|
|
||||||
const allListeners = [];
|
const allListeners = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Component | string} child
|
||||||
|
* @returns {import('vue').VNode | string}
|
||||||
|
*/
|
||||||
|
function renderChild(child) {
|
||||||
|
return typeof child === 'string' ? child : render(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Component} component
|
||||||
|
* @returns {import('vue').VNode}
|
||||||
|
*/
|
||||||
function render(component) {
|
function render(component) {
|
||||||
if (typeof component === 'string')
|
if (typeof component === 'string')
|
||||||
return component;
|
return component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import('vue').Component | string | undefined}
|
||||||
|
*/
|
||||||
let componentFunc = registry.get(component.type);
|
let componentFunc = registry.get(component.type);
|
||||||
if (!componentFunc) {
|
if (!componentFunc) {
|
||||||
// Lookup by shorthand.
|
// Lookup by shorthand.
|
||||||
|
|
@ -48,20 +70,25 @@ function render(component) {
|
||||||
componentFunc = componentFunc || component.type;
|
componentFunc = componentFunc || component.type;
|
||||||
|
|
||||||
const isVueComponent = componentFunc !== component.type;
|
const isVueComponent = componentFunc !== component.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import('vue').VNode | string)[]}
|
||||||
|
*/
|
||||||
const children = [];
|
const children = [];
|
||||||
|
/** @type {{[key: string]: any}} */
|
||||||
const slots = {};
|
const slots = {};
|
||||||
const listeners = {};
|
const listeners = {};
|
||||||
|
/** @type {{[key: string]: any}} */
|
||||||
let props = {};
|
let props = {};
|
||||||
|
|
||||||
if (component.kind === 'jsx') {
|
if (component.kind === 'jsx') {
|
||||||
for (const child of component.children || []) {
|
for (const child of component.children || []) {
|
||||||
if (child.type === 'template') {
|
if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') {
|
||||||
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
||||||
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
||||||
slots[slot] = child.children.map(render);
|
slots[slot] = child.children.map(renderChild);
|
||||||
} else {
|
} else {
|
||||||
children.push(render(child));
|
children.push(renderChild(child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,11 +127,15 @@ function render(component) {
|
||||||
lastArg = children;
|
lastArg = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
const wrapper = h(componentFunc, props, lastArg);
|
const wrapper = h(componentFunc, props, lastArg);
|
||||||
allListeners.push([wrapper, listeners]);
|
allListeners.push([wrapper, listeners]);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
function createDevTools() {
|
function createDevTools() {
|
||||||
return {
|
return {
|
||||||
emit(eventType, ...payload) {
|
emit(eventType, ...payload) {
|
||||||
|
|
@ -123,7 +154,7 @@ function createDevTools() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
window.playwrightMount = async component => {
|
/** @type {any} */ (window).playwrightMount = /** @param {Component} component */ async component => {
|
||||||
if (!document.getElementById('root')) {
|
if (!document.getElementById('root')) {
|
||||||
const rootElement = document.createElement('div');
|
const rootElement = document.createElement('div');
|
||||||
rootElement.id = 'root';
|
rootElement.id = 'root';
|
||||||
|
|
|
||||||
9
packages/playwright-ct-vue2/.npmignore
Normal file
9
packages/playwright-ct-vue2/.npmignore
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
**/*
|
||||||
|
|
||||||
|
!README.md
|
||||||
|
!LICENSE
|
||||||
|
!register.d.ts
|
||||||
|
!register.mjs
|
||||||
|
!registerSource.mjs
|
||||||
|
!index.d.ts
|
||||||
|
!index.js
|
||||||
3
packages/playwright-ct-vue2/README.md
Normal file
3
packages/playwright-ct-vue2/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
> **BEWARE** This package is EXPERIMENTAL and does not respect semver.
|
||||||
|
|
||||||
|
Read more at https://playwright.dev/docs/test-components
|
||||||
50
packages/playwright-ct-vue2/index.d.ts
vendored
Normal file
50
packages/playwright-ct-vue2/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
PlaywrightTestConfig as BasePlaywrightTestConfig,
|
||||||
|
PlaywrightTestOptions,
|
||||||
|
PlaywrightWorkerArgs,
|
||||||
|
PlaywrightWorkerOptions,
|
||||||
|
Locator,
|
||||||
|
} from '@playwright/test';
|
||||||
|
import type { InlineConfig } from 'vite';
|
||||||
|
|
||||||
|
export type PlaywrightTestConfig = Omit<BasePlaywrightTestConfig, 'use'> & {
|
||||||
|
use?: BasePlaywrightTestConfig['use'] & {
|
||||||
|
ctPort?: number,
|
||||||
|
ctTemplateDir?: string,
|
||||||
|
ctCacheDir?: string,
|
||||||
|
ctViteConfig?: 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 const test: TestType<
|
||||||
|
PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures,
|
||||||
|
PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
|
||||||
|
|
||||||
|
export { expect, devices } from '@playwright/test';
|
||||||
31
packages/playwright-ct-vue2/index.js
Normal file
31
packages/playwright-ct-vue2/index.js
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* 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, devices, _addRunnerPlugin } = require('@playwright/test');
|
||||||
|
const { fixtures } = require('@playwright/test/lib/mount');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
_addRunnerPlugin(() => {
|
||||||
|
// Only fetch upon request to avoid resolution in workers.
|
||||||
|
const { createPlugin } = require('@playwright/test/lib/plugins/vitePlugin');
|
||||||
|
return createPlugin(
|
||||||
|
path.join(__dirname, 'registerSource.mjs'),
|
||||||
|
() => require('vite-plugin-vue2').createVuePlugin());
|
||||||
|
});
|
||||||
|
|
||||||
|
const test = baseTest.extend(fixtures);
|
||||||
|
|
||||||
|
module.exports = { test, expect, devices };
|
||||||
32
packages/playwright-ct-vue2/package.json
Normal file
32
packages/playwright-ct-vue2/package.json
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"name": "@playwright/experimental-ct-vue2",
|
||||||
|
"version": "1.23.0-next",
|
||||||
|
"description": "Playwright Component Testing for Vue2",
|
||||||
|
"repository": "github:Microsoft/playwright",
|
||||||
|
"homepage": "https://playwright.dev",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"name": "Microsoft Corporation"
|
||||||
|
},
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
|
"default": "./index.js"
|
||||||
|
},
|
||||||
|
"./register": {
|
||||||
|
"types": "./register.d.ts",
|
||||||
|
"default": "./register.mjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@playwright/test": "1.23.0-next",
|
||||||
|
"vite": "^2.9.5",
|
||||||
|
"vite-plugin-vue2": "^2.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vue": "^2.6.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
packages/playwright-ct-vue2/register.d.ts
vendored
Normal file
24
packages/playwright-ct-vue2/register.d.ts
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* 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 default function register(
|
||||||
|
components: { [key: string]: any },
|
||||||
|
options?: {
|
||||||
|
createApp: any,
|
||||||
|
setDevtoolsHook: any,
|
||||||
|
h: any,
|
||||||
|
}
|
||||||
|
): void
|
||||||
21
packages/playwright-ct-vue2/register.mjs
Normal file
21
packages/playwright-ct-vue2/register.mjs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* 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 { register } from './registerSource.mjs';
|
||||||
|
|
||||||
|
export default components => {
|
||||||
|
register(components);
|
||||||
|
};
|
||||||
148
packages/playwright-ct-vue2/registerSource.mjs
Normal file
148
packages/playwright-ct-vue2/registerSource.mjs
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
// This file is injected into the registry as text, no dependencies are allowed.
|
||||||
|
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
/** @typedef {import('../playwright-test/types/component').Component} Component */
|
||||||
|
|
||||||
|
/** @type { Map<string, import('vue').Component> } */
|
||||||
|
const registry = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{[key: string]: import('vue').Component}} components
|
||||||
|
*/
|
||||||
|
export function register(components) {
|
||||||
|
for (const [name, value] of Object.entries(components))
|
||||||
|
registry.set(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Component | string} child
|
||||||
|
* @param {import('vue').CreateElement} h
|
||||||
|
* @returns {import('vue').VNode | string}
|
||||||
|
*/
|
||||||
|
function renderChild(child, h) {
|
||||||
|
return typeof child === 'string' ? child : render(child, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Component} component
|
||||||
|
* @param {import('vue').CreateElement} h
|
||||||
|
* @returns {import('vue').VNode}
|
||||||
|
*/
|
||||||
|
function render(component, h) {
|
||||||
|
/**
|
||||||
|
* @type {import('vue').Component | string | undefined}
|
||||||
|
*/
|
||||||
|
let componentFunc = registry.get(component.type);
|
||||||
|
if (!componentFunc) {
|
||||||
|
// Lookup by shorthand.
|
||||||
|
for (const [name, value] of registry) {
|
||||||
|
if (component.type.endsWith(`_${name}_vue`)) {
|
||||||
|
componentFunc = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!componentFunc && component.type[0].toUpperCase() === component.type[0])
|
||||||
|
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`);
|
||||||
|
|
||||||
|
componentFunc = componentFunc || component.type;
|
||||||
|
|
||||||
|
const isVueComponent = componentFunc !== component.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import('vue').VNode | string)[]}
|
||||||
|
*/
|
||||||
|
const children = [];
|
||||||
|
|
||||||
|
/** @type {import('vue').VNodeData} */
|
||||||
|
const nodeData = {};
|
||||||
|
nodeData.attrs = {};
|
||||||
|
nodeData.props = {};
|
||||||
|
nodeData.scopedSlots = {};
|
||||||
|
nodeData.on = {};
|
||||||
|
|
||||||
|
if (component.kind === 'jsx') {
|
||||||
|
for (const child of component.children || []) {
|
||||||
|
if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') {
|
||||||
|
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
||||||
|
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
||||||
|
nodeData.scopedSlots[slot] = () => child.children.map(c => renderChild(c, h));
|
||||||
|
} else {
|
||||||
|
children.push(renderChild(child, h));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(component.props)) {
|
||||||
|
if (key.startsWith('v-on:')) {
|
||||||
|
const event = key.substring('v-on:'.length);
|
||||||
|
nodeData.on[event] = value;
|
||||||
|
} else {
|
||||||
|
if (isVueComponent)
|
||||||
|
nodeData.props[key] = value;
|
||||||
|
else
|
||||||
|
nodeData.attrs[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.kind === 'object') {
|
||||||
|
// Vue test util syntax.
|
||||||
|
const options = component.options || {};
|
||||||
|
for (const [key, value] of Object.entries(options.slots || {})) {
|
||||||
|
const list = (Array.isArray(value) ? value : [value]).map(v => renderChild(v, h));
|
||||||
|
if (key === 'default')
|
||||||
|
children.push(...list);
|
||||||
|
else
|
||||||
|
nodeData.scopedSlots[key] = () => list;
|
||||||
|
}
|
||||||
|
nodeData.props = options.props || {};
|
||||||
|
for (const [key, value] of Object.entries(options.on || {}))
|
||||||
|
nodeData.on[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {(string|import('vue').VNode)[] | undefined} */
|
||||||
|
let lastArg;
|
||||||
|
if (Object.entries(nodeData.scopedSlots).length) {
|
||||||
|
if (children.length)
|
||||||
|
nodeData.scopedSlots.default = () => children;
|
||||||
|
} else if (children.length) {
|
||||||
|
lastArg = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapper = h(componentFunc, nodeData, lastArg);
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {any} */ (window).playwrightMount = /** @param {Component} component */ async component => {
|
||||||
|
let rootElement = document.getElementById('root');
|
||||||
|
if (!rootElement) {
|
||||||
|
rootElement = document.createElement('div');
|
||||||
|
rootElement.id = 'root';
|
||||||
|
document.body.append(rootElement);
|
||||||
|
}
|
||||||
|
const mounted = new Vue({
|
||||||
|
render: h => render(component, h),
|
||||||
|
}).$mount();
|
||||||
|
rootElement.appendChild(mounted.$el);
|
||||||
|
return '#root > *';
|
||||||
|
};
|
||||||
|
|
@ -23,11 +23,11 @@ import { parse, traverse, types as t } from '../babelBundle';
|
||||||
import type { ComponentInfo } from '../tsxTransform';
|
import type { ComponentInfo } from '../tsxTransform';
|
||||||
import { collectComponentUsages, componentInfo } from '../tsxTransform';
|
import { collectComponentUsages, componentInfo } from '../tsxTransform';
|
||||||
import type { FullConfig } from '../types';
|
import type { FullConfig } from '../types';
|
||||||
import { assert } from 'playwright-core/lib/utils';
|
import { assert, calculateSha1 } from 'playwright-core/lib/utils';
|
||||||
import type { AddressInfo } from 'net';
|
import type { AddressInfo } from 'net';
|
||||||
|
|
||||||
let previewServer: PreviewServer;
|
let previewServer: PreviewServer;
|
||||||
const VERSION = 3;
|
const VERSION = 4;
|
||||||
|
|
||||||
type CtConfig = {
|
type CtConfig = {
|
||||||
ctPort?: number;
|
ctPort?: number;
|
||||||
|
|
@ -58,13 +58,19 @@ export function createPlugin(
|
||||||
const buildInfoFile = path.join(outDir, 'metainfo.json');
|
const buildInfoFile = path.join(outDir, 'metainfo.json');
|
||||||
let buildExists = false;
|
let buildExists = false;
|
||||||
let buildInfo: BuildInfo;
|
let buildInfo: BuildInfo;
|
||||||
|
|
||||||
|
const registerSource = await fs.promises.readFile(registerSourceFile, 'utf-8');
|
||||||
|
const registerSourceHash = calculateSha1(registerSource);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
buildInfo = JSON.parse(await fs.promises.readFile(buildInfoFile, 'utf-8')) as BuildInfo;
|
buildInfo = JSON.parse(await fs.promises.readFile(buildInfoFile, 'utf-8')) as BuildInfo;
|
||||||
assert(buildInfo.version === VERSION);
|
assert(buildInfo.version === VERSION);
|
||||||
|
assert(buildInfo.registerSourceHash === registerSourceHash);
|
||||||
buildExists = true;
|
buildExists = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
buildInfo = {
|
buildInfo = {
|
||||||
version: VERSION,
|
version: VERSION,
|
||||||
|
registerSourceHash,
|
||||||
components: [],
|
components: [],
|
||||||
tests: {},
|
tests: {},
|
||||||
sources: {},
|
sources: {},
|
||||||
|
|
@ -106,7 +112,6 @@ export function createPlugin(
|
||||||
viteConfig.plugins = viteConfig.plugins || [
|
viteConfig.plugins = viteConfig.plugins || [
|
||||||
frameworkPluginFactory()
|
frameworkPluginFactory()
|
||||||
];
|
];
|
||||||
const registerSource = await fs.promises.readFile(registerSourceFile, 'utf-8');
|
|
||||||
viteConfig.plugins.push(vitePlugin(registerSource, relativeTemplateDir, buildInfo, componentRegistry));
|
viteConfig.plugins.push(vitePlugin(registerSource, relativeTemplateDir, buildInfo, componentRegistry));
|
||||||
viteConfig.configFile = viteConfig.configFile || false;
|
viteConfig.configFile = viteConfig.configFile || false;
|
||||||
viteConfig.define = viteConfig.define || {};
|
viteConfig.define = viteConfig.define || {};
|
||||||
|
|
@ -149,6 +154,7 @@ export function createPlugin(
|
||||||
|
|
||||||
type BuildInfo = {
|
type BuildInfo = {
|
||||||
version: number,
|
version: number,
|
||||||
|
registerSourceHash: string,
|
||||||
sources: {
|
sources: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
|
|
|
||||||
34
packages/playwright-test/types/component.d.ts
vendored
Normal file
34
packages/playwright-test/types/component.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type JsxComponent = {
|
||||||
|
kind: 'jsx',
|
||||||
|
type: string,
|
||||||
|
props: {[key: string]: any},
|
||||||
|
children: (Component | string)[],
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ObjectComponent = {
|
||||||
|
kind: 'object',
|
||||||
|
type: string,
|
||||||
|
options?: {
|
||||||
|
props?: { [key: string]: any },
|
||||||
|
slots?: { [key: string]: any },
|
||||||
|
on?: { [key: string]: Function },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Component = JsxComponent | ObjectComponent;
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"vite": "^2.8.0"
|
"vite": "^2.8.0"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-react": "0.0.1",
|
"@playwright/experimental-ct-react": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
"typescript": "^4.6.2"
|
"typescript": "^4.6.2"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-react": "0.0.1",
|
"@playwright/experimental-ct-react": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
"svelte": "^3.44.0"
|
"svelte": "^3.44.0"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-svelte": "0.0.1",
|
"@playwright/experimental-ct-svelte": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
"vite": "^2.8.0"
|
"vite": "^2.8.0"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-svelte": "0.0.1",
|
"@playwright/experimental-ct-svelte": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
"svelte": "^3.0.0"
|
"svelte": "^3.0.0"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-svelte": "0.0.1",
|
"@playwright/experimental-ct-svelte": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sirv-cli": "^2.0.0"
|
"sirv-cli": "^2.0.0"
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
"eslint-plugin-vue": "^8.0.3"
|
"eslint-plugin-vue": "^8.0.3"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-vue": "0.0.1",
|
"@playwright/experimental-ct-vue": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"vite": "^2.8.4"
|
"vite": "^2.8.4"
|
||||||
},
|
},
|
||||||
"@standaloneDevDependencies": {
|
"@standaloneDevDependencies": {
|
||||||
"@playwright/experimental-ct-vue": "0.0.1",
|
"@playwright/experimental-ct-vue": "^1.22.2",
|
||||||
"@playwright/test": "1.21.0-alpha-mar-12-2022"
|
"@playwright/test": "^1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
tests/components/ct-vue2-cli/.gitignore
vendored
Normal file
23
tests/components/ct-vue2-cli/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
24
tests/components/ct-vue2-cli/README.md
Normal file
24
tests/components/ct-vue2-cli/README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# ct-vue2-cli
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
5
tests/components/ct-vue2-cli/babel.config.js
Normal file
5
tests/components/ct-vue2-cli/babel.config.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
47
tests/components/ct-vue2-cli/package.json
Normal file
47
tests/components/ct-vue2-cli/package.json
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"name": "ct-vue2-cli",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"vue": "^2.6.14"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.16",
|
||||||
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
|
"@vue/cli-service": "~5.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
|
"vue-template-compiler": "^2.6.14"
|
||||||
|
},
|
||||||
|
"@standaloneDevDependencies": {
|
||||||
|
"@playwright/experimental-ct-vue2": "^1.22.2",
|
||||||
|
"@playwright/test": "^1.22.2"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "@babel/eslint-parser"
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead"
|
||||||
|
]
|
||||||
|
}
|
||||||
43
tests/components/ct-vue2-cli/playwright.config.ts
Normal file
43
tests/components/ct-vue2-cli/playwright.config.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* 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 PlaywrightTestConfig, devices } from '@playwright/experimental-ct-vue2';
|
||||||
|
|
||||||
|
const config: PlaywrightTestConfig = {
|
||||||
|
testDir: 'src',
|
||||||
|
forbidOnly: !!process.env.CI,
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
|
reporter: 'html',
|
||||||
|
use: {
|
||||||
|
trace: 'on-first-retry',
|
||||||
|
},
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'chromium',
|
||||||
|
use: { ...devices['Desktop Chrome'] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'firefox',
|
||||||
|
use: { ...devices['Desktop Firefox'] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'webkit',
|
||||||
|
use: { ...devices['Desktop Safari'] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
12
tests/components/ct-vue2-cli/playwright/index.html
Normal file
12
tests/components/ct-vue2-cli/playwright/index.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/playwright/index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
tests/components/ct-vue2-cli/playwright/index.js
Normal file
0
tests/components/ct-vue2-cli/playwright/index.js
Normal file
BIN
tests/components/ct-vue2-cli/public/favicon.ico
Normal file
BIN
tests/components/ct-vue2-cli/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
17
tests/components/ct-vue2-cli/public/index.html
Normal file
17
tests/components/ct-vue2-cli/public/index.html
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
tests/components/ct-vue2-cli/src/App.vue
Normal file
28
tests/components/ct-vue2-cli/src/App.vue
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<img alt="Vue logo" src="./assets/logo.png">
|
||||||
|
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HelloWorld from './components/HelloWorld.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
HelloWorld
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
tests/components/ct-vue2-cli/src/assets/logo.png
Normal file
BIN
tests/components/ct-vue2-cli/src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
12
tests/components/ct-vue2-cli/src/components/Button.vue
Normal file
12
tests/components/ct-vue2-cli/src/components/Button.vue
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<template>
|
||||||
|
<button @click='$emit("submit", "hello")'>
|
||||||
|
{{ title }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ButtonButton',
|
||||||
|
props: ['title']
|
||||||
|
}
|
||||||
|
</script>
|
||||||
11
tests/components/ct-vue2-cli/src/components/DefaultSlot.vue
Normal file
11
tests/components/ct-vue2-cli/src/components/DefaultSlot.vue
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Welcome!</h1>
|
||||||
|
<main>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
Thanks for visiting.
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
58
tests/components/ct-vue2-cli/src/components/HelloWorld.vue
Normal file
58
tests/components/ct-vue2-cli/src/components/HelloWorld.vue
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
<template>
|
||||||
|
<div class="hello">
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
<p>
|
||||||
|
For a guide and recipes on how to configure / customize this project,<br>
|
||||||
|
check out the
|
||||||
|
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||||
|
</p>
|
||||||
|
<h3>Installed CLI Plugins</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||||
|
</ul>
|
||||||
|
<h3>Essential Links</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||||
|
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||||
|
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||||
|
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||||
|
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||||
|
</ul>
|
||||||
|
<h3>Ecosystem</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||||
|
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||||
|
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HelloWorld',
|
||||||
|
props: {
|
||||||
|
msg: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
h3 {
|
||||||
|
margin: 40px 0 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
14
tests/components/ct-vue2-cli/src/components/NamedSlots.vue
Normal file
14
tests/components/ct-vue2-cli/src/components/NamedSlots.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<slot name="header" />
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<slot name="main" />
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<slot name="footer" />
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
8
tests/components/ct-vue2-cli/src/main.js
Normal file
8
tests/components/ct-vue2-cli/src/main.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
render: h => h(App),
|
||||||
|
}).$mount('#app')
|
||||||
62
tests/components/ct-vue2-cli/src/notation-jsx.spec.tsx
Normal file
62
tests/components/ct-vue2-cli/src/notation-jsx.spec.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { test, expect } from '@playwright/experimental-ct-vue2'
|
||||||
|
import Button from './components/Button.vue'
|
||||||
|
import DefaultSlot from './components/DefaultSlot.vue'
|
||||||
|
import NamedSlots from './components/NamedSlots.vue'
|
||||||
|
|
||||||
|
test.use({ viewport: { width: 500, height: 500 } })
|
||||||
|
|
||||||
|
test('props should work', async ({ mount }) => {
|
||||||
|
const component = await mount(<Button title='Submit'></Button>)
|
||||||
|
await expect(component).toContainText('Submit')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('event should work', async ({ mount }) => {
|
||||||
|
const messages = []
|
||||||
|
const component = await mount(<Button title='Submit' v-on:submit={data => {
|
||||||
|
messages.push(data)
|
||||||
|
}}></Button>)
|
||||||
|
await component.click()
|
||||||
|
expect(messages).toEqual(['hello'])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('default slot should work', async ({ mount }) => {
|
||||||
|
const component = await mount(<DefaultSlot>
|
||||||
|
Main Content
|
||||||
|
</DefaultSlot>)
|
||||||
|
await expect(component).toContainText('Main Content')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('multiple slots should work', async ({ mount }) => {
|
||||||
|
const component = await mount(<DefaultSlot>
|
||||||
|
<div id="one">One</div>
|
||||||
|
<div id="two">Two</div>
|
||||||
|
</DefaultSlot>)
|
||||||
|
await expect(component.locator('#one')).toContainText('One')
|
||||||
|
await expect(component.locator('#two')).toContainText('Two')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('named slots should work', async ({ mount }) => {
|
||||||
|
const component = await mount(<NamedSlots>
|
||||||
|
<template v-slot:header>
|
||||||
|
Header
|
||||||
|
</template>
|
||||||
|
<template v-slot:main>
|
||||||
|
Main Content
|
||||||
|
</template>
|
||||||
|
<template v-slot:footer>
|
||||||
|
Footer
|
||||||
|
</template>
|
||||||
|
</NamedSlots>);
|
||||||
|
await expect(component).toContainText('Header')
|
||||||
|
await expect(component).toContainText('Main Content')
|
||||||
|
await expect(component).toContainText('Footer')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('slot should emit events', async ({ mount }) => {
|
||||||
|
let clickFired = false;
|
||||||
|
const component = await mount(<DefaultSlot>
|
||||||
|
<span v-on:click={() => clickFired = true}>Main Content</span>
|
||||||
|
</DefaultSlot>);
|
||||||
|
await component.locator('text=Main Content').click();
|
||||||
|
expect(clickFired).toBeTruthy();
|
||||||
|
})
|
||||||
62
tests/components/ct-vue2-cli/src/notation-vue.spec.ts
Normal file
62
tests/components/ct-vue2-cli/src/notation-vue.spec.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { test, expect } from '@playwright/experimental-ct-vue2'
|
||||||
|
|
||||||
|
import Button from './components/Button.vue'
|
||||||
|
import DefaultSlot from './components/DefaultSlot.vue'
|
||||||
|
import NamedSlots from './components/NamedSlots.vue'
|
||||||
|
|
||||||
|
test.use({ viewport: { width: 500, height: 500 } })
|
||||||
|
|
||||||
|
test('props should work', async ({ mount }) => {
|
||||||
|
const component = await mount(Button, {
|
||||||
|
props: {
|
||||||
|
title: 'Submit'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await expect(component).toContainText('Submit')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('event should work', async ({ mount }) => {
|
||||||
|
const messages = []
|
||||||
|
const component = await mount(Button, {
|
||||||
|
props: {
|
||||||
|
title: 'Submit'
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
submit: data => messages.push(data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await component.click()
|
||||||
|
expect(messages).toEqual(['hello'])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('default slot should work', async ({ mount }) => {
|
||||||
|
const component = await mount(DefaultSlot, {
|
||||||
|
slots: {
|
||||||
|
default: 'Main Content'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await expect(component).toContainText('Main Content')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('multiple slots should work', async ({ mount }) => {
|
||||||
|
const component = await mount(DefaultSlot, {
|
||||||
|
slots: {
|
||||||
|
default: ['one', 'two']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await expect(component).toContainText('one')
|
||||||
|
await expect(component).toContainText('two')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('named slots should work', async ({ mount }) => {
|
||||||
|
const component = await mount(NamedSlots, {
|
||||||
|
slots: {
|
||||||
|
header: 'Header',
|
||||||
|
main: 'Main Content',
|
||||||
|
footer: 'Footer'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await expect(component).toContainText('Header')
|
||||||
|
await expect(component).toContainText('Main Content')
|
||||||
|
await expect(component).toContainText('Footer')
|
||||||
|
})
|
||||||
4
tests/components/ct-vue2-cli/src/vue.d.ts
vendored
Normal file
4
tests/components/ct-vue2-cli/src/vue.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
declare module '*.vue' {
|
||||||
|
const value: any;
|
||||||
|
export default value;
|
||||||
|
}
|
||||||
4
tests/components/ct-vue2-cli/vue.config.js
Normal file
4
tests/components/ct-vue2-cli/vue.config.js
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
const { defineConfig } = require('@vue/cli-service')
|
||||||
|
module.exports = defineConfig({
|
||||||
|
transpileDependencies: true
|
||||||
|
})
|
||||||
|
|
@ -4,6 +4,7 @@ const path = require('path');
|
||||||
const rimraf = require('rimraf');
|
const rimraf = require('rimraf');
|
||||||
|
|
||||||
for (const pkg of workspace.packages()) {
|
for (const pkg of workspace.packages()) {
|
||||||
|
rimraf.sync(path.join(pkg.path, 'node_modules'));
|
||||||
rimraf.sync(path.join(pkg.path, 'lib'));
|
rimraf.sync(path.join(pkg.path, 'lib'));
|
||||||
rimraf.sync(path.join(pkg.path, 'src', 'generated'));
|
rimraf.sync(path.join(pkg.path, 'src', 'generated'));
|
||||||
const bundles = path.join(pkg.path, 'bundles');
|
const bundles = path.join(pkg.path, 'bundles');
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,11 @@ const workspace = new Workspace(ROOT_PATH, [
|
||||||
path: path.join(ROOT_PATH, 'packages', 'playwright-ct-vue'),
|
path: path.join(ROOT_PATH, 'packages', 'playwright-ct-vue'),
|
||||||
files: ['LICENSE'],
|
files: ['LICENSE'],
|
||||||
}),
|
}),
|
||||||
|
new PWPackage({
|
||||||
|
name: '@playwright/experimental-ct-vue2',
|
||||||
|
path: path.join(ROOT_PATH, 'packages', 'playwright-ct-vue2'),
|
||||||
|
files: ['LICENSE'],
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue