centralizing test setup with a universal resetAllFiles hook (#3693)
This commit is contained in:
parent
589b840f5a
commit
c7cb5df450
20 changed files with 168 additions and 315 deletions
|
@ -1,13 +1,8 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { expect } from '@playwright/test';
|
||||
import os from 'os';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/astro-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/astro-component/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/client-only/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/client-only/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,44 +1,38 @@
|
|||
<template>
|
||||
<div :id="id" class="counter">
|
||||
<h1><slot /></h1>
|
||||
<button class="decrement" @click="subtract()">-</button>
|
||||
<Result :value="count" />
|
||||
<pre>{{count}}</pre>
|
||||
<button class="increment" @click="add()">+</button>
|
||||
</div>
|
||||
<div :id="messageId" class="message">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import Result from './Result.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Result
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
start: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
stepSize: {
|
||||
type: String,
|
||||
default: "1"
|
||||
count: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const id = props.id;
|
||||
const count = ref(parseInt(props.start))
|
||||
const stepSize = ref(parseInt(props.stepSize))
|
||||
const add = () => (count.value = count.value + stepSize.value);
|
||||
const subtract = () => (count.value = count.value - stepSize.value);
|
||||
const count = ref(props.count);
|
||||
const messageId = `${id}-message`;
|
||||
const add = () => (count.value = count.value + 1);
|
||||
const subtract = () => (count.value = count.value - 1);
|
||||
return {
|
||||
count,
|
||||
id,
|
||||
messageId,
|
||||
add,
|
||||
subtract,
|
||||
};
|
||||
|
@ -47,11 +41,14 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
.counter {
|
||||
display: grid;
|
||||
font-size: 2em;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
margin-top: 2em;
|
||||
place-items: center;
|
||||
}
|
||||
.message {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
<template>
|
||||
<pre>{{ value }}</pre>
|
||||
<my-button>Click Me</my-button>
|
||||
<div :id="id">Framework client:only component</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
|
@ -1,33 +1,37 @@
|
|||
---
|
||||
import Counter from '../components/Counter.vue'
|
||||
import Counter from '../components/Counter.vue';
|
||||
import VueComponent from '../components/VueComponent.vue';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width"
|
||||
/>
|
||||
<title>Vue component</title>
|
||||
<style>
|
||||
:global(:root) {
|
||||
font-family: system-ui;
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<Counter id="server-only" start="0">No Client</Counter>
|
||||
<Counter id="client-load" start="0" client:load>Hello, client:load!</Counter>
|
||||
<!-- Test island deduplication, i.e. same UID as the component above. -->
|
||||
<Counter id="client-load-dup" start="0" client:load>Hello, client:load!</Counter>
|
||||
<!-- Test island deduplication account for non-render affecting props. -->
|
||||
<Counter id="client-load-step" start="0" step-size="2" client:load>Hello, client:load!</Counter>
|
||||
<Counter id="client-idle" start="0" client:idle>Hello, client:idle!</Counter>
|
||||
<!-- Test that two client:visibles have unique uids -->
|
||||
<Counter id="client-visible" start="0" client:visible>Hello, client:visible!</Counter>
|
||||
<Counter id="client-media" start="0" client:media="(max-width: 50rem)">Hello, client:media!</Counter>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Counter id="server-only" {...someProps}>
|
||||
<h1>Hello, server!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
<h1>Hello, client:idle!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
<h1>Hello, client:load!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
<h1>Hello, client:visible!</h1>
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
<h1>Hello, client:media!</h1>
|
||||
</Counter>
|
||||
|
||||
<VueComponent id="client-only" client:only="vue" />
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
setup: |
|
||||
import Counter from '../components/Counter.vue';
|
||||
import VueComponent from '../components/VueComponent.vue';
|
||||
|
||||
const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
---
|
||||
|
||||
<Counter id="server-only" {...someProps}>
|
||||
# Hello, server!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
# Hello, client:idle!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
# Hello, client:load!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
# Hello, client:visible!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
# Hello, client:media!
|
||||
</Counter>
|
||||
|
||||
<VueComponent id="client-only" client:only="vue" />
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/lit-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/lit-component/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/multiple-frameworks/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/multiple-frameworks/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/nested-in-preact/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/nested-in-preact/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/nested-in-react/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/nested-in-react/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/nested-in-solid/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/nested-in-solid/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/nested-in-svelte/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/nested-in-svelte/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/nested-in-vue/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/nested-in-vue/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/nested-styles/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/nested-styles/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/pass-js/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/pass-js/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
export function prepareTestFactory({ root }) {
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
export function prepareTestFactory(opts) {
|
||||
const test = testFactory(opts);
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/tailwindcss/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/tailwindcss/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { test as testBase } from '@playwright/test';
|
||||
import { loadFixture as baseLoadFixture } from '../test/test-utils.js';
|
||||
|
||||
export function loadFixture(inlineConfig) {
|
||||
|
@ -11,3 +12,20 @@ export function loadFixture(inlineConfig) {
|
|||
root: new URL(inlineConfig.root, import.meta.url).toString(),
|
||||
});
|
||||
}
|
||||
|
||||
export function testFactory(inlineConfig) {
|
||||
let fixture;
|
||||
|
||||
const test = testBase.extend({
|
||||
astro: async ({}, use) => {
|
||||
fixture = await loadFixture(inlineConfig);
|
||||
await use(fixture);
|
||||
}
|
||||
});
|
||||
|
||||
test.afterEach(() => {
|
||||
fixture.resetAllFiles();
|
||||
});
|
||||
|
||||
return test;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/ts-resolution/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const test = testFactory({ root: './fixtures/ts-resolution/' });
|
||||
|
||||
function runTest(it) {
|
||||
it('client:idle', async ({ page, astro }) => {
|
||||
|
|
|
@ -1,147 +1,21 @@
|
|||
import { test as base, expect } from '@playwright/test';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { prepareTestFactory } from './shared-component-tests.js';
|
||||
|
||||
const test = base.extend({
|
||||
astro: async ({}, use) => {
|
||||
const fixture = await loadFixture({ root: './fixtures/vue-component/' });
|
||||
await use(fixture);
|
||||
},
|
||||
});
|
||||
const { test, createTests } = prepareTestFactory({ root: './fixtures/vue-component/' });
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Vue components', () => {
|
||||
test('server only', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#server-only');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'component not hydrated').toHaveText('0');
|
||||
});
|
||||
|
||||
test('client:idle', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-idle');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:load', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Multiple counters on the page to verify islands aren't sharing state
|
||||
const counter = page.locator('#client-load');
|
||||
const counterDup = page.locator('#client-load-dup');
|
||||
const counterStep = page.locator('#client-load-step');
|
||||
|
||||
await expect(counter).toBeVisible();
|
||||
await expect(counterDup).toBeVisible();
|
||||
await expect(counterStep).toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
const countDup = counterDup.locator('pre');
|
||||
const countStep = counterStep.locator('pre');
|
||||
|
||||
const countInc = counter.locator('.increment');
|
||||
const countDupInc = counterDup.locator('.increment');
|
||||
const countStepInc = counterStep.locator('.increment');
|
||||
|
||||
// Should only increment the first counter
|
||||
await countInc.click();
|
||||
|
||||
await expect(count, 'intial count is 1').toHaveText('1');
|
||||
await expect(countDup, 'initial count is 0').toHaveText('0');
|
||||
await expect(countStep, 'initial count is 0').toHaveText('0');
|
||||
|
||||
// Should only increment the second counter
|
||||
await countDupInc.click();
|
||||
|
||||
await expect(count, "count didn't change").toHaveText('1');
|
||||
await expect(countDup, 'count incremented by 1').toHaveText('1');
|
||||
await expect(countStep, "count didn't change").toHaveText('0');
|
||||
|
||||
// Should only increment the third counter
|
||||
// Expecting an increase of 4 becasuse the component's
|
||||
// step is set to 2
|
||||
await countStepInc.click();
|
||||
await countStepInc.click();
|
||||
|
||||
await expect(count, "count didn't change").toHaveText('1');
|
||||
await expect(countDup, "count didn't change").toHaveText('1');
|
||||
await expect(countStep, 'count incremented by 4').toHaveText('4');
|
||||
});
|
||||
|
||||
test('client:visible', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Make sure the component is on screen to trigger hydration
|
||||
const counter = page.locator('#client-visible');
|
||||
await counter.scrollIntoViewIfNeeded();
|
||||
await expect(counter).toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('client:media', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const counter = page.locator('#client-media');
|
||||
await expect(counter, 'component is visible').toBeVisible();
|
||||
|
||||
const count = counter.locator('pre');
|
||||
await expect(count, 'initial count is 0').toHaveText('0');
|
||||
|
||||
const inc = counter.locator('.increment');
|
||||
await inc.click();
|
||||
await expect(count, 'component not hydrated yet').toHaveText('0');
|
||||
|
||||
// Reset the viewport to hydrate the component (max-width: 50rem)
|
||||
await page.setViewportSize({ width: 414, height: 1124 });
|
||||
await inc.click();
|
||||
await expect(count, 'count incremented by 1').toHaveText('1');
|
||||
});
|
||||
|
||||
test('HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Edit the component's slot text
|
||||
await astro.editFile('./src/pages/index.astro', (original) =>
|
||||
original.replace('Hello, client:visible!', 'Hello, updated client:visible!')
|
||||
);
|
||||
|
||||
const counter = page.locator('#client-visible');
|
||||
const label = counter.locator('h1');
|
||||
|
||||
await expect(label, 'slotted text updated').toHaveText('Hello, updated client:visible!');
|
||||
await expect(counter, 'component styles persisted').toHaveCSS('display', 'grid');
|
||||
test.describe('Vue components in Astro files', () => {
|
||||
createTests({
|
||||
pageUrl: '/',
|
||||
pageSourceFilePath: './src/pages/index.astro',
|
||||
componentFilePath: './src/components/VueComponent.vue',
|
||||
counterCssFilePath: './src/components/Counter.vue',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Vue components in Markdown files', () => {
|
||||
createTests({
|
||||
pageUrl: '/markdown/',
|
||||
pageSourceFilePath: './src/pages/markdown.md',
|
||||
componentFilePath: './src/components/VueComponent.vue',
|
||||
counterCssFilePath: './src/components/Counter.vue',
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue