14
14
* See the License for the specific language governing permissions and
15
15
* limitations under the License.
16
16
*/
17
+
17
18
const fs = require ( 'fs' ) ;
18
19
const path = require ( 'path' ) ;
19
20
const rm = require ( 'rimraf' ) . sync ;
20
21
const readline = require ( 'readline' ) ;
21
22
const { TestServer} = require ( '../utils/testserver/' ) ;
23
+ const { Environment} = require ( '../utils/testrunner/Test' ) ;
24
+
25
+ const serverEnvironment = new Environment ( 'TestServer' ) ;
26
+ serverEnvironment . beforeAll ( async state => {
27
+ const assetsPath = path . join ( __dirname , 'assets' ) ;
28
+ const cachedPath = path . join ( __dirname , 'assets' , 'cached' ) ;
29
+
30
+ const port = 8907 + state . parallelIndex * 3 ;
31
+ state . server = await TestServer . create ( assetsPath , port ) ;
32
+ state . server . enableHTTPCache ( cachedPath ) ;
33
+ state . server . PORT = port ;
34
+ state . server . PREFIX = `http://localhost:${ port } ` ;
35
+ state . server . CROSS_PROCESS_PREFIX = `http://127.0.0.1:${ port } ` ;
36
+ state . server . EMPTY_PAGE = `http://localhost:${ port } /empty.html` ;
37
+
38
+ const httpsPort = port + 1 ;
39
+ state . httpsServer = await TestServer . createHTTPS ( assetsPath , httpsPort ) ;
40
+ state . httpsServer . enableHTTPCache ( cachedPath ) ;
41
+ state . httpsServer . PORT = httpsPort ;
42
+ state . httpsServer . PREFIX = `https://localhost:${ httpsPort } ` ;
43
+ state . httpsServer . CROSS_PROCESS_PREFIX = `https://127.0.0.1:${ httpsPort } ` ;
44
+ state . httpsServer . EMPTY_PAGE = `https://localhost:${ httpsPort } /empty.html` ;
22
45
23
- const YELLOW_COLOR = '\x1b[33m' ;
24
- const RESET_COLOR = '\x1b[0m' ;
46
+ const sourcePort = port + 2 ;
47
+ state . sourceServer = await TestServer . create ( path . join ( __dirname , '..' ) , sourcePort ) ;
48
+ state . sourceServer . PORT = sourcePort ;
49
+ state . sourceServer . PREFIX = `http://localhost:${ sourcePort } ` ;
50
+ } ) ;
51
+ serverEnvironment . afterAll ( async ( { server, sourceServer, httpsServer} ) => {
52
+ await Promise . all ( [
53
+ server . stop ( ) ,
54
+ httpsServer . stop ( ) ,
55
+ sourceServer . stop ( ) ,
56
+ ] ) ;
57
+ } ) ;
58
+ serverEnvironment . beforeEach ( async ( { server, httpsServer} ) => {
59
+ server . reset ( ) ;
60
+ httpsServer . reset ( ) ;
61
+ } ) ;
62
+
63
+ const goldenEnvironment = new Environment ( 'Golden' ) ;
64
+ goldenEnvironment . beforeAll ( async ( { browserType} ) => {
65
+ const { OUTPUT_DIR , GOLDEN_DIR } = require ( './utils' ) . testOptions ( browserType ) ;
66
+ if ( fs . existsSync ( OUTPUT_DIR ) )
67
+ rm ( OUTPUT_DIR ) ;
68
+ fs . mkdirSync ( OUTPUT_DIR , { recursive : true } ) ;
69
+ expect . setupGolden ( GOLDEN_DIR , OUTPUT_DIR ) ;
70
+ } ) ;
25
71
26
72
/**
27
73
* @type {TestSuite }
28
74
*/
29
- module . exports . addPlaywrightTests = ( { platform, products, playwrightPath, headless, slowMo, dumpProtocolOnFailure, coverage} ) => {
30
- const MAC = platform === 'darwin' ;
31
- const LINUX = platform === 'linux' ;
32
- const WIN = platform === 'win32' ;
75
+ module . exports . addPlaywrightTests = ( { testRunner, products} ) => {
76
+ const dumpProtocolOnFailure = valueFromEnv ( 'DEBUGP' , false ) ;
77
+ const playwrightPath = require ( './utils' ) . projectRoot ( ) ;
33
78
const playwright = require ( playwrightPath ) ;
34
79
35
- beforeAll ( async state => {
36
- const assetsPath = path . join ( __dirname , 'assets' ) ;
37
- const cachedPath = path . join ( __dirname , 'assets' , 'cached' ) ;
38
-
39
- const port = 8907 + state . parallelIndex * 3 ;
40
- state . server = await TestServer . create ( assetsPath , port ) ;
41
- state . server . enableHTTPCache ( cachedPath ) ;
42
- state . server . PORT = port ;
43
- state . server . PREFIX = `http://localhost:${ port } ` ;
44
- state . server . CROSS_PROCESS_PREFIX = `http://127.0.0.1:${ port } ` ;
45
- state . server . EMPTY_PAGE = `http://localhost:${ port } /empty.html` ;
46
-
47
- const httpsPort = port + 1 ;
48
- state . httpsServer = await TestServer . createHTTPS ( assetsPath , httpsPort ) ;
49
- state . httpsServer . enableHTTPCache ( cachedPath ) ;
50
- state . httpsServer . PORT = httpsPort ;
51
- state . httpsServer . PREFIX = `https://localhost:${ httpsPort } ` ;
52
- state . httpsServer . CROSS_PROCESS_PREFIX = `https://127.0.0.1:${ httpsPort } ` ;
53
- state . httpsServer . EMPTY_PAGE = `https://localhost:${ httpsPort } /empty.html` ;
54
-
55
- const sourcePort = port + 2 ;
56
- state . sourceServer = await TestServer . create ( path . join ( __dirname , '..' ) , sourcePort ) ;
57
- state . sourceServer . PORT = sourcePort ;
58
- state . sourceServer . PREFIX = `http://localhost:${ sourcePort } ` ;
80
+ const playwrightEnvironment = new Environment ( 'Playwright' ) ;
81
+ playwrightEnvironment . beforeAll ( async state => {
82
+ state . playwright = playwright ;
59
83
} ) ;
60
-
61
- afterAll ( async ( { server, sourceServer, httpsServer} ) => {
62
- await Promise . all ( [
63
- server . stop ( ) ,
64
- httpsServer . stop ( ) ,
65
- sourceServer . stop ( ) ,
66
- ] ) ;
84
+ playwrightEnvironment . afterAll ( async state => {
85
+ delete state . playwright ;
67
86
} ) ;
68
87
69
- beforeEach ( async ( { server, httpsServer} ) => {
70
- server . reset ( ) ;
71
- httpsServer . reset ( ) ;
72
- } ) ;
88
+ for ( const product of products ) {
89
+ const browserTypeEnvironment = new Environment ( 'BrowserType' ) ;
90
+ browserTypeEnvironment . beforeAll ( async state => {
91
+ state . browserType = state . playwright [ product . toLowerCase ( ) ] ;
92
+ } ) ;
93
+ browserTypeEnvironment . afterAll ( async state => {
94
+ delete state . browserType ;
95
+ } ) ;
73
96
74
- for ( const productInfo of products ) {
75
- const product = productInfo . product ;
76
- const browserType = playwright [ product . toLowerCase ( ) ] ;
77
- const CHROMIUM = product === 'Chromium' ;
78
- const FFOX = product === 'Firefox' ;
79
- const WEBKIT = product === 'WebKit' ;
80
- const defaultBrowserOptions = {
81
- handleSIGINT : false ,
82
- executablePath : productInfo . executablePath ,
83
- slowMo,
84
- headless,
85
- } ;
86
-
87
- if ( defaultBrowserOptions . executablePath ) {
88
- console . warn ( `${ YELLOW_COLOR } WARN: running ${ product } tests with ${ defaultBrowserOptions . executablePath } ${ RESET_COLOR } ` ) ;
89
- } else {
90
- // Make sure the `npm install` was run after the chromium roll.
91
- if ( ! fs . existsSync ( browserType . executablePath ( ) ) )
92
- throw new Error ( `Browser is not downloaded. Run 'npm install' and try to re-run tests` ) ;
93
- }
97
+ const browserEnvironment = new Environment ( product ) ;
98
+ browserEnvironment . beforeAll ( async state => {
99
+ const { defaultBrowserOptions } = require ( './utils' ) . testOptions ( state . browserType ) ;
100
+ state . browser = await state . browserType . launch ( defaultBrowserOptions ) ;
101
+ state . browserServer = state . browser . _ownedServer ;
102
+ state . _stdout = readline . createInterface ( { input : state . browserServer . process ( ) . stdout } ) ;
103
+ state . _stderr = readline . createInterface ( { input : state . browserServer . process ( ) . stderr } ) ;
104
+ } ) ;
105
+ browserEnvironment . afterAll ( async state => {
106
+ await state . browserServer . close ( ) ;
107
+ state . browser = null ;
108
+ state . browserServer = null ;
109
+ state . _stdout . close ( ) ;
110
+ state . _stderr . close ( ) ;
111
+ } ) ;
112
+ browserEnvironment . beforeEach ( async ( state , testRun ) => {
113
+ const dumpout = data => testRun . log ( `\x1b[33m[pw:stdio:out]\x1b[0m ${ data } ` ) ;
114
+ const dumperr = data => testRun . log ( `\x1b[31m[pw:stdio:err]\x1b[0m ${ data } ` ) ;
115
+ state . _stdout . on ( 'line' , dumpout ) ;
116
+ state . _stderr . on ( 'line' , dumperr ) ;
117
+ if ( dumpProtocolOnFailure )
118
+ state . browser . _debugProtocol . log = data => testRun . log ( `\x1b[32m[pw:protocol]\x1b[0m ${ data } ` ) ;
119
+ state . tearDown = async ( ) => {
120
+ state . _stdout . off ( 'line' , dumpout ) ;
121
+ state . _stderr . off ( 'line' , dumperr ) ;
122
+ if ( dumpProtocolOnFailure )
123
+ delete state . browser . _debugProtocol . log ;
124
+ } ;
125
+ } ) ;
126
+ browserEnvironment . afterEach ( async ( state , test ) => {
127
+ if ( state . browser . contexts ( ) . length !== 0 ) {
128
+ if ( test . result === 'ok' )
129
+ console . warn ( `\nWARNING: test "${ test . fullName ( ) } " (${ test . location ( ) } ) did not close all created contexts!\n` ) ;
130
+ await Promise . all ( state . browser . contexts ( ) . map ( context => context . close ( ) ) ) ;
131
+ }
132
+ await state . tearDown ( ) ;
133
+ } ) ;
94
134
95
- const GOLDEN_DIR = path . join ( __dirname , 'golden-' + product . toLowerCase ( ) ) ;
96
- const OUTPUT_DIR = path . join ( __dirname , 'output-' + product . toLowerCase ( ) ) ;
97
- if ( fs . existsSync ( OUTPUT_DIR ) )
98
- rm ( OUTPUT_DIR ) ;
99
- fs . mkdirSync ( OUTPUT_DIR , { recursive : true } ) ;
100
- expect . setupGolden ( GOLDEN_DIR , OUTPUT_DIR ) ;
101
-
102
- const testOptions = {
103
- FFOX ,
104
- WEBKIT ,
105
- CHROMIUM ,
106
- MAC ,
107
- LINUX ,
108
- WIN ,
109
- browserType,
110
- playwright,
111
- defaultBrowserOptions,
112
- playwrightPath,
113
- headless : ! ! defaultBrowserOptions . headless ,
114
- OUTPUT_DIR ,
115
- } ;
135
+ const pageEnvironment = new Environment ( 'Page' ) ;
136
+ pageEnvironment . beforeEach ( async state => {
137
+ state . context = await state . browser . newContext ( ) ;
138
+ state . page = await state . context . newPage ( ) ;
139
+ } ) ;
140
+ pageEnvironment . afterEach ( async state => {
141
+ await state . context . close ( ) ;
142
+ state . context = null ;
143
+ state . page = null ;
144
+ } ) ;
116
145
117
146
function loadTests ( modulePath ) {
147
+ const testOptions = {
148
+ ...require ( './utils' ) . testOptions ( global . browserType ) ,
149
+ playwright : global . playwright ,
150
+ browserType : global . browserType ,
151
+ } ;
118
152
const module = require ( modulePath ) ;
119
153
if ( typeof module . describe === 'function' )
120
154
describe ( '' , module . describe , testOptions ) ;
@@ -124,58 +158,22 @@ module.exports.addPlaywrightTests = ({platform, products, playwrightPath, headle
124
158
xdescribe ( '' , module . xdescribe , testOptions ) ;
125
159
}
126
160
127
- describe ( product , ( ) => {
128
- describe ( '' , function ( ) {
129
- beforeAll ( async state => {
130
- state . browser = await browserType . launch ( defaultBrowserOptions ) ;
131
- state . browserServer = state . browser . _ownedServer ;
132
- state . _stdout = readline . createInterface ( { input : state . browserServer . process ( ) . stdout } ) ;
133
- state . _stderr = readline . createInterface ( { input : state . browserServer . process ( ) . stderr } ) ;
134
- } ) ;
161
+ testRunner . collector ( ) . useEnvironment ( serverEnvironment ) ; // Custom global environment.
162
+ testRunner . collector ( ) . useEnvironment ( playwrightEnvironment ) ;
135
163
136
- afterAll ( async state => {
137
- await state . browserServer . close ( ) ;
138
- state . browser = null ;
139
- state . browserServer = null ;
140
- state . _stdout . close ( ) ;
141
- state . _stderr . close ( ) ;
142
- } ) ;
164
+ describe ( product , ( ) => {
165
+ // In addition to state, expose these two on global so that describes can access them.
166
+ global . playwright = playwright ;
167
+ global . browserType = playwright [ product . toLowerCase ( ) ] ;
143
168
144
- beforeEach ( async ( state , testRun ) => {
145
- const dumpout = data => testRun . log ( `\x1b[33m[pw:stdio:out]\x1b[0m ${ data } ` ) ;
146
- const dumperr = data => testRun . log ( `\x1b[31m[pw:stdio:err]\x1b[0m ${ data } ` ) ;
147
- state . _stdout . on ( 'line' , dumpout ) ;
148
- state . _stderr . on ( 'line' , dumperr ) ;
149
- if ( dumpProtocolOnFailure )
150
- state . browser . _debugProtocol . log = data => testRun . log ( `\x1b[32m[pw:protocol]\x1b[0m ${ data } ` ) ;
151
- state . tearDown = async ( ) => {
152
- state . _stdout . off ( 'line' , dumpout ) ;
153
- state . _stderr . off ( 'line' , dumperr ) ;
154
- if ( dumpProtocolOnFailure )
155
- delete state . browser . _debugProtocol . log ;
156
- } ;
157
- } ) ;
169
+ testRunner . collector ( ) . useEnvironment ( browserTypeEnvironment ) ;
170
+ testRunner . collector ( ) . useEnvironment ( goldenEnvironment ) ; // Custom environment.
158
171
159
- afterEach ( async ( state , test ) => {
160
- if ( state . browser . contexts ( ) . length !== 0 ) {
161
- if ( test . result === 'ok' )
162
- console . warn ( `\nWARNING: test "${ test . fullName ( ) } " (${ test . location ( ) } ) did not close all created contexts!\n` ) ;
163
- await Promise . all ( state . browser . contexts ( ) . map ( context => context . close ( ) ) ) ;
164
- }
165
- await state . tearDown ( ) ;
166
- } ) ;
172
+ describe ( '' , function ( ) {
173
+ testRunner . collector ( ) . useEnvironment ( browserEnvironment ) ;
167
174
168
175
describe ( '' , function ( ) {
169
- beforeEach ( async state => {
170
- state . context = await state . browser . newContext ( ) ;
171
- state . page = await state . context . newPage ( ) ;
172
- } ) ;
173
-
174
- afterEach ( async state => {
175
- await state . context . close ( ) ;
176
- state . context = null ;
177
- state . page = null ;
178
- } ) ;
176
+ testRunner . collector ( ) . useEnvironment ( pageEnvironment ) ;
179
177
180
178
// Page-level tests that are given a browser, a context and a page.
181
179
// Each test is launched in a new browser context.
@@ -210,7 +208,7 @@ module.exports.addPlaywrightTests = ({platform, products, playwrightPath, headle
210
208
loadTests ( './permissions.spec.js' ) ;
211
209
} ) ;
212
210
213
- describe . skip ( ! CHROMIUM ) ( '[Chromium]' , ( ) => {
211
+ describe . skip ( product !== 'Chromium' ) ( '[Chromium]' , ( ) => {
214
212
loadTests ( './chromium/chromium.spec.js' ) ;
215
213
loadTests ( './chromium/coverage.spec.js' ) ;
216
214
loadTests ( './chromium/pdf.spec.js' ) ;
@@ -236,14 +234,23 @@ module.exports.addPlaywrightTests = ({platform, products, playwrightPath, headle
236
234
loadTests ( './multiclient.spec.js' ) ;
237
235
} ) ;
238
236
239
- describe . skip ( ! CHROMIUM ) ( '[Chromium]' , ( ) => {
237
+ describe . skip ( product !== 'Chromium' ) ( '[Chromium]' , ( ) => {
240
238
loadTests ( './chromium/launcher.spec.js' ) ;
241
239
loadTests ( './chromium/oopif.spec.js' ) ;
242
240
loadTests ( './chromium/tracing.spec.js' ) ;
243
241
} ) ;
244
242
245
- if ( coverage )
243
+ if ( process . env . COVERAGE )
246
244
loadTests ( './apicoverage.spec.js' ) ;
245
+
246
+ delete global . browserType ;
247
+ delete global . playwright ;
247
248
} ) ;
248
249
}
249
250
} ;
251
+
252
+ function valueFromEnv ( name , defaultValue ) {
253
+ if ( ! ( name in process . env ) )
254
+ return defaultValue ;
255
+ return JSON . parse ( process . env [ name ] ) ;
256
+ }
0 commit comments