adding react hydration and HMR tests

This commit is contained in:
Tony Sullivan 2022-05-15 13:00:53 -06:00
parent fe5bb8c50c
commit 8e5f0d2bd1
10 changed files with 206 additions and 1 deletions

View file

@ -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 .",

View file

@ -0,0 +1,7 @@
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
// https://astro.build/config
export default defineConfig({
integrations: [react()],
});

View file

@ -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"
}
}

View file

@ -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;
}

View file

@ -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 (
<>
<div id={id} className="counter">
<button className="decrement" onClick={subtract}>-</button>
<pre>{count}</pre>
<button className="increment" onClick={add}>+</button>
</div>
<div className="counter-message">{children}</div>
</>
);
}

View file

@ -0,0 +1,5 @@
import React from 'react';
export default function({ id }) {
return <div id={id}>React client:only component</div>
}

View file

@ -0,0 +1,29 @@
---
import Counter from '../components/Counter.jsx';
import ReactComponent from '../components/JSXComponent.jsx';
const someProps = {
count: 0,
};
---
<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<Counter id="counter-idle" {...someProps} client:idle>
<h1>Hello, client:idle!</h1>
</Counter>
<Counter id="counter-load" {...someProps} client:load>
<h1>Hello, client:load!</h1>
</Counter>
<Counter id="counter-visible" {...someProps} client:visible>
<h1>Hello, client:visible!</h1>
</Counter>
<ReactComponent id="client-only" client:only="react" />
</body>
</html>

View file

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

View file

@ -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",

View file

@ -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:*