From 8e5f0d2bd146efa8769b4ec08929410b5774d59d Mon Sep 17 00:00:00 2001 From: Tony Sullivan Date: Sun, 15 May 2022 13:00:53 -0600 Subject: [PATCH] adding react hydration and HMR tests --- package.json | 1 + .../astro/e2e/fixtures/react/astro.config.mjs | 7 ++ .../astro/e2e/fixtures/react/package.json | 11 ++ .../fixtures/react/src/components/Counter.css | 11 ++ .../fixtures/react/src/components/Counter.jsx | 19 +++ .../react/src/components/JSXComponent.jsx | 5 + .../e2e/fixtures/react/src/pages/index.astro | 29 +++++ packages/astro/e2e/react.test.js | 109 ++++++++++++++++++ packages/astro/package.json | 3 +- pnpm-lock.yaml | 12 ++ 10 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 packages/astro/e2e/fixtures/react/astro.config.mjs create mode 100644 packages/astro/e2e/fixtures/react/package.json create mode 100644 packages/astro/e2e/fixtures/react/src/components/Counter.css create mode 100644 packages/astro/e2e/fixtures/react/src/components/Counter.jsx create mode 100644 packages/astro/e2e/fixtures/react/src/components/JSXComponent.jsx create mode 100644 packages/astro/e2e/fixtures/react/src/pages/index.astro create mode 100644 packages/astro/e2e/react.test.js diff --git a/package.json b/package.json index 9508c7b0b..b143a6f0a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "test:smoke": "node scripts/smoke/index.js", "test:vite-ci": "turbo run test --no-deps --scope=astro --concurrency=1", "test:e2e": "cd packages/astro && pnpm run test:e2e", + "test:e2e:match": "cd packages/astro && pnpm run test:e2e:match", "benchmark": "turbo run benchmark --scope=astro", "lint": "eslint \"packages/**/*.ts\"", "format": "prettier -w .", diff --git a/packages/astro/e2e/fixtures/react/astro.config.mjs b/packages/astro/e2e/fixtures/react/astro.config.mjs new file mode 100644 index 000000000..8a6f1951c --- /dev/null +++ b/packages/astro/e2e/fixtures/react/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import react from '@astrojs/react'; + +// https://astro.build/config +export default defineConfig({ + integrations: [react()], +}); diff --git a/packages/astro/e2e/fixtures/react/package.json b/packages/astro/e2e/fixtures/react/package.json new file mode 100644 index 000000000..f76cc192d --- /dev/null +++ b/packages/astro/e2e/fixtures/react/package.json @@ -0,0 +1,11 @@ +{ + "name": "@e2e/react", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/react": "workspace:*", + "astro": "workspace:*", + "react": "^18.1.0", + "react-dom": "^18.1.0" + } +} diff --git a/packages/astro/e2e/fixtures/react/src/components/Counter.css b/packages/astro/e2e/fixtures/react/src/components/Counter.css new file mode 100644 index 000000000..fb21044d7 --- /dev/null +++ b/packages/astro/e2e/fixtures/react/src/components/Counter.css @@ -0,0 +1,11 @@ +.counter { + display: grid; + font-size: 2em; + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-top: 2em; + place-items: center; +} + +.counter-message { + text-align: center; +} diff --git a/packages/astro/e2e/fixtures/react/src/components/Counter.jsx b/packages/astro/e2e/fixtures/react/src/components/Counter.jsx new file mode 100644 index 000000000..769e0cccf --- /dev/null +++ b/packages/astro/e2e/fixtures/react/src/components/Counter.jsx @@ -0,0 +1,19 @@ +import React, { useState } from 'react'; +import './Counter.css'; + +export default function Counter({ children, count: initialCount, id }) { + const [count, setCount] = useState(initialCount); + const add = () => setCount((i) => i + 1); + const subtract = () => setCount((i) => i - 1); + + return ( + <> +
+ +
{count}
+ +
+
{children}
+ + ); +} diff --git a/packages/astro/e2e/fixtures/react/src/components/JSXComponent.jsx b/packages/astro/e2e/fixtures/react/src/components/JSXComponent.jsx new file mode 100644 index 000000000..90a4d7c42 --- /dev/null +++ b/packages/astro/e2e/fixtures/react/src/components/JSXComponent.jsx @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function({ id }) { + return
React client:only component
+} diff --git a/packages/astro/e2e/fixtures/react/src/pages/index.astro b/packages/astro/e2e/fixtures/react/src/pages/index.astro new file mode 100644 index 000000000..163618b13 --- /dev/null +++ b/packages/astro/e2e/fixtures/react/src/pages/index.astro @@ -0,0 +1,29 @@ +--- +import Counter from '../components/Counter.jsx'; +import ReactComponent from '../components/JSXComponent.jsx'; + +const someProps = { + count: 0, +}; +--- + + + + + + + +

Hello, client:idle!

+
+ + +

Hello, client:load!

+
+ + +

Hello, client:visible!

+
+ + + + diff --git a/packages/astro/e2e/react.test.js b/packages/astro/e2e/react.test.js new file mode 100644 index 000000000..0d6bc225b --- /dev/null +++ b/packages/astro/e2e/react.test.js @@ -0,0 +1,109 @@ +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/react/' }); + 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('React', 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('client:only', async () => { + const label = page.locator('#client-only'); + await expect(label).toBeVisible(); + + await expect(label).toHaveText('React client:only component'); + }); + + 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 the react component + await astro.writeFile( + 'src/components/JSXComponent.jsx', + (original) => original.replace('React client:only component', 'Updated react client:only component') + ); + + await afterHMR; + + const label = page.locator('#client-only'); + await expect(label).toBeVisible(); + + await expect(label).toHaveText('Updated react client:only component'); + + // test 3: 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/packages/astro/package.json b/packages/astro/package.json index c4d266a5d..bffad5663 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -73,7 +73,8 @@ "benchmark": "node test/benchmark/dev.bench.js && node test/benchmark/build.bench.js", "test": "mocha --exit --timeout 20000 --ignore **/lit-element.test.js && mocha --timeout 20000 **/lit-element.test.js", "test:match": "mocha --timeout 20000 -g", - "test:e2e": "playwright test e2e" + "test:e2e": "playwright test e2e", + "test:e2e:match": "playwright test e2e -g" }, "dependencies": { "@astrojs/compiler": "^0.14.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 497caf730..7a1d78e6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -661,6 +661,18 @@ importers: chai-as-promised: 7.1.1_chai@4.3.6 mocha: 9.2.2 + packages/astro/e2e/fixtures/react: + specifiers: + '@astrojs/react': workspace:* + astro: workspace:* + react: ^18.1.0 + react-dom: ^18.1.0 + dependencies: + '@astrojs/react': link:../../../../integrations/react + astro: link:../../.. + react: 18.1.0 + react-dom: 18.1.0_react@18.1.0 + packages/astro/e2e/fixtures/tailwindcss: specifiers: '@astrojs/tailwind': workspace:*