diff --git a/packages/astro/e2e/fixtures/solid/astro.config.mjs b/packages/astro/e2e/fixtures/solid/astro.config.mjs
new file mode 100644
index 000000000..a6c39b853
--- /dev/null
+++ b/packages/astro/e2e/fixtures/solid/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig } from 'astro/config';
+import solid from '@astrojs/solid-js';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [solid()],
+});
diff --git a/packages/astro/e2e/fixtures/solid/package.json b/packages/astro/e2e/fixtures/solid/package.json
new file mode 100644
index 000000000..d95d4629f
--- /dev/null
+++ b/packages/astro/e2e/fixtures/solid/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "@e2e/solid",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/solid-js": "workspace:*",
+ "astro": "workspace:*",
+ "solid-js": "^1.3.17"
+ }
+}
diff --git a/packages/astro/e2e/fixtures/solid/src/components/Counter.css b/packages/astro/e2e/fixtures/solid/src/components/Counter.css
new file mode 100644
index 000000000..cffdbda7b
--- /dev/null
+++ b/packages/astro/e2e/fixtures/solid/src/components/Counter.css
@@ -0,0 +1,11 @@
+.counter {
+ display: grid;
+ font-size: 2em;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ margin-top: 3em;
+ place-items: center;
+}
+
+.counter-message {
+ text-align: center;
+}
diff --git a/packages/astro/e2e/fixtures/solid/src/components/Counter.jsx b/packages/astro/e2e/fixtures/solid/src/components/Counter.jsx
new file mode 100644
index 000000000..e315033d3
--- /dev/null
+++ b/packages/astro/e2e/fixtures/solid/src/components/Counter.jsx
@@ -0,0 +1,19 @@
+import { createSignal } from 'solid-js';
+import './Counter.css';
+
+export default function Counter({ children, id, count: initialCount = 0 }) {
+ const [count, setCount] = createSignal(initialCount);
+ const add = () => setCount(count() + 1);
+ const subtract = () => setCount(count() - 1);
+
+ return (
+ <>
+
+ {children}
+ >
+ );
+}
diff --git a/packages/astro/e2e/fixtures/solid/src/pages/index.astro b/packages/astro/e2e/fixtures/solid/src/pages/index.astro
new file mode 100644
index 000000000..a49d4db25
--- /dev/null
+++ b/packages/astro/e2e/fixtures/solid/src/pages/index.astro
@@ -0,0 +1,26 @@
+---
+import Counter from '../components/Counter.jsx';
+
+const someProps = {
+ count: 0,
+};
+---
+
+
+
+
+
+
+
+ Hello, client:idle!
+
+
+
+ Hello, client:load!
+
+
+
+ Hello, client:visible!
+
+
+
diff --git a/packages/astro/e2e/fixtures/svelte/package.json b/packages/astro/e2e/fixtures/svelte/package.json
index 81ff25844..80e0661f8 100644
--- a/packages/astro/e2e/fixtures/svelte/package.json
+++ b/packages/astro/e2e/fixtures/svelte/package.json
@@ -1,5 +1,5 @@
{
- "name": "@e2e/react",
+ "name": "@e2e/svelte",
"version": "0.0.0",
"private": true,
"dependencies": {
diff --git a/packages/astro/e2e/solid.test.js b/packages/astro/e2e/solid.test.js
new file mode 100644
index 000000000..0ce073145
--- /dev/null
+++ b/packages/astro/e2e/solid.test.js
@@ -0,0 +1,89 @@
+import { test as base, expect } from '@playwright/test';
+import { loadFixture, onAfterHMR } from './test-utils.js';
+
+const test = base.extend({
+ astro: async ({}, use) => {
+ const fixture = await loadFixture({ root: './fixtures/solid/' });
+ await use(fixture);
+ },
+});
+
+let devServer;
+
+test.beforeAll(async ({ astro }) => {
+ devServer = await astro.startDevServer();
+});
+
+test.afterAll(async ({ astro }) => {
+ await devServer.stop();
+});
+
+test.afterEach(async ({ astro }) => {
+ astro.clean();
+});
+
+test.only('Solid', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ await test.step('client:idle', async () => {
+ const counter = page.locator('#counter-idle');
+ await expect(counter).toBeVisible();
+
+ const count = counter.locator('pre');
+ await expect(count).toHaveText('0');
+
+ const inc = counter.locator('.increment');
+ await inc.click();
+
+ await expect(count).toHaveText('1');
+ });
+
+ await test.step('client:load', async () => {
+ const counter = page.locator('#counter-load');
+ await expect(counter).toBeVisible();
+
+ const count = counter.locator('pre');
+ await expect(count).toHaveText('0');
+
+ const inc = counter.locator('.increment');
+ await inc.click();
+
+ await expect(count).toHaveText('1');
+ });
+
+ await test.step('client:visible', async () => {
+ const counter = page.locator('#counter-visible');
+ await expect(counter).toBeVisible();
+
+ const count = counter.locator('pre');
+ await expect(count).toHaveText('0');
+
+ const inc = counter.locator('.increment');
+ await inc.click();
+
+ await expect(count).toHaveText('1');
+ });
+
+ await test.step('HMR', async () => {
+ const afterHMR = onAfterHMR(page);
+
+ // test 1: updating the page component
+ await astro.writeFile(
+ 'src/pages/index.astro',
+ (original) => original.replace('id="counter-idle" {...someProps}', 'id="counter-idle" count={5}')
+ );
+
+ await afterHMR;
+
+ const count = page.locator('#counter-idle pre');
+ await expect(count).toHaveText('5');
+
+ // test 2: updating imported CSS
+ await astro.writeFile(
+ 'src/components/Counter.css',
+ (original) => original.replace('font-size: 2em;', 'font-size: 24px;')
+ );
+
+ await expect(count).toHaveCSS('font-size', '24px');
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b24296f10..f0a004249 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -683,6 +683,16 @@ importers:
react: 18.1.0
react-dom: 18.1.0_react@18.1.0
+ packages/astro/e2e/fixtures/solid:
+ specifiers:
+ '@astrojs/solid-js': workspace:*
+ astro: workspace:*
+ solid-js: ^1.3.17
+ dependencies:
+ '@astrojs/solid-js': link:../../../../integrations/solid
+ astro: link:../../..
+ solid-js: 1.3.17
+
packages/astro/e2e/fixtures/svelte:
specifiers:
'@astrojs/svelte': workspace:*