Skip to content

Commit

Permalink
Adding E2E tests for client hydration and HMR (withastro#3374)
Browse files Browse the repository at this point in the history
* adding Tailwind E2E tests with Playwright

* package.json updates

* adding e2e tests to CI workflow

* using e2e for dev tests, mocha for build tests

* refactor: sharing test-utils helpers

* chore: update lockfile

* Adding contributing docs

* Revert "refactor: sharing test-utils helpers"

This reverts commit 48496f4.

* refactor: simpler solution to resolving e2e test fixtures

* chore: updating lockfile

* refactor: cleaning up how URLs are resolved in e2e tests

* install playwright deps in CI

* ensure playwright deps are installed during CI

* adding a basic HMR test for tailwind styles

* using @e2e for playwright test packages

* adding react hydration and HMR tests

* adding hydration and HMR tests  for preact

* adding svelte hydration and HMR tests

* adding solid-js hydration and HMR tests

* adding solid hydration and HMR tests

* adding vue hydration and HMR tests

* adding client:media tests

* fixing Lit hydration and HMR tests

* fixing up the Vue e2e tests

* fixing up svelte tests

* chore: test cleanup

* chore: cleaning up test element IDs

* chore: updating lock file

* chore: update lockfile after merge

* TEMP: disabling React e2e tests

* Revert "TEMP: disabling React e2e tests"

This reverts commit ed1bad9.

* updating to use the new editFiles helper

* chore: updating lock file

* updating lock file

* updating lockfile

* TEMP: watching for console logs

* TEMP: testing typescript tests

* updating test:e2e scripts for config file

* seems like it didn't find the config file?

* use a fresh dev server for each test

* removing Lit tests for now

* Revert "removing Lit tests for now"

This reverts commit 4970a80.

* updating test config for CI

* WIP: disabling HMR tests to track down why they're unreliable

* TEMP: logging to debug HMR test

* afterEach isn't a global in Playwright

* fix: the test's file reset helper was using a URL not filepath

* one last try, why is the HMR test hanging at cleanup?

* resetting files after tailwind HMR test

* create the onNextChange watcher before editFile is called

* moving the file changed sync into editFile()

* code refactor + Astro Component HMR test

* chore: lint fixes

* adding a test suite for the framework-multiple example app
  • Loading branch information
Tony Sullivan authored May 23, 2022
1 parent 1a325d4 commit 7dd326a
Show file tree
Hide file tree
Showing 67 changed files with 1,979 additions and 24 deletions.
42 changes: 42 additions & 0 deletions e2e/astro-component.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { test as base, expect } from '@playwright/test';
import { loadFixture } from './test-utils.js';

const test = base.extend({
astro: async ({}, use) => {
const fixture = await loadFixture({ root: './fixtures/astro-component/' });
await use(fixture);
},
});

let devServer;

test.beforeEach(async ({ astro }) => {
devServer = await astro.startDevServer();
});

test.afterEach(async () => {
await devServer.stop();
});

test.describe('Astro components', () => {
test('HMR', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));

const hero = page.locator('section');
await expect(hero, 'hero has background: white').toHaveCSS(
'background-color',
'rgb(255, 255, 255)'
);
await expect(hero, 'hero has color: black').toHaveCSS('color', 'rgb(0, 0, 0)');

// Edit the Hero component with a new background color
await astro.editFile('./src/components/Hero.astro', (content) =>
content.replace('background: white', 'background: rgb(230, 230, 230)')
);

await expect(hero, 'background color updated').toHaveCSS(
'background-color',
'rgb(230, 230, 230)'
);
});
});
4 changes: 4 additions & 0 deletions e2e/fixtures/astro-component/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { defineConfig } from 'astro/config';

// https://astro.build/config
export default defineConfig({});
8 changes: 8 additions & 0 deletions e2e/fixtures/astro-component/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@e2e/astro-component",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
11 changes: 11 additions & 0 deletions e2e/fixtures/astro-component/src/components/Counter.css
Original file line number Diff line number Diff line change
@@ -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;
}
20 changes: 20 additions & 0 deletions e2e/fixtures/astro-component/src/components/Counter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { h, Fragment } from 'preact';
import { useState } from 'preact/hooks';
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>
</>
);
}
25 changes: 25 additions & 0 deletions e2e/fixtures/astro-component/src/components/Hero.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
export interface Props {
title: string;
}
const { title } = Astro.props as Props;
---

<section>
<h1>{title}</h1>
<slot />
</section>

<style>
section {
width: 100%;
height: 80vh;
background: white;
color: black;
}

h1 {
text-align: center;
}
</style>
5 changes: 5 additions & 0 deletions e2e/fixtures/astro-component/src/components/JSXComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { h } from 'preact';

export default function({ id }) {
return <div id={id}>Preact client:only component</div>
}
16 changes: 16 additions & 0 deletions e2e/fixtures/astro-component/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
import Hero from '../components/Hero.astro';
---

<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<main>
<Hero title="Astro Components">
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
</Hero>
</main>
</body>
</html>
7 changes: 7 additions & 0 deletions e2e/fixtures/lit-component/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'astro/config';
import lit from '@astrojs/lit';

