Skip to content

Commit d24da3b

Browse files
committed
Add SvelteKit to templte e2e test
1 parent d7640dc commit d24da3b

File tree

2 files changed

+139
-39
lines changed

2 files changed

+139
-39
lines changed

browser/create-template/templates/sveltekit-site/src/lib/components/SiteWrapper.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
--theme-color-bg: #fff;
1919
--theme-color-bg-1: #e3e3e3;
2020
--theme-color-bg-2: #ededed;
21-
--theme-color-accent: hsl(179, 58%, 37%);
21+
--theme-color-accent: hsl(179, 58%, 32%);
2222
--theme-color-alert: hsl(356, 53%, 50%);
2323
--theme-color-text: #000;
2424
--theme-color-text-light: #555555;

browser/e2e/tests/template.spec.ts

Lines changed: 138 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect, test } from '@playwright/test';
22
import AxeBuilder from '@axe-core/playwright';
3-
import { execSync } from 'child_process';
3+
import { exec } from 'child_process';
44
import {
55
before,
66
makeDrivePublic,
@@ -13,24 +13,69 @@ import fs from 'node:fs';
1313
import { spawn, type ChildProcess } from 'node:child_process';
1414
import path from 'node:path';
1515
import kill from 'kill-port';
16+
import { promisify } from 'util';
17+
import { log } from 'node:console';
1618

19+
const execAsync = promisify(exec);
1720
const TEMPLATE_DIR_NAME = 'template-tests';
21+
// test.describe.configure({ mode: 'serial' });
1822

19-
test.describe.configure({ mode: 'serial' });
23+
async function setupTemplateSite(
24+
templateDir: string,
25+
serverUrl: string,
26+
siteType: string,
27+
) {
28+
if (!fs.existsSync(templateDir)) {
29+
fs.mkdirSync(templateDir);
30+
}
2031

21-
const waitForNextServer = (
32+
await execAsync('pnpm link ../create-template');
33+
await execAsync(
34+
`pnpm exec create-template ${templateDir}/${siteType} --template ${siteType} --server-url ${serverUrl}`,
35+
);
36+
37+
const sitePath = `${templateDir}/${siteType}`;
38+
await execAsync('pnpm install', { cwd: sitePath });
39+
await execAsync('pnpm link ../../../cli', { cwd: sitePath });
40+
await execAsync('pnpm link ../../../lib', { cwd: sitePath });
41+
42+
if (siteType === 'nextjs-site') {
43+
await execAsync('pnpm link ../../../react', { cwd: sitePath });
44+
} else if (siteType === 'sveltekit-site') {
45+
await execAsync('pnpm link ../../../svelte', { cwd: sitePath });
46+
}
47+
48+
await execAsync('pnpm update-ontologies', { cwd: sitePath });
49+
}
50+
51+
function startServer(templateDir: string, siteType: string) {
52+
// Adjust runtime commands per template
53+
const command =
54+
siteType === 'nextjs-site'
55+
? 'pnpm run build && pnpm start'
56+
: 'pnpm run build && NO_COLOR=1 pnpm preview';
57+
58+
return spawn(command, {
59+
cwd: `${templateDir}/${siteType}`,
60+
shell: true,
61+
});
62+
}
63+
64+
const waitForServer = (
2265
childProcess: ChildProcess,
2366
timeout = 30000,
2467
): Promise<string> => {
2568
return new Promise((resolve, reject) => {
2669
const timeoutId = setTimeout(() => {
2770
childProcess.kill(); // Kill the process if it times out
28-
reject(new Error('Next.js server took too long to start.'));
71+
reject(new Error('Server took too long to start.'));
2972
}, timeout);
3073

3174
childProcess.stdout?.on('data', data => {
3275
const message = data.toString();
3376

77+
log(message);
78+
3479
const match = message.match(/http:\/\/localhost:\d+/);
3580

3681
if (match) {
@@ -45,17 +90,15 @@ const waitForNextServer = (
4590

4691
if (errorMessage.includes('error')) {
4792
clearTimeout(timeoutId); // Clear the timeout when rejecting
48-
reject(
49-
new Error(`Next.js server encountered an error: ${errorMessage}`),
50-
);
93+
reject(new Error(`Server encountered an error: ${errorMessage}`));
5194
}
5295
});
5396

5497
childProcess.on('exit', code => {
5598
clearTimeout(timeoutId); // Clear the timeout when the process exits
5699

57100
if (code !== 0) {
58-
reject(new Error(`Next.js server process exited with code ${code}`));
101+
reject(new Error(`Server process exited with code ${code}`));
59102
}
60103
});
61104
});
@@ -64,7 +107,7 @@ const waitForNextServer = (
64107
test.describe('Create Next.js Template', () => {
65108
test.beforeEach(before);
66109

67-
test('apply template', async ({ page }) => {
110+
test('apply next-js template', async ({ page }) => {
68111
test.slow();
69112
await signIn(page);
70113
const drive = await newDrive(page);
@@ -82,40 +125,94 @@ test.describe('Create Next.js Template', () => {
82125
});
83126
await applyTemplateButton.click();
84127

85-
if (!fs.existsSync(TEMPLATE_DIR_NAME)) {
86-
fs.mkdirSync(TEMPLATE_DIR_NAME);
128+
await setupTemplateSite(TEMPLATE_DIR_NAME, drive.driveURL, 'nextjs-site');
129+
130+
const child = startServer(TEMPLATE_DIR_NAME, 'nextjs-site');
131+
132+
try {
133+
//start server
134+
const url = await waitForServer(child);
135+
136+
// check if the server is running
137+
const response = await page.goto(url);
138+
expect(response?.status()).toBe(200);
139+
140+
// Check if home is following wcag AA standards
141+
const homeScanResults = await new AxeBuilder({ page }).analyze();
142+
143+
expect(homeScanResults.violations).toEqual([]);
144+
145+
await expect(page.locator('body')).toContainText(
146+
'This is a template site generated with @tomic/template.',
147+
);
148+
149+
await page.goto(`${url}/blog`);
150+
151+
// Check if blog is following wcag AA standards
152+
const blogScanResults = await new AxeBuilder({ page }).analyze();
153+
expect(blogScanResults.violations).toEqual([]);
154+
155+
// Search for a blogpost
156+
const searchInput = page.getByRole('searchbox');
157+
158+
await searchInput.fill('balloon');
159+
await expect(page.locator('body')).toContainText('Balloon');
160+
await expect(page.locator('body')).not.toContainText('coffee');
161+
} finally {
162+
child.kill();
87163
}
164+
});
88165

89-
execSync('pnpm link ../create-template');
90-
execSync(
91-
`pnpm exec create-template ${TEMPLATE_DIR_NAME}/nextjs-template --template nextjs-site --server-url ${drive.driveURL}`,
166+
test.afterEach(async () => {
167+
const dirPath = path.join(
168+
__dirname,
169+
'..',
170+
TEMPLATE_DIR_NAME,
171+
'nextjs-site',
92172
);
93-
execSync(`pnpm install`, {
94-
cwd: `${TEMPLATE_DIR_NAME}/nextjs-template`,
95-
});
96-
execSync('pnpm link ../../../cli', {
97-
cwd: `${TEMPLATE_DIR_NAME}/nextjs-template`,
98-
});
99-
execSync('pnpm link ../../../lib', {
100-
cwd: `${TEMPLATE_DIR_NAME}/nextjs-template`,
101-
});
102-
execSync('pnpm link ../../../react', {
103-
cwd: `${TEMPLATE_DIR_NAME}/nextjs-template`,
104-
});
105173

106-
execSync(`pnpm update-ontologies`, {
107-
cwd: `${TEMPLATE_DIR_NAME}/nextjs-template`,
108-
});
174+
try {
175+
await fs.promises.rm(dirPath, { recursive: true, force: true });
176+
} catch (error) {
177+
console.error(`Failed to delete ${TEMPLATE_DIR_NAME}:`, error);
178+
}
179+
180+
await kill(3000);
181+
});
182+
});
183+
184+
test.describe('Create SvelteKit Template', () => {
185+
test.beforeEach(before);
186+
187+
test('apply sveltekit template', async ({ page }) => {
188+
test.slow();
189+
await signIn(page);
190+
const drive = await newDrive(page);
191+
await makeDrivePublic(page);
192+
193+
// Apply the template in data browser
194+
await page.getByTestId(sideBarNewResourceTestId).click();
195+
await expect(page).toHaveURL(`${FRONTEND_URL}/app/new`);
109196

110-
const child = spawn('pnpm run build && pnpm start', {
111-
cwd: `${TEMPLATE_DIR_NAME}/nextjs-template`,
197+
const button = page.getByTestId('template-button');
198+
await button.click();
112199

113-
shell: true,
200+
const applyTemplateButton = page.getByRole('button', {
201+
name: 'Apply template',
114202
});
203+
await applyTemplateButton.click();
204+
205+
await setupTemplateSite(
206+
TEMPLATE_DIR_NAME,
207+
drive.driveURL,
208+
'sveltekit-site',
209+
);
210+
211+
const child = startServer(TEMPLATE_DIR_NAME, 'sveltekit-site');
115212

116213
try {
117214
//start server
118-
const url = await waitForNextServer(child);
215+
const url = await waitForServer(child);
119216

120217
// check if the server is running
121218
const response = await page.goto(url);
@@ -137,9 +234,7 @@ test.describe('Create Next.js Template', () => {
137234
expect(blogScanResults.violations).toEqual([]);
138235

139236
// Search for a blogpost
140-
const searchInput = page.locator(
141-
'input[aria-label="Search blogposts..."]',
142-
);
237+
const searchInput = page.getByRole('searchbox');
143238
await searchInput.fill('balloon');
144239
await expect(page.locator('body')).toContainText('Balloon');
145240
await expect(page.locator('body')).not.toContainText('coffee');
@@ -149,14 +244,19 @@ test.describe('Create Next.js Template', () => {
149244
});
150245

151246
test.afterEach(async () => {
152-
const dirPath = path.join(__dirname, '..', TEMPLATE_DIR_NAME);
247+
const dirPath = path.join(
248+
__dirname,
249+
'..',
250+
TEMPLATE_DIR_NAME,
251+
'sveltekit-site',
252+
);
153253

154254
try {
155255
await fs.promises.rm(dirPath, { recursive: true, force: true });
156256
} catch (error) {
157257
console.error(`Failed to delete ${TEMPLATE_DIR_NAME}:`, error);
158258
}
159259

160-
await kill(3000);
260+
await kill(4173);
161261
});
162262
});

0 commit comments

Comments
 (0)