From 6ab749be5c60c4b57aae8a0ba6083d010fe3b791 Mon Sep 17 00:00:00 2001 From: hippotastic <6137925+hippotastic@users.noreply.github.com> Date: Sat, 18 Jun 2022 00:34:19 +0200 Subject: [PATCH] Add component hydration in .md E2E tests, refactor (#3610) Co-authored-by: Tony Sullivan Co-authored-by: Nate Moore --- .changeset/hungry-ravens-cheat.md | 5 + .../src/components/JSXComponent.jsx | 2 +- .../preact-component/src/pages/index.astro | 14 +- .../preact-component/src/pages/markdown.md | 31 ++++ .../src/components/JSXComponent.jsx | 2 +- .../react-component/src/pages/index.astro | 12 +- .../react-component/src/pages/markdown.md | 31 ++++ .../src/components/SolidComponent.jsx | 5 + .../solid-component/src/pages/index.astro | 15 +- .../solid-component/src/pages/markdown.md | 31 ++++ .../src/components/Counter.svelte | 3 +- .../src/components/SvelteComponent.svelte | 5 + .../svelte-component/src/pages/index.astro | 23 +-- .../svelte-component/src/pages/markdown.md | 31 ++++ packages/astro/e2e/preact-component.test.js | 156 ++--------------- packages/astro/e2e/react-component.test.js | 156 ++--------------- packages/astro/e2e/shared-component-tests.js | 160 ++++++++++++++++++ packages/astro/e2e/solid-component.test.js | 136 ++------------- packages/astro/e2e/svelte-component.test.js | 130 ++------------ 19 files changed, 399 insertions(+), 549 deletions(-) create mode 100644 .changeset/hungry-ravens-cheat.md create mode 100644 packages/astro/e2e/fixtures/preact-component/src/pages/markdown.md create mode 100644 packages/astro/e2e/fixtures/react-component/src/pages/markdown.md create mode 100644 packages/astro/e2e/fixtures/solid-component/src/components/SolidComponent.jsx create mode 100644 packages/astro/e2e/fixtures/solid-component/src/pages/markdown.md create mode 100644 packages/astro/e2e/fixtures/svelte-component/src/components/SvelteComponent.svelte create mode 100644 packages/astro/e2e/fixtures/svelte-component/src/pages/markdown.md create mode 100644 packages/astro/e2e/shared-component-tests.js diff --git a/.changeset/hungry-ravens-cheat.md b/.changeset/hungry-ravens-cheat.md new file mode 100644 index 000000000..982c0b7bf --- /dev/null +++ b/.changeset/hungry-ravens-cheat.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Add component hydration in Markdown E2E tests diff --git a/packages/astro/e2e/fixtures/preact-component/src/components/JSXComponent.jsx b/packages/astro/e2e/fixtures/preact-component/src/components/JSXComponent.jsx index 6cc7b7858..16b98f6d4 100644 --- a/packages/astro/e2e/fixtures/preact-component/src/components/JSXComponent.jsx +++ b/packages/astro/e2e/fixtures/preact-component/src/components/JSXComponent.jsx @@ -1,5 +1,5 @@ import { h } from 'preact'; export default function({ id }) { - return
Preact client:only component
+ return
Framework client:only component
} diff --git a/packages/astro/e2e/fixtures/preact-component/src/pages/index.astro b/packages/astro/e2e/fixtures/preact-component/src/pages/index.astro index 946b90be0..2fe26a575 100644 --- a/packages/astro/e2e/fixtures/preact-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/preact-component/src/pages/index.astro @@ -8,10 +8,10 @@ const someProps = { --- - - - - + + + +

Hello, server!

@@ -24,14 +24,14 @@ const someProps = {

Hello, client:load!

- +

Hello, client:visible!

- +

Hello, client:media!

- + diff --git a/packages/astro/e2e/fixtures/preact-component/src/pages/markdown.md b/packages/astro/e2e/fixtures/preact-component/src/pages/markdown.md new file mode 100644 index 000000000..c05e2ae52 --- /dev/null +++ b/packages/astro/e2e/fixtures/preact-component/src/pages/markdown.md @@ -0,0 +1,31 @@ +--- +setup: | + import Counter from '../components/Counter.jsx'; + import PreactComponent from '../components/JSXComponent.jsx'; + + const someProps = { + count: 0, + }; +--- + + + # Hello, server! + + + + # Hello, client:idle! + + + + # Hello, client:load! + + + + # Hello, client:visible! + + + + # Hello, client:media! + + + diff --git a/packages/astro/e2e/fixtures/react-component/src/components/JSXComponent.jsx b/packages/astro/e2e/fixtures/react-component/src/components/JSXComponent.jsx index 90a4d7c42..dcafa028c 100644 --- a/packages/astro/e2e/fixtures/react-component/src/components/JSXComponent.jsx +++ b/packages/astro/e2e/fixtures/react-component/src/components/JSXComponent.jsx @@ -1,5 +1,5 @@ import React from 'react'; export default function({ id }) { - return
React client:only component
+ return
Framework client:only component
} diff --git a/packages/astro/e2e/fixtures/react-component/src/pages/index.astro b/packages/astro/e2e/fixtures/react-component/src/pages/index.astro index 388fc1d98..0a9a212d0 100644 --- a/packages/astro/e2e/fixtures/react-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/react-component/src/pages/index.astro @@ -8,10 +8,10 @@ const someProps = { --- - - - - + + + +

Hello, server!

@@ -24,7 +24,7 @@ const someProps = {

Hello, client:load!

- +

Hello, client:visible!

@@ -33,5 +33,5 @@ const someProps = {
- + diff --git a/packages/astro/e2e/fixtures/react-component/src/pages/markdown.md b/packages/astro/e2e/fixtures/react-component/src/pages/markdown.md new file mode 100644 index 000000000..5461fc48a --- /dev/null +++ b/packages/astro/e2e/fixtures/react-component/src/pages/markdown.md @@ -0,0 +1,31 @@ +--- +setup: | + import Counter from '../components/Counter.jsx'; + import ReactComponent from '../components/JSXComponent.jsx'; + + const someProps = { + count: 0, + }; +--- + + + # Hello, server! + + + + # Hello, client:idle! + + + + # Hello, client:load! + + + + # Hello, client:visible! + + + + # Hello, client:media! + + + diff --git a/packages/astro/e2e/fixtures/solid-component/src/components/SolidComponent.jsx b/packages/astro/e2e/fixtures/solid-component/src/components/SolidComponent.jsx new file mode 100644 index 000000000..248fd10d6 --- /dev/null +++ b/packages/astro/e2e/fixtures/solid-component/src/components/SolidComponent.jsx @@ -0,0 +1,5 @@ +export default function SolidComponent({ id }) { + return ( +
Framework client:only component
+ ); +} diff --git a/packages/astro/e2e/fixtures/solid-component/src/pages/index.astro b/packages/astro/e2e/fixtures/solid-component/src/pages/index.astro index 91013ad0e..9cfbedc7c 100644 --- a/packages/astro/e2e/fixtures/solid-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/solid-component/src/pages/index.astro @@ -1,5 +1,6 @@ --- import Counter from '../components/Counter.jsx'; +import SolidComponent from '../components/SolidComponent.jsx'; const someProps = { count: 0, @@ -7,10 +8,10 @@ const someProps = { --- - - - - + + + +

Hello, server!

@@ -23,12 +24,14 @@ const someProps = {

Hello, client:load!

- +

Hello, client:visible!

Hello, client:media!

- + + + diff --git a/packages/astro/e2e/fixtures/solid-component/src/pages/markdown.md b/packages/astro/e2e/fixtures/solid-component/src/pages/markdown.md new file mode 100644 index 000000000..22d546481 --- /dev/null +++ b/packages/astro/e2e/fixtures/solid-component/src/pages/markdown.md @@ -0,0 +1,31 @@ +--- +setup: | + import Counter from '../components/Counter.jsx'; + import SolidComponent from '../components/SolidComponent.jsx'; + + const someProps = { + count: 0, + }; +--- + + + # Hello, server! + + + + # Hello, client:idle! + + + + # Hello, client:load! + + + + # Hello, client:visible! + + + + # Hello, client:media! + + + diff --git a/packages/astro/e2e/fixtures/svelte-component/src/components/Counter.svelte b/packages/astro/e2e/fixtures/svelte-component/src/components/Counter.svelte index a2353f071..2f05ce798 100644 --- a/packages/astro/e2e/fixtures/svelte-component/src/components/Counter.svelte +++ b/packages/astro/e2e/fixtures/svelte-component/src/components/Counter.svelte @@ -1,7 +1,6 @@ + +
Framework client:only component
diff --git a/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro b/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro index 3c8117124..9bd8f23bf 100644 --- a/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/svelte-component/src/pages/index.astro @@ -1,5 +1,6 @@ --- import Counter from '../components/Counter.svelte'; +import SvelteComponent from '../components/SvelteComponent.svelte'; const someProps = { count: 0, @@ -7,28 +8,30 @@ const someProps = { --- - - - - - + + + + +

Hello, server!

- +

Hello, client:idle!

- +

Hello, client:load!

- +

Hello, client:visible!

- +

Hello, client:media!

- + + + diff --git a/packages/astro/e2e/fixtures/svelte-component/src/pages/markdown.md b/packages/astro/e2e/fixtures/svelte-component/src/pages/markdown.md new file mode 100644 index 000000000..0030bccd1 --- /dev/null +++ b/packages/astro/e2e/fixtures/svelte-component/src/pages/markdown.md @@ -0,0 +1,31 @@ +--- +setup: | + import Counter from '../components/Counter.svelte'; + import SvelteComponent from '../components/SvelteComponent.svelte'; + + const someProps = { + count: 0, + }; +--- + + + # Hello, server! + + + + # Hello, client:idle! + + + + # Hello, client:load! + + + + # Hello, client:visible! + + + + # Hello, client:media! + + + diff --git a/packages/astro/e2e/preact-component.test.js b/packages/astro/e2e/preact-component.test.js index c53c28f61..f7b79e9da 100644 --- a/packages/astro/e2e/preact-component.test.js +++ b/packages/astro/e2e/preact-component.test.js @@ -1,145 +1,19 @@ -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/preact-component/' }); - await use(fixture); - }, -}); +const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-component/' }); -let devServer; - -test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); -}); - -test.afterEach(async () => { - await devServer.stop(); -}); - -test.describe('Preact 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, 'count incremented by 1').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('/')); - - const counter = page.locator('#client-load'); - 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: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, '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: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('client:only', async ({ page, astro }) => { - await page.goto(astro.resolveUrl('/')); - - const label = page.locator('#client-only'); - await expect(label, 'component is visible').toBeVisible(); - - await expect(label, 'slot text is visible').toHaveText('Preact client:only component'); - }); - - test('HMR', async ({ page, astro }) => { - await page.goto(astro.resolveUrl('/')); - - const counter = page.locator('#client-idle'); - const count = counter.locator('pre'); - await expect(count, 'initial count is 0').toHaveText('0'); - - // Edit the component's initial count prop - await astro.editFile('./src/pages/index.astro', (original) => - original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}') - ); - - await expect(count, 'count prop updated').toHaveText('5'); - await expect(counter, 'component styles persisted').toHaveCSS('display', 'grid'); - - // Edit the component's slot text - await astro.editFile('./src/components/JSXComponent.jsx', (original) => - original.replace('Preact client:only component', 'Updated preact client:only component') - ); - - const label = page.locator('#client-only'); - await expect(label, 'client:only component is visible').toBeVisible(); - await expect(label, 'client:only slot text is visible').toHaveText( - 'Updated preact client:only component' - ); - - // Edit the imported CSS file - await astro.editFile('./src/components/Counter.css', (original) => - original.replace('font-size: 2em;', 'font-size: 24px;') - ); - - await expect(count, 'imported styles updated').toHaveCSS('font-size', '24px'); +test.describe('Preact components in Astro files', () => { + createTests({ + pageUrl: '/', + pageSourceFilePath: './src/pages/index.astro', + componentFilePath: './src/components/JSXComponent.jsx', + }); +}); + +test.describe('Preact components in Markdown files', () => { + createTests({ + pageUrl: '/markdown/', + pageSourceFilePath: './src/pages/markdown.md', + componentFilePath: './src/components/JSXComponent.jsx', }); }); diff --git a/packages/astro/e2e/react-component.test.js b/packages/astro/e2e/react-component.test.js index de39d512f..05f8c1a87 100644 --- a/packages/astro/e2e/react-component.test.js +++ b/packages/astro/e2e/react-component.test.js @@ -1,145 +1,19 @@ -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/react-component/' }); - await use(fixture); - }, -}); +const { test, createTests } = prepareTestFactory({ root: './fixtures/react-component/' }); -let devServer; - -test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); -}); - -test.afterEach(async () => { - await devServer.stop(); -}); - -test.describe('React 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('/')); - - const counter = page.locator('#client-load'); - 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: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, '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: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('client:only', async ({ page, astro }) => { - await page.goto(astro.resolveUrl('/')); - - const label = page.locator('#client-only'); - await expect(label, 'component is visible').toBeVisible(); - - await expect(label, 'slot text is visible').toHaveText('React client:only component'); - }); - - test('HMR', async ({ page, astro }) => { - await page.goto(astro.resolveUrl('/')); - - const counter = page.locator('#client-idle'); - const count = counter.locator('pre'); - await expect(count, 'initial count is 0').toHaveText('0'); - - // Edit the component's initial count prop - await astro.editFile('./src/pages/index.astro', (original) => - original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}') - ); - - await expect(count, 'count prop updated').toHaveText('5'); - await expect(counter, 'component styles persisted').toHaveCSS('display', 'grid'); - - // Edit the component's slot text - await astro.editFile('./src/components/JSXComponent.jsx', (original) => - original.replace('React client:only component', 'Updated react client:only component') - ); - - const label = page.locator('#client-only'); - await expect(label, 'client:only component is visible').toBeVisible(); - await expect(label, 'client:only slot text is visible').toHaveText( - 'Updated react client:only component' - ); - - // Edit the imported CSS file - await astro.editFile('./src/components/Counter.css', (original) => - original.replace('font-size: 2em;', 'font-size: 24px;') - ); - - await expect(count, 'imported CSS updated').toHaveCSS('font-size', '24px'); +test.describe('React components in Astro files', () => { + createTests({ + pageUrl: '/', + pageSourceFilePath: './src/pages/index.astro', + componentFilePath: './src/components/JSXComponent.jsx', + }); +}); + +test.describe('React components in Markdown files', () => { + createTests({ + pageUrl: '/markdown/', + pageSourceFilePath: './src/pages/markdown.md', + componentFilePath: './src/components/JSXComponent.jsx', }); }); diff --git a/packages/astro/e2e/shared-component-tests.js b/packages/astro/e2e/shared-component-tests.js new file mode 100644 index 000000000..a43b46168 --- /dev/null +++ b/packages/astro/e2e/shared-component-tests.js @@ -0,0 +1,160 @@ +import { test as base, expect } from '@playwright/test'; +import { loadFixture } from './test-utils.js'; + +export function prepareTestFactory({ root }) { + const test = base.extend({ + astro: async ({}, use) => { + const fixture = await loadFixture({ root }); + await use(fixture); + }, + }); + + let devServer; + + test.beforeEach(async ({ astro }) => { + devServer = await astro.startDevServer(); + }); + + test.afterEach(async () => { + await devServer.stop(); + }); + + const createTests = ({ + pageUrl, + pageSourceFilePath, + componentFilePath, + counterCssFilePath, + }) => { + test('server only', async ({ page, astro }) => { + await page.goto(astro.resolveUrl(pageUrl)); + + 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(pageUrl)); + + 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(pageUrl)); + + const counter = page.locator('#client-load'); + 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:visible', async ({ page, astro }) => { + await page.goto(astro.resolveUrl(pageUrl)); + + // Make sure the component is on screen to trigger hydration + const counter = page.locator('#client-visible'); + await counter.scrollIntoViewIfNeeded(); + 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:media', async ({ page, astro }) => { + await page.goto(astro.resolveUrl(pageUrl)); + + 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('client:only', async ({ page, astro }) => { + await page.goto(astro.resolveUrl(pageUrl)); + + const label = page.locator('#client-only'); + await expect(label, 'component is visible').toBeVisible(); + + await expect(label, 'slot text is visible').toHaveText('Framework client:only component'); + }); + + test('HMR', async ({ page, astro }) => { + await page.goto(astro.resolveUrl(pageUrl)); + + const counter = page.locator('#client-idle'); + const count = counter.locator('pre'); + await expect(count, 'initial count is 0').toHaveText('0'); + + // Edit the component's initial count prop + await astro.editFile(pageSourceFilePath, (original) => + original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}') + ); + + await expect(count, 'count prop updated').toHaveText('5'); + await expect(counter, 'component styles persisted').toHaveCSS('display', 'grid'); + + // Edit the client:only component's slot text + await astro.editFile(componentFilePath, (original) => + original.replace('Framework client:only component', 'Updated framework client:only component') + ); + + const label = page.locator('#client-only'); + await expect(label, 'client:only component is visible').toBeVisible(); + await expect(label, 'client:only slot text is visible').toHaveText( + 'Updated framework client:only component' + ); + + // Edit the imported CSS file + await astro.editFile(counterCssFilePath || './src/components/Counter.css', (original) => + original.replace('font-size: 2em;', 'font-size: 24px;') + ); + + await expect(count, 'imported CSS updated').toHaveCSS('font-size', '24px'); + + // Revert our edits + astro.resetAllFiles(); + }); + } + + return { + test, + createTests, + }; +} diff --git a/packages/astro/e2e/solid-component.test.js b/packages/astro/e2e/solid-component.test.js index 149cae3df..3a200c67e 100644 --- a/packages/astro/e2e/solid-component.test.js +++ b/packages/astro/e2e/solid-component.test.js @@ -1,125 +1,19 @@ -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/solid-component/' }); - await use(fixture); - }, -}); +const { test, createTests } = prepareTestFactory({ root: './fixtures/solid-component/' }); -let devServer; - -test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); -}); - -test.afterEach(async () => { - await devServer.stop(); -}); - -test.describe('Solid 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('/')); - - const counter = page.locator('#client-load'); - 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: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, '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: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('/')); - - const counter = page.locator('#client-idle'); - const count = counter.locator('pre'); - await expect(count, 'initial count is 0').toHaveText('0'); - - // Edit the component's initial count prop - await astro.editFile('./src/pages/index.astro', (original) => - original.replace('id="client-idle" {...someProps}', 'id="client-idle" count={5}') - ); - - await expect(counter, 'component styles persisted').toHaveCSS('display', 'grid'); - await expect(count, 'count prop updated').toHaveText('5'); - - // Edit the imported CSS - await astro.editFile('./src/components/Counter.css', (original) => - original.replace('font-size: 2em;', 'font-size: 24px;') - ); - - await expect(count, 'imported CSS updated').toHaveCSS('font-size', '24px'); +test.describe('Solid components in Astro files', () => { + createTests({ + pageUrl: '/', + pageSourceFilePath: './src/pages/index.astro', + componentFilePath: './src/components/SolidComponent.jsx', + }); +}); + +test.describe('Solid components in Markdown files', () => { + createTests({ + pageUrl: '/markdown/', + pageSourceFilePath: './src/pages/markdown.md', + componentFilePath: './src/components/SolidComponent.jsx', }); }); diff --git a/packages/astro/e2e/svelte-component.test.js b/packages/astro/e2e/svelte-component.test.js index de5dc46b2..6ee9f1100 100644 --- a/packages/astro/e2e/svelte-component.test.js +++ b/packages/astro/e2e/svelte-component.test.js @@ -1,117 +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/svelte-component/' }); - await use(fixture); - }, -}); +const { test, createTests } = prepareTestFactory({ root: './fixtures/svelte-component/' }); -let devServer; - -test.beforeEach(async ({ astro }) => { - devServer = await astro.startDevServer(); -}); - -test.afterEach(async () => { - await devServer.stop(); -}); - -test.describe('Svelte 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('/')); - - const counter = page.locator('#client-load'); - 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: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, '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: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:idle!', 'Hello, updated client:idle!') - ); - - const counter = page.locator('#client-idle'); - const label = page.locator('#client-idle-message'); - - await expect(label, 'slot text updated').toHaveText('Hello, updated client:idle!'); - await expect(counter, 'component styles persisted').toHaveCSS('display', 'grid'); +test.describe('Svelte components in Astro files', () => { + createTests({ + pageUrl: '/', + pageSourceFilePath: './src/pages/index.astro', + componentFilePath: './src/components/SvelteComponent.svelte', + counterCssFilePath: './src/components/Counter.svelte', + }); +}); + +test.describe('Svelte components in Markdown files', () => { + createTests({ + pageUrl: '/markdown/', + pageSourceFilePath: './src/pages/markdown.md', + componentFilePath: './src/components/SvelteComponent.svelte', + counterCssFilePath: './src/components/Counter.svelte', }); });