feat(ct-vue): allow configuring apps per test (#15538)

This commit is contained in:
Pavel Feldman 2022-07-11 12:54:05 -08:00 committed by GitHub
parent 5a3f0a7195
commit 3a9b29f46c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 77 additions and 6 deletions

View File

@ -68,6 +68,6 @@ function render(component) {
}));
}
window.playwrightMount = component => {
window.playwrightMount = async component => {
ReactDOM.render(render(component), document.getElementById('root'));
};

View File

@ -32,7 +32,7 @@ export function register(components) {
registry.set(name, value);
}
window.playwrightMount = (component, rootElement) => {
window.playwrightMount = async (component, rootElement) => {
let componentCtor = registry.get(component.type);
if (!componentCtor) {
// Lookup by shorthand.

View File

@ -7,3 +7,5 @@
!registerSource.mjs
!index.d.ts
!index.js
!hooks.d.ts
!hooks.mjs

19
packages/playwright-ct-vue/hooks.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
/**
* 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 { App } from 'vue';
export declare function onApp(callback: (app: App, appConfig: any) => Promise<void>): void;

View File

@ -0,0 +1,22 @@
/**
* 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_on_app = [];
window.__pw_hooks_on_app = __pw_hooks_on_app;
export const onApp = callback => {
__pw_hooks_on_app.push(callback);
};

View File

@ -40,6 +40,7 @@ interface ComponentFixtures {
props?: Props,
slots?: { [key: string]: any },
on?: { [key: string]: Function },
appConfig?: any,
}): Promise<Locator>;
}

View File

@ -19,6 +19,10 @@
"./register": {
"types": "./register.d.ts",
"default": "./register.mjs"
},
"./hooks": {
"types": "./hooks.d.ts",
"default": "./hooks.mjs"
}
},
"dependencies": {

View File

@ -155,10 +155,14 @@ function createDevTools() {
};
}
window.playwrightMount = (component, rootElement) => {
window.playwrightMount = async (component, rootElement) => {
const app = createApp({
render: () => render(component)
});
setDevtoolsHook(createDevTools(), {});
if (component.kind === 'object') {
for (const onAppCallback of /** @type {any} */(window).__pw_hooks_on_app || [])
await onAppCallback(app, /** @type {any} */(component.options)?.appConfig)
}
app.mount(rootElement);
};

View File

@ -134,7 +134,7 @@ function render(component, h) {
return wrapper;
}
window.playwrightMount = (component, rootElement) => {
window.playwrightMount = async (component, rootElement) => {
const mounted = new Vue({
render: h => render(component, h),
}).$mount();

View File

@ -110,7 +110,7 @@ async function innerMount(page: Page, jsxOrType: JsxComponent | string, options:
document.body.appendChild(rootElement);
}
window.playwrightMount(component, rootElement);
await window.playwrightMount(component, rootElement);
// When mounting fragments, return selector pointing to the root element.
return rootElement.childNodes.length > 1 ? '#root' : '#root > *';

View File

@ -37,6 +37,6 @@ export type Component = JsxComponent | ObjectComponent;
declare global {
interface Window {
playwrightMount(component: Component, rootElement: Element): void;
playwrightMount(component: Component, rootElement: Element): Promise<void>;
}
}

View File

@ -0,0 +1,5 @@
import { onApp } from '@playwright/experimental-ct-vue/hooks';
onApp(async (app, addConfig) => {
console.log(`App ${!!app} configured with config: ${JSON.stringify(addConfig)}`);
});

View File

@ -66,3 +66,17 @@ test('optionless should work', async ({ mount }) => {
const component = await mount(Component)
await expect(component).toContainText('test')
})
test('should configure app', async ({ page, mount }) => {
const messages = []
page.on('console', m => messages.push(m.text()))
const component = await mount(Button, {
props: {
title: 'Submit'
},
appConfig: {
route: 'A'
}
})
expect(messages).toEqual(['App true configured with config: {\"route\":\"A\"}'])
})