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',
});
});