1
+ import 'isomorphic-fetch' ;
2
+
1
3
import {
2
4
checkFilesExist ,
3
5
ensureNxProject ,
@@ -11,6 +13,7 @@ import {
11
13
killPort ,
12
14
stripConsoleColors ,
13
15
killPorts ,
16
+ DEFAULT_E2E_TIMEOUT ,
14
17
} from '@qwikifiers/e2e/utils' ;
15
18
16
19
export function testApplicationBasicBehavior ( generator : 'app' | 'preset' ) {
@@ -33,7 +36,7 @@ export function testApplicationBasicBehavior(generator: 'app' | 'preset') {
33
36
await runNxCommandAsync (
34
37
`generate qwik-nx:${ generator } ${ projectNameParam } --no-interactive`
35
38
) ;
36
- } , 200000 ) ;
39
+ } , DEFAULT_E2E_TIMEOUT ) ;
37
40
38
41
afterAll ( async ( ) => {
39
42
await runNxCommandAsync ( 'reset' ) ;
@@ -43,80 +46,164 @@ export function testApplicationBasicBehavior(generator: 'app' | 'preset') {
43
46
expect ( ( ) => checkFilesExist ( `tsconfig.base.json` ) ) . not . toThrow ( ) ;
44
47
} ) ;
45
48
46
- it ( 'should create qwik-nx' , async ( ) => {
47
- const result = await runNxCommandAsync ( `build ${ project } ` ) ;
48
- expect ( stripConsoleColors ( result . stdout . replace ( / \n | \s / g, '' ) ) ) . toContain (
49
- [
50
- 'Targets to be executed:' ,
51
- `${ project } :build.client` ,
52
- `${ project } :build.ssr` ,
53
- ]
54
- . join ( '' )
55
- . replace ( / \n | \s / g, '' )
56
- ) ;
57
- expect ( result . stdout ) . toContain (
58
- `Successfully ran target build for project ${ project } `
59
- ) ;
60
- expect ( ( ) =>
61
- checkFilesExist ( `dist/apps/${ project } /client/q-manifest.json` )
62
- ) . not . toThrow ( ) ;
63
- expect ( ( ) =>
64
- checkFilesExist ( `dist/apps/${ project } /server/entry.preview.mjs` )
65
- ) . not . toThrow ( ) ;
66
- } , 200000 ) ;
67
-
68
- it ( 'should run build with a specified configuration' , async ( ) => {
69
- // TODO: cloudflare pages or custom configurations should also be tested
70
- const result = await runNxCommandAsync (
71
- `build ${ project } --configuration=preview`
72
- ) ;
73
- expect ( stripConsoleColors ( result . stdout . replace ( / \n | \s / g, '' ) ) ) . toContain (
74
- [
75
- 'Targets to be executed:' ,
76
- `${ project } :build.client:preview` ,
77
- `${ project } :build.ssr:preview` ,
78
- ]
79
- . join ( '' )
80
- . replace ( / \n | \s / g, '' )
81
- ) ;
82
- expect ( result . stdout ) . toContain (
83
- `Successfully ran target build for project ${ project } `
84
- ) ;
85
- } , 200000 ) ;
86
-
87
- it ( 'should serve application in dev mode with custom port' , async ( ) => {
88
- const p = await runCommandUntil (
89
- `run ${ project } :serve --port=${ devServerPort } ` ,
90
- ( output ) => {
91
- return (
92
- output . includes ( 'Local:' ) && output . includes ( `:${ devServerPort } ` )
93
- ) ;
49
+ it (
50
+ 'should create qwik-nx' ,
51
+ async ( ) => {
52
+ const result = await runNxCommandAsync ( `build ${ project } ` ) ;
53
+ expect (
54
+ stripConsoleColors ( result . stdout . replace ( / \n | \s / g, '' ) )
55
+ ) . toContain (
56
+ [
57
+ 'Targets to be executed:' ,
58
+ `${ project } :build.client` ,
59
+ `${ project } :build.ssr` ,
60
+ ]
61
+ . join ( '' )
62
+ . replace ( / \n | \s / g, '' )
63
+ ) ;
64
+ expect ( result . stdout ) . toContain (
65
+ `Successfully ran target build for project ${ project } `
66
+ ) ;
67
+ expect ( ( ) =>
68
+ checkFilesExist ( `dist/apps/${ project } /client/q-manifest.json` )
69
+ ) . not . toThrow ( ) ;
70
+ expect ( ( ) =>
71
+ checkFilesExist ( `dist/apps/${ project } /server/entry.preview.mjs` )
72
+ ) . not . toThrow ( ) ;
73
+ } ,
74
+ DEFAULT_E2E_TIMEOUT
75
+ ) ;
76
+
77
+ it (
78
+ 'should run build with a specified configuration' ,
79
+ async ( ) => {
80
+ // TODO: cloudflare pages or custom configurations should also be tested
81
+ const result = await runNxCommandAsync (
82
+ `build ${ project } --configuration=preview`
83
+ ) ;
84
+ expect (
85
+ stripConsoleColors ( result . stdout . replace ( / \n | \s / g, '' ) )
86
+ ) . toContain (
87
+ [
88
+ 'Targets to be executed:' ,
89
+ `${ project } :build.client:preview` ,
90
+ `${ project } :build.ssr:preview` ,
91
+ ]
92
+ . join ( '' )
93
+ . replace ( / \n | \s / g, '' )
94
+ ) ;
95
+ expect ( result . stdout ) . toContain (
96
+ `Successfully ran target build for project ${ project } `
97
+ ) ;
98
+ } ,
99
+ DEFAULT_E2E_TIMEOUT
100
+ ) ;
101
+
102
+ it (
103
+ 'should serve application in dev mode with custom port' ,
104
+ async ( ) => {
105
+ let host : string | undefined ;
106
+ const p = await runCommandUntil (
107
+ `run ${ project } :serve --port=${ devServerPort } ` ,
108
+ ( output ) => {
109
+ host = getHostOutput ( output , devServerPort ) ;
110
+ return ! ! host ;
111
+ }
112
+ ) ;
113
+ await checkPageResponses ( host ! ) ;
114
+ try {
115
+ await promisifiedTreeKill ( p . pid ! , 'SIGKILL' ) ;
116
+ await killPort ( devServerPort ) ;
117
+ } catch {
118
+ // ignore
94
119
}
95
- ) ;
96
- try {
97
- await promisifiedTreeKill ( p . pid ! , 'SIGKILL' ) ;
98
- await killPort ( devServerPort ) ;
99
- } catch {
100
- // ignore
101
- }
102
- } , 200000 ) ;
103
-
104
- it ( 'should serve application in preview mode with custom port' , async ( ) => {
105
- const p = await runCommandUntil (
106
- `run ${ project } :preview --port=${ previewServerPort } ` ,
107
- ( output ) => {
108
- return (
109
- output . includes ( 'Local:' ) &&
110
- output . includes ( `:${ previewServerPort } ` )
111
- ) ;
120
+ } ,
121
+ DEFAULT_E2E_TIMEOUT
122
+ ) ;
123
+
124
+ it (
125
+ 'should serve application in preview mode with custom port' ,
126
+ async ( ) => {
127
+ let host : string | undefined ;
128
+ const p = await runCommandUntil (
129
+ `run ${ project } :preview --port=${ previewServerPort } ` ,
130
+ ( output ) => {
131
+ host = getHostOutput ( output , previewServerPort ) ;
132
+ return ! ! host ;
133
+ }
134
+ ) ;
135
+ await checkPageResponses ( host ! ) ;
136
+ try {
137
+ await promisifiedTreeKill ( p . pid ! , 'SIGKILL' ) ;
138
+ await killPort ( previewServerPort ) ;
139
+ } catch {
140
+ // ignore
112
141
}
113
- ) ;
114
- try {
115
- await promisifiedTreeKill ( p . pid ! , 'SIGKILL' ) ;
116
- await killPort ( previewServerPort ) ;
117
- } catch {
118
- // ignore
119
- }
120
- } , 200000 ) ;
142
+ } ,
143
+ DEFAULT_E2E_TIMEOUT
144
+ ) ;
121
145
} ) ;
122
146
}
147
+
148
+ async function checkPageResponses ( host : string ) {
149
+ // wait for a while to make sure everything is settled
150
+ await new Promise ( r => setTimeout ( r , 3000 ) ) ;
151
+ const domParser = new DOMParser ( ) ;
152
+ const pages = [ '' , 'flower' ] ;
153
+ for ( const page of pages ) {
154
+ const url = `${ host } /${ page } ` ;
155
+ const res = await fetch ( url , { headers : { accept : 'text/html' } } ) . then (
156
+ ( r ) => r . text ( )
157
+ ) ;
158
+ const html = domParser . parseFromString ( res , 'text/html' ) ;
159
+ expectHtmlOnAPage ( html , page ) ;
160
+ }
161
+ }
162
+
163
+ function getHostOutput ( output : string , port : number ) : string | undefined {
164
+ // extracts the host url from the output message
165
+ // the reason it's done is because it can either be in these formats:
166
+ // http://localhost:4200 or https://127.0.0.1:4200
167
+ const regexp = new RegExp (
168
+ `Local:(?:\\s{3})(http(?:s)?:\\/\\/(?:.+):${ port } )`
169
+ ) ;
170
+ return output . match ( regexp ) ?. [ 1 ] ;
171
+ }
172
+
173
+ function expectHtmlOnAPage ( html : Document , page : string ) {
174
+ switch ( page ) {
175
+ case '' :
176
+ expectHtmlOnARootPage ( html ) ;
177
+ break ;
178
+ case 'flower' :
179
+ expectHtmlOnAFlowerPage ( html ) ;
180
+ break ;
181
+ }
182
+ }
183
+
184
+ function expectHtmlOnARootPage ( html : Document ) {
185
+ expectCommonHtml ( html ) ;
186
+
187
+ expect ( html . querySelector ( '.mindblow' ) ?. textContent ) . toContain (
188
+ 'Blow my mind'
189
+ ) ;
190
+ }
191
+
192
+ function expectHtmlOnAFlowerPage ( html : Document ) {
193
+ expectCommonHtml ( html ) ;
194
+
195
+ expect ( html . querySelector ( 'input[type="range"]' ) ) . toBeTruthy ( ) ;
196
+ }
197
+
198
+ function expectCommonHtml ( html : Document ) {
199
+ const headerLinks = html . querySelectorAll ( 'header li a' ) ;
200
+ expect ( headerLinks . length ) . toBe ( 3 ) ;
201
+ expect ( Array . from ( headerLinks ) . map ( ( l ) => l . textContent ) ) . toEqual ( [
202
+ 'Docs' ,
203
+ 'Examples' ,
204
+ 'Tutorials' ,
205
+ ] ) ;
206
+ expect ( html . querySelector ( 'footer' ) ?. textContent ) . toContain (
207
+ 'Made with ♡ by Builder.io'
208
+ ) ;
209
+ }
0 commit comments