chore: remove playwright-ct-vue2 (#33302)
This commit is contained in:
parent
1e8884621a
commit
87b896e597
|
|
@ -521,7 +521,6 @@ You can use `beforeMount` and `afterMount` hooks to configure your app. This let
|
||||||
{label: 'React', value: 'react'},
|
{label: 'React', value: 'react'},
|
||||||
{label: 'Solid', value: 'solid'},
|
{label: 'Solid', value: 'solid'},
|
||||||
{label: 'Vue3', value: 'vue3'},
|
{label: 'Vue3', value: 'vue3'},
|
||||||
{label: 'Vue2', value: 'vue2'},
|
|
||||||
]
|
]
|
||||||
}>
|
}>
|
||||||
<TabItem value="react">
|
<TabItem value="react">
|
||||||
|
|
@ -617,40 +616,6 @@ You can use `beforeMount` and `afterMount` hooks to configure your app. This let
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
<TabItem value="vue2">
|
|
||||||
|
|
||||||
```js title="playwright/index.ts"
|
|
||||||
import { beforeMount, afterMount } from '@playwright/experimental-ct-vue2/hooks';
|
|
||||||
import Router from 'vue-router';
|
|
||||||
import { router } from '../src/router';
|
|
||||||
|
|
||||||
export type HooksConfig = {
|
|
||||||
enableRouting?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeMount<HooksConfig>(async ({ app, hooksConfig }) => {
|
|
||||||
if (hooksConfig?.enableRouting) {
|
|
||||||
Vue.use(Router);
|
|
||||||
return { router }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
```js title="src/pages/ProductsPage.spec.ts"
|
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import type { HooksConfig } from '../playwright';
|
|
||||||
import ProductsPage from './pages/ProductsPage.vue';
|
|
||||||
|
|
||||||
test('configure routing through hooks config', async ({ page, mount }) => {
|
|
||||||
const component = await mount<HooksConfig>(ProductsPage, {
|
|
||||||
hooksConfig: { enableRouting: true },
|
|
||||||
});
|
|
||||||
await expect(component.getByRole('link')).toHaveAttribute('href', '/products/42');
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### unmount
|
### unmount
|
||||||
|
|
|
||||||
80
package-lock.json
generated
80
package-lock.json
generated
|
|
@ -1508,10 +1508,6 @@
|
||||||
"resolved": "packages/playwright-ct-vue",
|
"resolved": "packages/playwright-ct-vue",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@playwright/experimental-ct-vue2": {
|
|
||||||
"resolved": "packages/playwright-ct-vue2",
|
|
||||||
"link": true
|
|
||||||
},
|
|
||||||
"node_modules/@playwright/test": {
|
"node_modules/@playwright/test": {
|
||||||
"resolved": "packages/playwright-test",
|
"resolved": "packages/playwright-test",
|
||||||
"link": true
|
"link": true
|
||||||
|
|
@ -5964,21 +5960,6 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
|
||||||
"version": "2.8.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
|
||||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
|
||||||
"optional": true,
|
|
||||||
"bin": {
|
|
||||||
"prettier": "bin-prettier.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.13.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/progress": {
|
"node_modules/progress": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||||
|
|
@ -6593,14 +6574,6 @@
|
||||||
"solid-js": "^1.3"
|
"solid-js": "^1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map": {
|
|
||||||
"version": "0.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
|
@ -8097,59 +8070,6 @@
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-vue2": {
|
|
||||||
"name": "@playwright/experimental-ct-vue2",
|
|
||||||
"version": "1.49.0-next",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@playwright/experimental-ct-core": "1.49.0-next",
|
|
||||||
"@vitejs/plugin-vue2": "^2.2.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"playwright": "cli.js"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"vue": "^2.7.14"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/playwright-ct-vue2/node_modules/@vitejs/plugin-vue2": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue2/-/plugin-vue2-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-/ksaaz2SRLN11JQhLdEUhDzOn909WEk99q9t9w+N12GjQCljzv7GyvAbD/p20aBUjHkvpGOoQ+FCOkG+mjDF4A==",
|
|
||||||
"engines": {
|
|
||||||
"node": "^14.18.0 || >= 16.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0",
|
|
||||||
"vue": "^2.7.0-0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/playwright-ct-vue2/node_modules/@vue/compiler-sfc": {
|
|
||||||
"version": "2.7.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz",
|
|
||||||
"integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/parser": "^7.23.5",
|
|
||||||
"postcss": "^8.4.14",
|
|
||||||
"source-map": "^0.6.1"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"prettier": "^1.18.2 || ^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/playwright-ct-vue2/node_modules/vue": {
|
|
||||||
"version": "2.7.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz",
|
|
||||||
"integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==",
|
|
||||||
"deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/compiler-sfc": "2.7.16",
|
|
||||||
"csstype": "^3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/playwright-firefox": {
|
"packages/playwright-firefox": {
|
||||||
"version": "1.49.0-next",
|
"version": "1.49.0-next",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
**/*
|
|
||||||
|
|
||||||
!README.md
|
|
||||||
!LICENSE
|
|
||||||
!cli.js
|
|
||||||
!register.d.ts
|
|
||||||
!register.mjs
|
|
||||||
!registerSource.mjs
|
|
||||||
!index.d.ts
|
|
||||||
!index.js
|
|
||||||
!hooks.d.ts
|
|
||||||
!hooks.mjs
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
> **BEWARE** This package is EXPERIMENTAL and does not respect semver.
|
|
||||||
|
|
||||||
Read more at https://playwright.dev/docs/test-components
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
/**
|
|
||||||
* 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 { program } = require('@playwright/experimental-ct-core/lib/program');
|
|
||||||
|
|
||||||
program.parse(process.argv);
|
|
||||||
37
packages/playwright-ct-vue2/hooks.d.ts
vendored
37
packages/playwright-ct-vue2/hooks.d.ts
vendored
|
|
@ -1,37 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { ComponentOptions } from 'vue';
|
|
||||||
import type { CombinedVueInstance, Vue, VueConstructor } from 'vue/types/vue';
|
|
||||||
|
|
||||||
export declare function beforeMount<HooksConfig>(
|
|
||||||
callback: (params: {
|
|
||||||
hooksConfig?: HooksConfig,
|
|
||||||
Vue: VueConstructor<Vue>,
|
|
||||||
}) => Promise<void | ComponentOptions<Vue> & Record<string, unknown>>
|
|
||||||
): void;
|
|
||||||
export declare function afterMount<HooksConfig>(
|
|
||||||
callback: (params: {
|
|
||||||
hooksConfig?: HooksConfig;
|
|
||||||
instance: CombinedVueInstance<
|
|
||||||
Vue,
|
|
||||||
object,
|
|
||||||
object,
|
|
||||||
object,
|
|
||||||
Record<never, any>
|
|
||||||
>;
|
|
||||||
}) => Promise<void>
|
|
||||||
): void;
|
|
||||||
|
|
@ -1,29 +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 __pw_hooks_before_mount = [];
|
|
||||||
const __pw_hooks_after_mount = [];
|
|
||||||
|
|
||||||
window.__pw_hooks_before_mount = __pw_hooks_before_mount;
|
|
||||||
window.__pw_hooks_after_mount = __pw_hooks_after_mount;
|
|
||||||
|
|
||||||
export const beforeMount = callback => {
|
|
||||||
__pw_hooks_before_mount.push(callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const afterMount = callback => {
|
|
||||||
__pw_hooks_after_mount.push(callback);
|
|
||||||
};
|
|
||||||
66
packages/playwright-ct-vue2/index.d.ts
vendored
66
packages/playwright-ct-vue2/index.d.ts
vendored
|
|
@ -1,66 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { TestType, Locator } from '@playwright/experimental-ct-core';
|
|
||||||
|
|
||||||
type Slot = string | string[];
|
|
||||||
type ComponentSlots = Record<string, Slot> & { default?: Slot };
|
|
||||||
|
|
||||||
type ComponentEvents = Record<string, Function>;
|
|
||||||
|
|
||||||
// Copied from: https://github.com/vuejs/language-tools/blob/master/packages/vue-component-type-helpers/index.d.ts#L10-L13
|
|
||||||
type ComponentProps<T> =
|
|
||||||
T extends new (...angs: any) => { $props: infer P; } ? NonNullable<P> :
|
|
||||||
T extends (props: infer P, ...args: any) => any ? P :
|
|
||||||
{};
|
|
||||||
|
|
||||||
export interface MountOptions<HooksConfig, Component> {
|
|
||||||
props?: ComponentProps<Component>;
|
|
||||||
slots?: ComponentSlots;
|
|
||||||
on?: ComponentEvents;
|
|
||||||
hooksConfig?: HooksConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MountOptionsJsx<HooksConfig> {
|
|
||||||
hooksConfig?: HooksConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MountResult<Component> extends Locator {
|
|
||||||
unmount(): Promise<void>;
|
|
||||||
update(options: {
|
|
||||||
props?: Partial<ComponentProps<Component>>;
|
|
||||||
slots?: Partial<ComponentSlots>;
|
|
||||||
on?: Partial<ComponentEvents>;
|
|
||||||
}): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MountResultJsx extends Locator {
|
|
||||||
unmount(): Promise<void>;
|
|
||||||
update(component: JSX.Element): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const test: TestType<{
|
|
||||||
mount<HooksConfig>(
|
|
||||||
component: JSX.Element,
|
|
||||||
options?: MountOptionsJsx<HooksConfig>
|
|
||||||
): Promise<MountResultJsx>;
|
|
||||||
mount<HooksConfig, Component = unknown>(
|
|
||||||
component: Component,
|
|
||||||
options?: MountOptions<HooksConfig, Component>
|
|
||||||
): Promise<MountResult<Component>>;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
export { defineConfig, PlaywrightTestConfig, expect, devices } from '@playwright/experimental-ct-core';
|
|
||||||
|
|
@ -1,33 +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 { test, expect, devices, defineConfig: originalDefineConfig } = require('@playwright/experimental-ct-core');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const defineConfig = (config, ...configs) => {
|
|
||||||
return originalDefineConfig({
|
|
||||||
...config,
|
|
||||||
'@playwright/test': {
|
|
||||||
packageJSON: require.resolve('./package.json'),
|
|
||||||
},
|
|
||||||
'@playwright/experimental-ct-core': {
|
|
||||||
registerSourceFile: path.join(__dirname, 'registerSource.mjs'),
|
|
||||||
frameworkPluginFactory: () => import('@vitejs/plugin-vue2').then(plugin => plugin.default()),
|
|
||||||
},
|
|
||||||
}, ...configs);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = { test, expect, devices, defineConfig };
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@playwright/experimental-ct-vue2",
|
|
||||||
"version": "1.49.0-next",
|
|
||||||
"description": "Playwright Component Testing for Vue2",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/microsoft/playwright.git"
|
|
||||||
},
|
|
||||||
"homepage": "https://playwright.dev",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"name": "Microsoft Corporation"
|
|
||||||
},
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./index.d.ts",
|
|
||||||
"default": "./index.js"
|
|
||||||
},
|
|
||||||
"./register": {
|
|
||||||
"types": "./register.d.ts",
|
|
||||||
"default": "./register.mjs"
|
|
||||||
},
|
|
||||||
"./hooks": {
|
|
||||||
"types": "./hooks.d.ts",
|
|
||||||
"default": "./hooks.mjs"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@playwright/experimental-ct-core": "1.49.0-next",
|
|
||||||
"@vitejs/plugin-vue2": "^2.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"vue": "^2.7.14"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"playwright": "cli.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
packages/playwright-ct-vue2/register.d.ts
vendored
24
packages/playwright-ct-vue2/register.d.ts
vendored
|
|
@ -1,24 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default function pwRegister(
|
|
||||||
components: Record<string, any>,
|
|
||||||
options?: {
|
|
||||||
createApp: any,
|
|
||||||
setDevtoolsHook: any,
|
|
||||||
h: any,
|
|
||||||
}
|
|
||||||
): void;
|
|
||||||
|
|
@ -1,21 +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 { pwRegister } from './registerSource.mjs';
|
|
||||||
|
|
||||||
export default components => {
|
|
||||||
pwRegister(components);
|
|
||||||
};
|
|
||||||
|
|
@ -1,212 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
// This file is injected into the registry as text, no dependencies are allowed.
|
|
||||||
|
|
||||||
import __pwVue, { h as __pwH } from 'vue';
|
|
||||||
|
|
||||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
|
||||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
|
||||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
|
||||||
/** @typedef {import('vue').Component} FrameworkComponent */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} component
|
|
||||||
* @returns {component is ObjectComponent}
|
|
||||||
*/
|
|
||||||
function isObjectComponent(component) {
|
|
||||||
return typeof component === 'object' && component && component.__pw_type === 'object-component';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} component
|
|
||||||
* @returns {component is JsxComponent}
|
|
||||||
*/
|
|
||||||
function isJsxComponent(component) {
|
|
||||||
return typeof component === 'object' && component && component.__pw_type === 'jsx';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} child
|
|
||||||
*/
|
|
||||||
function __pwCreateChild(child) {
|
|
||||||
if (Array.isArray(child))
|
|
||||||
return child.map(grandChild => __pwCreateChild(grandChild));
|
|
||||||
if (isJsxComponent(child) || isObjectComponent(child))
|
|
||||||
return __pwCreateWrapper(child);
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exists to support fallthrough attributes:
|
|
||||||
* https://vuejs.org/guide/components/attrs.html#fallthrough-attributes
|
|
||||||
* @param {any} Component
|
|
||||||
* @param {string} key
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
function __pwComponentHasKeyInProps(Component, key) {
|
|
||||||
return typeof Component.props === 'object' && Component.props && key in Component.props;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JsxComponent} component
|
|
||||||
* @returns {any[] | undefined}
|
|
||||||
*/
|
|
||||||
function __pwJsxChildArray(component) {
|
|
||||||
if (!component.props.children)
|
|
||||||
return;
|
|
||||||
if (Array.isArray(component.props.children))
|
|
||||||
return component.props.children;
|
|
||||||
return [component.props.children];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Component} component
|
|
||||||
*/
|
|
||||||
function __pwCreateComponent(component) {
|
|
||||||
const isVueComponent = typeof component.type !== 'string';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import('vue').VNode | string)[]}
|
|
||||||
*/
|
|
||||||
const children = [];
|
|
||||||
|
|
||||||
/** @type {import('vue').VNodeData} */
|
|
||||||
const nodeData = {};
|
|
||||||
nodeData.attrs = {};
|
|
||||||
nodeData.props = {};
|
|
||||||
nodeData.scopedSlots = {};
|
|
||||||
nodeData.on = {};
|
|
||||||
|
|
||||||
if (component.__pw_type === 'jsx') {
|
|
||||||
for (const child of __pwJsxChildArray(component) || []) {
|
|
||||||
if (isJsxComponent(child) && child.type === 'template') {
|
|
||||||
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
|
||||||
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
|
||||||
nodeData.scopedSlots[slot] = () => __pwJsxChildArray(child)?.map(c => __pwCreateChild(c));
|
|
||||||
} else {
|
|
||||||
children.push(__pwCreateChild(child));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 && __pwComponentHasKeyInProps(component.type, key))
|
|
||||||
nodeData.props[key] = value;
|
|
||||||
else
|
|
||||||
nodeData.attrs[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (component.__pw_type === 'object-component') {
|
|
||||||
// Vue test util syntax.
|
|
||||||
for (const [key, value] of Object.entries(component.slots || {})) {
|
|
||||||
const list = (Array.isArray(value) ? value : [value]).map(v => __pwCreateChild(v));
|
|
||||||
if (key === 'default')
|
|
||||||
children.push(...list);
|
|
||||||
else
|
|
||||||
nodeData.scopedSlots[key] = () => list;
|
|
||||||
}
|
|
||||||
nodeData.props = component.props || {};
|
|
||||||
for (const [key, value] of Object.entries(component.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { Component: component.type, nodeData, slots: lastArg };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Component} component
|
|
||||||
* @returns {import('vue').VNode}
|
|
||||||
*/
|
|
||||||
function __pwCreateWrapper(component) {
|
|
||||||
const { Component, nodeData, slots } = __pwCreateComponent(component);
|
|
||||||
const wrapper = __pwH(Component, nodeData, slots);
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
const instanceKey = Symbol('instanceKey');
|
|
||||||
const wrapperKey = Symbol('wrapperKey');
|
|
||||||
|
|
||||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
|
||||||
let options = {};
|
|
||||||
for (const hook of window.__pw_hooks_before_mount || [])
|
|
||||||
options = await hook({ hooksConfig, Vue: __pwVue });
|
|
||||||
|
|
||||||
const instance = new __pwVue({
|
|
||||||
...options,
|
|
||||||
render: () => {
|
|
||||||
const wrapper = __pwCreateWrapper(component);
|
|
||||||
/** @type {any} */ (rootElement)[wrapperKey] = wrapper;
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
}).$mount();
|
|
||||||
rootElement.appendChild(instance.$el);
|
|
||||||
/** @type {any} */ (rootElement)[instanceKey] = instance;
|
|
||||||
|
|
||||||
for (const hook of window.__pw_hooks_after_mount || [])
|
|
||||||
await hook({ hooksConfig, instance });
|
|
||||||
};
|
|
||||||
|
|
||||||
window.playwrightUnmount = async rootElement => {
|
|
||||||
const component = rootElement[instanceKey];
|
|
||||||
if (!component)
|
|
||||||
throw new Error('Component was not mounted');
|
|
||||||
component.$destroy();
|
|
||||||
component.$el.remove();
|
|
||||||
delete rootElement[instanceKey];
|
|
||||||
};
|
|
||||||
|
|
||||||
window.playwrightUpdate = async (element, options) => {
|
|
||||||
const wrapper = /** @type {any} */(element)[wrapperKey];
|
|
||||||
if (!wrapper)
|
|
||||||
throw new Error('Component was not mounted');
|
|
||||||
|
|
||||||
const component = wrapper.componentInstance;
|
|
||||||
if (!component)
|
|
||||||
throw new Error('Updating a native HTML element is not supported');
|
|
||||||
|
|
||||||
const { nodeData, slots } = __pwCreateComponent(options);
|
|
||||||
|
|
||||||
for (const [name, value] of Object.entries(nodeData.on || {})) {
|
|
||||||
component.$on(name, value);
|
|
||||||
component.$listeners[name] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(component.$scopedSlots, nodeData.scopedSlots);
|
|
||||||
component.$slots.default = slots;
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(nodeData.props || {}))
|
|
||||||
component[key] = value;
|
|
||||||
|
|
||||||
if (!Object.keys(nodeData.props || {}).length)
|
|
||||||
component.$forceUpdate();
|
|
||||||
};
|
|
||||||
23
tests/components/ct-vue2-cli/.gitignore
vendored
23
tests/components/ct-vue2-cli/.gitignore
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
.DS_Store
|
|
||||||
node_modules
|
|
||||||
/dist
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# 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?
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
# 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/).
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
presets: [
|
|
||||||
'@vue/cli-plugin-babel/preset'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
{
|
|
||||||
"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",
|
|
||||||
"typecheck": "tsc --noEmit --project tsconfig.test.json"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"core-js": "^3.8.3",
|
|
||||||
"vue": "^2.7.13",
|
|
||||||
"vue-router": "^3.6.5"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/core": "^7.23.2",
|
|
||||||
"@babel/eslint-parser": "^7.22.15",
|
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
|
||||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
|
||||||
"@vue/cli-service": "~5.0.0",
|
|
||||||
"@vue/tsconfig": "^0.1.3",
|
|
||||||
"eslint": "^7.32.0",
|
|
||||||
"eslint-plugin-vue": "^8.0.3"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +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 { defineConfig, devices } from '@playwright/experimental-ct-vue2';
|
|
||||||
import { resolve } from 'path';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
testDir: 'tests',
|
|
||||||
forbidOnly: !!process.env.CI,
|
|
||||||
retries: process.env.CI ? 2 : 0,
|
|
||||||
reporter: process.env.CI ? 'html' : 'line',
|
|
||||||
use: {
|
|
||||||
trace: 'on-first-retry',
|
|
||||||
ctViteConfig: {
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': resolve(__dirname, './src'),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
name: 'chromium',
|
|
||||||
use: { ...devices['Desktop Chrome'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'firefox',
|
|
||||||
use: { ...devices['Desktop Firefox'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'webkit',
|
|
||||||
use: { ...devices['Desktop Safari'] },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<!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="./index.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import { beforeMount, afterMount } from '@playwright/experimental-ct-vue2/hooks';
|
|
||||||
import Router from 'vue-router';
|
|
||||||
import { router } from '../src/router';
|
|
||||||
import '../src/assets/index.css';
|
|
||||||
|
|
||||||
beforeMount(async ({ Vue, hooksConfig }) => {
|
|
||||||
console.log(`Before mount: ${JSON.stringify(hooksConfig)}`);
|
|
||||||
|
|
||||||
if (hooksConfig?.routing) {
|
|
||||||
Vue.use(Router);
|
|
||||||
return { router }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
afterMount(async ({ instance }) => {
|
|
||||||
console.log(`After mount el: ${instance.$el.constructor.name}`);
|
|
||||||
});
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
|
|
@ -1,17 +0,0 @@
|
||||||
<!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>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<template>
|
|
||||||
<div id="app">
|
|
||||||
<header>
|
|
||||||
<img alt="Vue logo" src="./assets/logo.png" width="60" height="60">
|
|
||||||
<router-link to="/">Login</router-link>
|
|
||||||
<router-link to="/dashboard">Dashboard</router-link>
|
|
||||||
</header>
|
|
||||||
<router-view />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
||||||
sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
|
||||||
monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
:root {
|
|
||||||
color: #e3e3e3;
|
|
||||||
background-color: #1b1b1d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
|
|
@ -1,10 +0,0 @@
|
||||||
<template>
|
|
||||||
<button @click="$emit('submit', 'hello')">{{ title }}</button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
export default {
|
|
||||||
name: 'ButtonButton',
|
|
||||||
props: ['title']
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>test</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<button @click="$emit('submit', 'hello')">
|
|
||||||
<span data-testid="props">{{ count }}</span>
|
|
||||||
<span data-testid="remount-count">{{ remountCount }}</span>
|
|
||||||
<slot name="main" />
|
|
||||||
<slot />
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
let remountCount = 0;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Button',
|
|
||||||
props: ['count'],
|
|
||||||
data() {
|
|
||||||
return { remountCount }
|
|
||||||
},
|
|
||||||
beforeCreate() {
|
|
||||||
remountCount++;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<h1>Welcome!</h1>
|
|
||||||
<main>
|
|
||||||
<slot />
|
|
||||||
</main>
|
|
||||||
<footer>
|
|
||||||
Thanks for visiting.
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { useSlots } from 'vue';
|
|
||||||
const slots = useSlots();
|
|
||||||
Object.assign(window, { slots });
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<header>
|
|
||||||
<slot name="header" />
|
|
||||||
</header>
|
|
||||||
<main>
|
|
||||||
<slot name="main" />
|
|
||||||
</main>
|
|
||||||
<footer>
|
|
||||||
<slot name="footer" />
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import Router from 'vue-router';
|
|
||||||
import App from './App.vue';
|
|
||||||
import { router } from './router';
|
|
||||||
import './assets/index.css';
|
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
|
||||||
|
|
||||||
Vue.use(Router);
|
|
||||||
|
|
||||||
new Vue({
|
|
||||||
router,
|
|
||||||
render: h => h(App),
|
|
||||||
}).$mount('#app');
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<template>
|
|
||||||
<main>Dashboard</main>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<template>
|
|
||||||
<main>Login</main>
|
|
||||||
</template>
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import Router from 'vue-router';
|
|
||||||
import LoginPage from '../pages/LoginPage.vue';
|
|
||||||
import DashboardPage from '../pages/DashboardPage.vue';
|
|
||||||
|
|
||||||
export const router = new Router({
|
|
||||||
mode: 'history',
|
|
||||||
base: '/',
|
|
||||||
routes: [
|
|
||||||
{ path: '/', component: LoginPage },
|
|
||||||
{ path: '/dashboard', component: DashboardPage }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
declare module '*.vue' {
|
|
||||||
import Vue from 'vue';
|
|
||||||
export default Vue;
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Button from '@/components/Button.vue';
|
|
||||||
|
|
||||||
test('emit an submit event when the button is clicked', async ({ mount }) => {
|
|
||||||
const messages: string[] = [];
|
|
||||||
const component = await mount(Button, {
|
|
||||||
props: {
|
|
||||||
title: 'Submit',
|
|
||||||
},
|
|
||||||
on: {
|
|
||||||
submit: (data: string) => messages.push(data),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await component.click();
|
|
||||||
expect(messages).toEqual(['hello']);
|
|
||||||
});
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Button from '@/components/Button.vue';
|
|
||||||
import DefaultSlot from '@/components/DefaultSlot.vue';
|
|
||||||
|
|
||||||
test('emit an submit event when the button is clicked', async ({ mount }) => {
|
|
||||||
const messages: string[] = [];
|
|
||||||
const component = await mount(
|
|
||||||
<Button
|
|
||||||
title="Submit"
|
|
||||||
v-on:submit={(data: string) => {
|
|
||||||
messages.push(data);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
await component.click();
|
|
||||||
expect(messages).toEqual(['hello']);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('emit a event when a slot is clicked', async ({ mount }) => {
|
|
||||||
let clickFired = false;
|
|
||||||
const component = await mount(
|
|
||||||
<DefaultSlot>
|
|
||||||
<span v-on:click={() => (clickFired = true)}>Main Content</span>
|
|
||||||
</DefaultSlot>
|
|
||||||
);
|
|
||||||
await component.getByText('Main Content').click();
|
|
||||||
expect(clickFired).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Button from '@/components/Button.vue';
|
|
||||||
import Component from '@/components/Component.vue';
|
|
||||||
import EmptyTemplate from '@/components/EmptyTemplate.vue';
|
|
||||||
|
|
||||||
test('render props', async ({ mount }) => {
|
|
||||||
const component = await mount(Button, {
|
|
||||||
props: {
|
|
||||||
title: 'Submit',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expect(component).toContainText('Submit');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render a component without options', async ({ mount }) => {
|
|
||||||
const component = await mount(Component);
|
|
||||||
await expect(component).toContainText('test');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get textContent of the empty template', async ({ mount }) => {
|
|
||||||
const component = await mount(EmptyTemplate);
|
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
|
||||||
expect(await component.textContent()).toBe('');
|
|
||||||
await expect(component).toHaveText('');
|
|
||||||
});
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Button from '@/components/Button.vue';
|
|
||||||
import EmptyTemplate from '@/components/EmptyTemplate.vue';
|
|
||||||
|
|
||||||
test('render props', async ({ mount }) => {
|
|
||||||
const component = await mount(<Button title="Submit" />);
|
|
||||||
await expect(component).toContainText('Submit');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render attributes', async ({ mount }) => {
|
|
||||||
const component = await mount(<Button class="primary" title="Submit" />);
|
|
||||||
await expect(component).toHaveClass('primary');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render an empty component', async ({ page, mount }) => {
|
|
||||||
const component = await mount(<EmptyTemplate />);
|
|
||||||
expect(await page.evaluate(() => 'slots' in window && window.slots)).toEqual({});
|
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
|
||||||
expect(await component.textContent()).toBe('');
|
|
||||||
await expect(component).toHaveText('');
|
|
||||||
});
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import DefaultSlot from '@/components/DefaultSlot.vue';
|
|
||||||
import NamedSlots from '@/components/NamedSlots.vue';
|
|
||||||
|
|
||||||
test('render a default slot', async ({ mount }) => {
|
|
||||||
const component = await mount(DefaultSlot, {
|
|
||||||
slots: {
|
|
||||||
default: 'Main Content',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expect(component).toContainText('Main Content');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render a component with multiple slots', async ({ mount }) => {
|
|
||||||
const component = await mount(DefaultSlot, {
|
|
||||||
slots: {
|
|
||||||
default: ['one', 'two'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expect(component).toContainText('one');
|
|
||||||
await expect(component).toContainText('two');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render a component with a named slot', 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');
|
|
||||||
});
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
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('render a default slot', async ({ mount }) => {
|
|
||||||
const component = await mount(<DefaultSlot>Main Content</DefaultSlot>);
|
|
||||||
await expect(component).toContainText('Main Content');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render a component as slot', async ({ mount }) => {
|
|
||||||
const component = await mount(
|
|
||||||
<DefaultSlot>
|
|
||||||
<Button title="Submit" />
|
|
||||||
</DefaultSlot>
|
|
||||||
);
|
|
||||||
await expect(component).toContainText('Submit');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render a component with multiple slots', async ({ mount }) => {
|
|
||||||
const component = await mount(
|
|
||||||
<DefaultSlot>
|
|
||||||
<div data-testid="one">One</div>
|
|
||||||
<div data-testid="two">Two</div>
|
|
||||||
</DefaultSlot>
|
|
||||||
);
|
|
||||||
await expect(component.getByTestId('one')).toContainText('One');
|
|
||||||
await expect(component.getByTestId('two')).toContainText('Two');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render a component with a named slot', 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('render array as child', async ({ mount }) => {
|
|
||||||
const component = await mount(<DefaultSlot>{[<h4>{[4]}</h4>,[[<p>[2,3]</p>]]]}</DefaultSlot>);
|
|
||||||
await expect(component.getByRole('heading', { level: 4 })).toHaveText('4');
|
|
||||||
await expect(component.getByRole('paragraph')).toHaveText('[2,3]');
|
|
||||||
});
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Button from '@/components/Button.vue';
|
|
||||||
|
|
||||||
test('unmount', async ({ page, mount }) => {
|
|
||||||
const component = await mount(Button, {
|
|
||||||
props: {
|
|
||||||
title: 'Submit',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expect(page.locator('#root')).toContainText('Submit');
|
|
||||||
await component.unmount();
|
|
||||||
await expect(page.locator('#root')).not.toContainText('Submit');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('unmount twice throws an error', async ({ mount }) => {
|
|
||||||
const component = await mount(Button, {
|
|
||||||
props: {
|
|
||||||
title: 'Submit',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await component.unmount();
|
|
||||||
await expect(component.unmount()).rejects.toThrowError('Component was not mounted');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('mount then unmount then mount', async ({ mount }) => {
|
|
||||||
let component = await mount(Button, {
|
|
||||||
props: {
|
|
||||||
title: 'Submit',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await component.unmount();
|
|
||||||
component = await mount(Button, {
|
|
||||||
props: {
|
|
||||||
title: 'Save',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expect(component).toContainText('Save');
|
|
||||||
});
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Button from '@/components/Button.vue';
|
|
||||||
|
|
||||||
test('unmount', async ({ page, mount }) => {
|
|
||||||
const component = await mount(<Button title="Submit" />);
|
|
||||||
await expect(page.locator('#root')).toContainText('Submit');
|
|
||||||
await component.unmount();
|
|
||||||
await expect(page.locator('#root')).not.toContainText('Submit');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('unmount twice throws an error', async ({ mount }) => {
|
|
||||||
const component = await mount(<Button title="Submit" />);
|
|
||||||
await component.unmount();
|
|
||||||
await expect(component.unmount()).rejects.toThrowError('Component was not mounted');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('mount then unmount then mount', async ({ mount }) => {
|
|
||||||
let component = await mount(<Button title="Submit" />);
|
|
||||||
await component.unmount();
|
|
||||||
component = await mount(<Button title="Save" />);
|
|
||||||
await expect(component).toContainText('Save');
|
|
||||||
});
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Counter from '@/components/Counter.vue';
|
|
||||||
|
|
||||||
test('update props without remounting', async ({ mount }) => {
|
|
||||||
const component = await mount(Counter, {
|
|
||||||
props: { count: 9001 },
|
|
||||||
});
|
|
||||||
await expect(component.getByTestId('props')).toContainText('9001');
|
|
||||||
|
|
||||||
await component.update({
|
|
||||||
props: { count: 1337 },
|
|
||||||
});
|
|
||||||
await expect(component).not.toContainText('9001');
|
|
||||||
await expect(component.getByTestId('props')).toContainText('1337');
|
|
||||||
|
|
||||||
await expect(component.getByTestId('remount-count')).toContainText('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('update event listeners without remounting', async ({ mount }) => {
|
|
||||||
const component = await mount(Counter);
|
|
||||||
|
|
||||||
const messages: string[] = [];
|
|
||||||
await component.update({
|
|
||||||
on: {
|
|
||||||
submit: (data: string) => messages.push(data),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await component.click();
|
|
||||||
expect(messages).toEqual(['hello']);
|
|
||||||
|
|
||||||
await expect(component.getByTestId('remount-count')).toContainText('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('update slots without remounting', async ({ mount }) => {
|
|
||||||
const component = await mount(Counter, {
|
|
||||||
slots: { default: 'Default Slot' },
|
|
||||||
});
|
|
||||||
await expect(component).toContainText('Default Slot');
|
|
||||||
|
|
||||||
await component.update({
|
|
||||||
slots: { main: 'Test Slot' },
|
|
||||||
});
|
|
||||||
await expect(component).not.toContainText('Default Slot');
|
|
||||||
await expect(component).toContainText('Test Slot');
|
|
||||||
|
|
||||||
await component.update({
|
|
||||||
slots: { default: 'Default Slot' },
|
|
||||||
});
|
|
||||||
await expect(component).toContainText('Default Slot');
|
|
||||||
|
|
||||||
await expect(component.getByTestId('remount-count')).toContainText('1');
|
|
||||||
});
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import Counter from '@/components/Counter.vue';
|
|
||||||
|
|
||||||
test('update props without remounting', async ({ mount }) => {
|
|
||||||
const component = await mount(<Counter count={9001} />);
|
|
||||||
await expect(component.getByTestId('props')).toContainText('9001');
|
|
||||||
|
|
||||||
await component.update(<Counter count={1337} />);
|
|
||||||
await expect(component).not.toContainText('9001');
|
|
||||||
await expect(component.getByTestId('props')).toContainText('1337');
|
|
||||||
|
|
||||||
await expect(component.getByTestId('remount-count')).toContainText('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('update event listeners without remounting', async ({ mount }) => {
|
|
||||||
const messages: string[] = [];
|
|
||||||
const component = await mount(<Counter />);
|
|
||||||
|
|
||||||
await component.update(
|
|
||||||
<Counter
|
|
||||||
v-on:submit={(count: string) => {
|
|
||||||
messages.push(count);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
await component.click();
|
|
||||||
expect(messages).toEqual(['hello']);
|
|
||||||
|
|
||||||
await expect(component.getByTestId('remount-count')).toContainText('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('update slots without remounting', async ({ mount }) => {
|
|
||||||
const component = await mount(<Counter>Default Slot</Counter>);
|
|
||||||
await expect(component).toContainText('Default Slot');
|
|
||||||
|
|
||||||
await component.update(
|
|
||||||
<Counter>
|
|
||||||
<template v-slot:main>Test Slot</template>
|
|
||||||
</Counter>
|
|
||||||
);
|
|
||||||
await expect(component).not.toContainText('Default Slot');
|
|
||||||
await expect(component).toContainText('Test Slot');
|
|
||||||
|
|
||||||
await expect(component.getByTestId('remount-count')).toContainText('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throw error when updating a native html element', async ({ mount }) => {
|
|
||||||
const component = await mount(<div id="1337"></div>);
|
|
||||||
|
|
||||||
await expect(async () => {
|
|
||||||
await component.update(<div id="9001"></div>);
|
|
||||||
}).rejects.toThrowError('Updating a native HTML element is not supported');
|
|
||||||
});
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import App from '@/App.vue';
|
|
||||||
|
|
||||||
test('navigate to a page by clicking a link', async ({ page, mount }) => {
|
|
||||||
const component = await mount(App, {
|
|
||||||
hooksConfig: { routing: true },
|
|
||||||
});
|
|
||||||
await expect(component.getByRole('main')).toHaveText('Login');
|
|
||||||
await expect(page).toHaveURL('/');
|
|
||||||
await component.getByRole('link', { name: 'Dashboard' }).click();
|
|
||||||
await expect(component.getByRole('main')).toHaveText('Dashboard');
|
|
||||||
await expect(page).toHaveURL('/dashboard');
|
|
||||||
});
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
import { test, expect } from '@playwright/experimental-ct-vue2';
|
|
||||||
import App from '@/App.vue';
|
|
||||||
|
|
||||||
test('navigate to a page by clicking a link', async ({ page, mount }) => {
|
|
||||||
const component = await mount(<App />, {
|
|
||||||
hooksConfig: { routing: true },
|
|
||||||
});
|
|
||||||
await expect(component.getByRole('main')).toHaveText('Login');
|
|
||||||
await expect(page).toHaveURL('/');
|
|
||||||
await component.getByRole('link', { name: 'Dashboard' }).click();
|
|
||||||
await expect(component.getByRole('main')).toHaveText('Dashboard');
|
|
||||||
await expect(page).toHaveURL('/dashboard');
|
|
||||||
});
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
|
||||||
"include": ["src/**/*", "src/**/*.vue"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"],
|
|
||||||
"*": ["_"],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "@vue/tsconfig/tsconfig.node.json",
|
|
||||||
"include": ["playwright.config.*"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true,
|
|
||||||
"types": ["node"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"files": [],
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.config.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.app.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.test.json"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "./tsconfig.app.json",
|
|
||||||
"include": ["tests/**/*", "src/shims-vue.d.ts"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"allowJs": true,
|
|
||||||
"composite": true,
|
|
||||||
"lib": [],
|
|
||||||
"types": ["node"],
|
|
||||||
"ignoreDeprecations": "5.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
const { defineConfig } = require('@vue/cli-service')
|
|
||||||
module.exports = defineConfig({
|
|
||||||
transpileDependencies: true
|
|
||||||
})
|
|
||||||
|
|
@ -212,11 +212,6 @@ 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