// https://astro.build/config
export default defineConfig({
integrations: [lit()],
});
11 changes: 11 additions & 0 deletions e2e/fixtures/lit-component/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@e2e/lit-component",
"version": "0.0.0",
"private": true,
"dependencies": {
"@astrojs/lit": "workspace:*",
"astro": "workspace:*",
"@webcomponents/template-shadowroot": "^0.1.0",
"lit": "^2.2.3"
}
}
36 changes: 36 additions & 0 deletions e2e/fixtures/lit-component/src/components/Counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { LitElement, html } from 'lit';

export const tagName = 'my-counter';

class Counter extends LitElement {
static get properties() {
return {
count: {
type: Number,
},
};
}

constructor() {
super();
this.count = 0;
}

increment() {
this.count++;
}

render() {
return html`
<div>
<p>Count: ${this.count}</p>
<button type="button" @click=${this.increment}>Increment</button>
<slot />
</div>
`;
}
}

customElements.define(tagName, Counter);
26 changes: 26 additions & 0 deletions e2e/fixtures/lit-component/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
import '../components/Counter.js';
const someProps = {
count: 0,
};
---

<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<my-counter id="client-idle" {...someProps} client:idle>
<h1>Hello, client:idle!</h1>
</my-counter>

<my-counter id="client-load" {...someProps} client:load>
<h1>Hello, client:load!</h1>
</my-counter>

<my-counter id="client-visible" {...someProps} client:visible>
<h1>Hello, client:visible!</h1>
</my-counter>
</body>
</html>
18 changes: 18 additions & 0 deletions e2e/fixtures/lit-component/src/pages/media.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
import '../components/Counter.js';
const someProps = {
count: 0,
};
---

<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<my-counter id="client-media" {...someProps} client:media="(max-width: 50em)">
<h1>Hello, client:media!</h1>
</my-counter>
</body>
</html>
12 changes: 12 additions & 0 deletions e2e/fixtures/multiple-frameworks/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';

// https://astro.build/config
export default defineConfig({
// Enable many frameworks to support all different kinds of components.
integrations: [preact(), react(), svelte(), vue(), solid()],
});
24 changes: 24 additions & 0 deletions e2e/fixtures/multiple-frameworks/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@e2e/multiple-frameworks",
"version": "0.0.0",
"private": true,
"devDependencies": {
"@astrojs/lit": "^0.1.3",
"@astrojs/preact": "^0.1.2",
"@astrojs/react": "^0.1.2",
"@astrojs/solid-js": "^0.1.2",
"@astrojs/svelte": "^0.1.3",
"@astrojs/vue": "^0.1.4",
"astro": "^1.0.0-beta.31"
},
"dependencies": {
"@webcomponents/template-shadowroot": "^0.1.0",
"lit": "^2.2.4",
"preact": "^10.7.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"solid-js": "^1.4.2",
"svelte": "^3.48.0",
"vue": "^3.2.34"
}
}
7 changes: 7 additions & 0 deletions e2e/fixtures/multiple-frameworks/src/components/A.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
const { id } = Astro.props
---

<div id={id} class="children">
<h1>Hello Astro (A)</h1>
</div>
7 changes: 7 additions & 0 deletions e2e/fixtures/multiple-frameworks/src/components/B.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
const { id } = Astro.props
---

<div id={id} class="children">
<h1>Hello Astro (B)</h1>
</div>
33 changes: 33 additions & 0 deletions e2e/fixtures/multiple-frameworks/src/components/LitCounter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { LitElement, html } from 'lit';

export const tagName = 'my-counter';

class Counter extends LitElement {
static get properties() {
return {
count: {
type: Number,
},
};
}

constructor() {
super();
this.count = 0;
}

increment() {
this.count++;
}

render() {
return html`
<div>
<p>Count: ${this.count}</p>
<button type="button" @click=${this.increment}>Increment</button>
</div>
`;
}
}

customElements.define(tagName, Counter);
19 changes: 19 additions & 0 deletions e2e/fixtures/multiple-frameworks/src/components/PreactCounter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useState } from 'preact/hooks';

/** a counter written in Preact */
export function PreactCounter({ children, id }) {
const [count, setCount] = useState(0);
const add = () => setCount((i) => i + 1);
const subtract = () => setCount((i) => i - 1);

return (
<>
<div id={id} class="counter">
<button class="decrement" onClick={subtract}>-</button>
<pre>{count}</pre>
<button class="increment" onClick={add}>+</button>
</div>
<div class="counter-message">{children}</div>
</>
);
}
19 changes: 19 additions & 0 deletions e2e/fixtures/multiple-frameworks/src/components/ReactCounter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useState } from 'react';

/** a counter written in React */
export function Counter({ children, id }) {
const [count, setCount] = useState(0);
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>
</>
);
}
19 changes: 19 additions & 0 deletions e2e/fixtures/multiple-frameworks/src/components/SolidCounter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createSignal } from 'solid-js';

/** a counter written with Solid */
export default function SolidCounter({ children, id }) {
const [count, setCount] = createSignal(0);
const add = () => setCount(count() + 1);
const subtract = () => setCount(count() - 1);

return (
<>
<div id={id} class="counter">
<button class="decrement" onClick={subtract}>-</button>
<pre>{count()}</pre>
<button class="increment" onClick={add}>+</button>
</div>
<div class="counter-message">{children}</div>
</>
);
}
Loading

0 comments on commit 7dd326a

Please sign in to comment.