1
1
import { expect , test } from '@playwright/test' ;
2
2
import AxeBuilder from '@axe-core/playwright' ;
3
- import { execSync } from 'child_process' ;
3
+ import { exec } from 'child_process' ;
4
4
import {
5
5
before ,
6
6
makeDrivePublic ,
@@ -13,24 +13,69 @@ import fs from 'node:fs';
13
13
import { spawn , type ChildProcess } from 'node:child_process' ;
14
14
import path from 'node:path' ;
15
15
import kill from 'kill-port' ;
16
+ import { promisify } from 'util' ;
17
+ import { log } from 'node:console' ;
16
18
19
+ const execAsync = promisify ( exec ) ;
17
20
const TEMPLATE_DIR_NAME = 'template-tests' ;
21
+ // test.describe.configure({ mode: 'serial' });
18
22
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
+ }
20
31
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 = (
22
65
childProcess : ChildProcess ,
23
66
timeout = 30000 ,
24
67
) : Promise < string > => {
25
68
return new Promise ( ( resolve , reject ) => {
26
69
const timeoutId = setTimeout ( ( ) => {
27
70
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.' ) ) ;
29
72
} , timeout ) ;
30
73
31
74
childProcess . stdout ?. on ( 'data' , data => {
32
75
const message = data . toString ( ) ;
33
76
77
+ log ( message ) ;
78
+
34
79
const match = message . match ( / h t t p : \/ \/ l o c a l h o s t : \d + / ) ;
35
80
36
81
if ( match ) {
@@ -45,17 +90,15 @@ const waitForNextServer = (
45
90
46
91
if ( errorMessage . includes ( 'error' ) ) {
47
92
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 } ` ) ) ;
51
94
}
52
95
} ) ;
53
96
54
97
childProcess . on ( 'exit' , code => {
55
98
clearTimeout ( timeoutId ) ; // Clear the timeout when the process exits
56
99
57
100
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 } ` ) ) ;
59
102
}
60
103
} ) ;
61
104
} ) ;
@@ -64,7 +107,7 @@ const waitForNextServer = (
64
107
test . describe ( 'Create Next.js Template' , ( ) => {
65
108
test . beforeEach ( before ) ;
66
109
67
- test ( 'apply template' , async ( { page } ) => {
110
+ test ( 'apply next-js template' , async ( { page } ) => {
68
111
test . slow ( ) ;
69
112
await signIn ( page ) ;
70
113
const drive = await newDrive ( page ) ;
@@ -82,40 +125,94 @@ test.describe('Create Next.js Template', () => {
82
125
} ) ;
83
126
await applyTemplateButton . click ( ) ;
84
127
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 ( ) ;
87
163
}
164
+ } ) ;
88
165
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' ,
92
172
) ;
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
- } ) ;
105
173
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` ) ;
109
196
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 ( ) ;
112
199
113
- shell : true ,
200
+ const applyTemplateButton = page . getByRole ( 'button' , {
201
+ name : 'Apply template' ,
114
202
} ) ;
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' ) ;
115
212
116
213
try {
117
214
//start server
118
- const url = await waitForNextServer ( child ) ;
215
+ const url = await waitForServer ( child ) ;
119
216
120
217
// check if the server is running
121
218
const response = await page . goto ( url ) ;
@@ -137,9 +234,7 @@ test.describe('Create Next.js Template', () => {
137
234
expect ( blogScanResults . violations ) . toEqual ( [ ] ) ;
138
235
139
236
// Search for a blogpost
140
- const searchInput = page . locator (
141
- 'input[aria-label="Search blogposts..."]' ,
142
- ) ;
237
+ const searchInput = page . getByRole ( 'searchbox' ) ;
143
238
await searchInput . fill ( 'balloon' ) ;
144
239
await expect ( page . locator ( 'body' ) ) . toContainText ( 'Balloon' ) ;
145
240
await expect ( page . locator ( 'body' ) ) . not . toContainText ( 'coffee' ) ;
@@ -149,14 +244,19 @@ test.describe('Create Next.js Template', () => {
149
244
} ) ;
150
245
151
246
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
+ ) ;
153
253
154
254
try {
155
255
await fs . promises . rm ( dirPath , { recursive : true , force : true } ) ;
156
256
} catch ( error ) {
157
257
console . error ( `Failed to delete ${ TEMPLATE_DIR_NAME } :` , error ) ;
158
258
}
159
259
160
- await kill ( 3000 ) ;
260
+ await kill ( 4173 ) ;
161
261
} ) ;
162
262
} ) ;
0 commit comments