mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
Adds tests for server islands
This commit is contained in:
parent
a86b43d7b1
commit
dc376448bb
17 changed files with 342 additions and 0 deletions
11
packages/astro/e2e/fixtures/server-islands/astro.config.mjs
Normal file
11
packages/astro/e2e/fixtures/server-islands/astro.config.mjs
Normal file
|
@ -0,0 +1,11 @@
|
|||
import mdx from '@astrojs/mdx';
|
||||
import react from '@astrojs/react';
|
||||
import { defineConfig } from 'astro/config';
|
||||
import nodejs from '@astrojs/node';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
output: 'hybrid',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
integrations: [react(), mdx()],
|
||||
});
|
16
packages/astro/e2e/fixtures/server-islands/package.json
Normal file
16
packages/astro/e2e/fixtures/server-islands/package.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "@e2e/server-islands",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/react": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*",
|
||||
"@astrojs/node": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
---
|
||||
<h2 id="island">I am an island</h2>
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
import Island from '../components/Island.astro';
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Island server:defer />
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
import Island from '../components/Island.astro';
|
||||
|
||||
<Island server:defer />
|
59
packages/astro/e2e/server-islands.test.js
Normal file
59
packages/astro/e2e/server-islands.test.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = testFactory({ root: './fixtures/server-islands/' });
|
||||
|
||||
test.describe('Server islands', () => {
|
||||
test.describe('Development', () => {
|
||||
let devServer;
|
||||
|
||||
test.beforeAll(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test('Load content from the server', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
let el = page.locator('#island');
|
||||
|
||||
await expect(el, 'element rendered').toBeVisible();
|
||||
await expect(el, 'should have content').toHaveText('I am an island');
|
||||
});
|
||||
|
||||
test('Can be in an MDX file', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/mdx'));
|
||||
let el = page.locator('#island');
|
||||
|
||||
await expect(el, 'element rendered').toBeVisible();
|
||||
await expect(el, 'should have content').toHaveText('I am an island');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Production', () => {
|
||||
let previewServer;
|
||||
|
||||
test.beforeAll(async ({ astro }) => {
|
||||
// Playwright's Node version doesn't have these functions, so stub them.
|
||||
process.stdout.clearLine = () => {};
|
||||
process.stdout.cursorTo = () => {};
|
||||
await astro.build();
|
||||
previewServer = await astro.preview();
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await previewServer.stop();
|
||||
});
|
||||
|
||||
test('Only one component in prod', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
let el = page.locator('#island');
|
||||
|
||||
await expect(el, 'element rendered').toBeVisible();
|
||||
await expect(el, 'should have content').toHaveText('I am an island');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -69,6 +69,7 @@ export function createEndpoint(manifest: SSRManifest) {
|
|||
|
||||
const instance: ComponentInstance = {
|
||||
default: page,
|
||||
partial: true,
|
||||
};
|
||||
|
||||
return instance;
|
||||
|
|
10
packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs
vendored
Normal file
10
packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import svelte from '@astrojs/svelte';
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
export default defineConfig({
|
||||
output: 'hybrid',
|
||||
integrations: [
|
||||
svelte()
|
||||
]
|
||||
});
|
||||
|
10
packages/astro/test/fixtures/server-islands/hybrid/package.json
vendored
Normal file
10
packages/astro/test/fixtures/server-islands/hybrid/package.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@test/server-islands-hybrid",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/svelte": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"svelte": "^4.2.18"
|
||||
}
|
||||
}
|
4
packages/astro/test/fixtures/server-islands/hybrid/src/components/Island.astro
vendored
Normal file
4
packages/astro/test/fixtures/server-islands/hybrid/src/components/Island.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
|
||||
---
|
||||
<h2 id="island">I'm an island</h2>
|
12
packages/astro/test/fixtures/server-islands/hybrid/src/pages/index.astro
vendored
Normal file
12
packages/astro/test/fixtures/server-islands/hybrid/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
import Island from '../components/Island.astro';
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Testing</h1>
|
||||
<Island server:defer />
|
||||
</body>
|
||||
</html>
|
10
packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs
vendored
Normal file
10
packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import svelte from '@astrojs/svelte';
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
export default defineConfig({
|
||||
output: 'server',
|
||||
integrations: [
|
||||
svelte()
|
||||
]
|
||||
});
|
||||
|
10
packages/astro/test/fixtures/server-islands/ssr/package.json
vendored
Normal file
10
packages/astro/test/fixtures/server-islands/ssr/package.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@test/server-islands-ssr",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/svelte": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"svelte": "^4.2.18"
|
||||
}
|
||||
}
|
4
packages/astro/test/fixtures/server-islands/ssr/src/components/Island.astro
vendored
Normal file
4
packages/astro/test/fixtures/server-islands/ssr/src/components/Island.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
|
||||
---
|
||||
<h2 id="island">I'm an island</h2>
|
12
packages/astro/test/fixtures/server-islands/ssr/src/pages/index.astro
vendored
Normal file
12
packages/astro/test/fixtures/server-islands/ssr/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
import Island from '../components/Island.astro';
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Testing</h1>
|
||||
<Island server:defer />
|
||||
</body>
|
||||
</html>
|
120
packages/astro/test/server-islands.test.js
Normal file
120
packages/astro/test/server-islands.test.js
Normal file
|
@ -0,0 +1,120 @@
|
|||
|
||||
import assert from 'node:assert/strict';
|
||||
import { after, before, describe, it } from 'node:test';
|
||||
import * as cheerio from 'cheerio';
|
||||
import testAdapter from './test-adapter.js';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
describe('Server islands', () => {
|
||||
describe('SSR', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/server-islands/ssr',
|
||||
adapter: testAdapter(),
|
||||
});
|
||||
});
|
||||
|
||||
describe('dev', () => {
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
it('omits the islands HTML', async () => {
|
||||
const res = await fixture.fetch('/');
|
||||
assert.equal(res.status, 200);
|
||||
const html = await res.text();
|
||||
const $ = cheerio.load(html);
|
||||
const serverIslandEl = $('h2#island');
|
||||
assert.equal(serverIslandEl.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prod', () => {
|
||||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('omits the islands HTML', async () => {
|
||||
const app = await fixture.loadTestAdapterApp();
|
||||
const request = new Request('http://example.com/');
|
||||
const response = await app.render(request);
|
||||
const html = await response.text();
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
const serverIslandEl = $('h2#island');
|
||||
assert.equal(serverIslandEl.length, 0);
|
||||
|
||||
const serverIslandScript = $('script[data-island-id]');
|
||||
assert.equal(serverIslandScript.length, 1, 'has the island script');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Hybrid mode', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/server-islands/hybrid',
|
||||
adapter: testAdapter(),
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Omits the island HTML from the static HTML', async () => {
|
||||
let html = await fixture.readFile('/client/index.html');
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
const serverIslandEl = $('h2#island');
|
||||
assert.equal(serverIslandEl.length, 0);
|
||||
|
||||
const serverIslandScript = $('script[data-island-id]');
|
||||
assert.equal(serverIslandScript.length, 1, 'has the island script');
|
||||
});
|
||||
|
||||
describe('prod', () => {
|
||||
async function fetchIsland() {
|
||||
const app = await fixture.loadTestAdapterApp();
|
||||
const request = new Request('http://example.com/_server-islands/Island', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
componentExport: 'default',
|
||||
props: {},
|
||||
slots: {},
|
||||
})
|
||||
});
|
||||
return app.render(request);
|
||||
}
|
||||
|
||||
it('Island returns its HTML', async () => {
|
||||
const response = await fetchIsland();
|
||||
const html = await response.text();
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const serverIslandEl = $('h2#island');
|
||||
assert.equal(serverIslandEl.length, 1);
|
||||
});
|
||||
|
||||
it('Island does not include the doctype', async () => {
|
||||
const response = await fetchIsland();
|
||||
const html = await response.text();
|
||||
console.log(html);
|
||||
|
||||
assert.ok(!/doctype/i.test(html), 'html does not include doctype');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1596,6 +1596,27 @@ importers:
|
|||
specifier: ^18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
|
||||
packages/astro/e2e/fixtures/server-islands:
|
||||
dependencies:
|
||||
'@astrojs/mdx':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../integrations/mdx
|
||||
'@astrojs/node':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../integrations/node
|
||||
'@astrojs/react':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../integrations/react
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
react:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
react-dom:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
|
||||
packages/astro/e2e/fixtures/solid-circular:
|
||||
dependencies:
|
||||
'@astrojs/solid-js':
|
||||
|
@ -3616,6 +3637,30 @@ importers:
|
|||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/server-islands/hybrid:
|
||||
dependencies:
|
||||
'@astrojs/svelte':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../../integrations/svelte
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../../..
|
||||
svelte:
|
||||
specifier: ^4.2.18
|
||||
version: 4.2.18
|
||||
|
||||
packages/astro/test/fixtures/server-islands/ssr:
|
||||
dependencies:
|
||||
'@astrojs/svelte':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../../integrations/svelte
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../../..
|
||||
svelte:
|
||||
specifier: ^4.2.18
|
||||
version: 4.2.18
|
||||
|
||||
packages/astro/test/fixtures/set-html:
|
||||
dependencies:
|
||||
astro:
|
||||
|
|
Loading…
Reference in a new issue