3
3
import fs from 'fs'
4
4
import rimraf from "rimraf" ;
5
5
import path from 'path'
6
- import { emitTest , emitSuite } from '@maxmattone/code-export-browserstack-mocha'
6
+ import codeExport from './browserstack-mocha-export.mjs'
7
+ import { project as projectProcessor } from '@seleniumhq/side-code-export'
7
8
import pkg from '@seleniumhq/side-utils' ;
8
9
import commander from 'commander' ;
9
10
import logger from 'cli-logger' ;
10
- import yaml from 'js-yaml' ;
11
- import Mocha from 'mocha' ;
12
11
import glob from 'glob' ;
13
- import createClone from 'rfdc' ;
14
- import { fileURLToPath } from 'url' ;
15
- const __filename = fileURLToPath ( import . meta. url ) ;
16
- const __dirname = path . dirname ( __filename ) ;
17
-
18
-
19
- const clone = createClone ( ) ;
20
-
21
- const { project : projectProcessor } = pkg ;
22
- import { exec } from "child_process" ;
23
-
12
+ import spawn from 'cross-spawn' ;
13
+ import * as dotenv from 'dotenv' ;
14
+ import { exit } from 'process' ;
15
+ dotenv . config ( ) ;
24
16
commander
25
17
. usage ( '[options] project.side [project.side] [*.side]' )
26
18
. option ( '-d, --debug' , 'output extra debugging' )
27
19
. option ( '-f, --filter <grep regex>' , 'Run tests matching name' )
28
- . option ( '-w, --max-workers <number>' , 'Maximum amount of workers that will run your tests, defaults to 1' )
29
20
. option ( '--base-url <url>' , 'Override the base URL that was set in the IDE' )
30
- . option ( '--config, --config-file <filepath >' , 'Use specified YAML file for configuration. (default: .side.yml )' )
31
- . option ( '--test-timeout <ms >' , 'Timeout value for each tests. ( default: 30000) ')
32
- . option ( '--output-directory <directory >' , 'Write test results to files, format is defined by -- output-format ' )
33
- . option ( '--output-format <@mochajs/json-file-reporter|xunit >' , 'Format for the output file. (default: @mochajs/json-file-reporter) ')
21
+ . option ( '--test-timeout <ms >' , 'Timeout value for each tests (default: 30000 )' )
22
+ . option ( '--browserstack.config <path >' , 'path to browserstack config file, default to browserstack.yml ')
23
+ . option ( '--output-format <json|xunit >' , 'Format for the output file. ' )
24
+ . option ( '--output-file <path >' , 'path for the report file. required if --output-format provided ')
34
25
35
26
commander . parse ( process . argv ) ;
36
27
const options = commander . opts ( ) ;
37
-
38
- options . maxWorkers = options . maxWorkers ? options . maxWorkers : 1
39
28
options . testTimeout = options . testTimeout ? options . testTimeout : 30000
40
- options . configFile = options . configFile ? options . configFile : '.side.yml'
41
29
options . filter = options . filter ? options . filter : ''
42
- options . outputFormat = options . outputFormat ? options . outputFormat : '@mochajs/json-file-reporter '
30
+ options . browserstackConfig = options [ 'browserstack.config' ] ? options [ 'browserstack.config' ] : 'browserstack.yml '
43
31
options . buildFolderPath = '_generated'
44
-
45
32
var conf = { level : options . debug ? logger . DEBUG :logger . INFO } ;
46
33
var log = logger ( conf ) ;
47
34
@@ -54,69 +41,60 @@ const sideFiles = [
54
41
} , new Set ( ) ) ,
55
42
] ;
56
43
57
- var mocha = new Mocha (
58
- {
59
- reporter : "mocha-multi-reporters" ,
60
- grep : options . filter ,
61
- parallel : true ,
62
- jobs : options . maxWorkers ,
63
- timeout : options . testTimeout ,
64
- reporterOptions : {
65
- "reporterEnabled" : "spec" + ( options . outputDirectory ? ', ' + options . outputFormat :'' ) ,
66
- "mochajsJsonFileReporterReporterOptions" : {
67
- "output" : path . join ( options . outputDirectory || '' , "test-output.json" )
68
- } ,
69
- "xunitReporterOptions" : {
70
- "output" : path . join ( options . outputDirectory || '' , "test-output.xunit.xml" )
71
- } ,
72
- }
73
- } ) ;
74
-
75
-
76
44
rimraf . sync ( options . buildFolderPath )
77
45
fs . mkdirSync ( options . buildFolderPath ) ;
78
46
79
- var config
80
- try {
81
- config = yaml . load ( fs . readFileSync ( options . configFile ) ) ;
82
- } catch ( e ) {
83
- log . error ( e ) ;
47
+ function readFile ( filename ) {
48
+ return JSON . parse (
49
+ fs . readFileSync (
50
+ path . join (
51
+ '.' ,
52
+ filename
53
+ )
54
+ )
55
+ )
56
+ }
57
+
58
+ function normalizeProject ( project ) {
59
+ let _project = { ...project }
60
+ _project . suites . forEach ( suite => {
61
+ projectProcessor . normalizeTestsInSuite ( { suite, tests : _project . tests } )
62
+ } )
63
+ _project . url = options . baseUrl ? options . baseUrl : project . url
64
+ return _project
84
65
}
85
66
86
- const projects = sideFiles . map ( name => JSON . parse ( fs . readFileSync ( name ) ) )
87
- var testFileInc = 1 ;
88
- var promises = [ ] ;
89
- projects . forEach ( project => {
90
- project . tests . forEach ( test => {
91
- promises . push ( new Promise ( async ( resolve , reject ) => {
92
- var _config = clone ( config ) ;
93
- _config . capabilities [ 'name' ] = test . name
94
- if ( _config . capabilities [ 'bstack:options' ] == undefined )
67
+ for ( const sideFileName of sideFiles )
68
+ {
69
+ const project = normalizeProject ( readFile ( sideFileName ) )
70
+ for ( const aSuite of project . suites )
71
+ {
72
+ for ( const aTestCase of aSuite . tests )
95
73
{
96
- _config . capabilities [ 'bstack:options' ] = [ ]
74
+ const test = project . tests . find ( test => test . name === aTestCase ) ;
75
+ var results = await codeExport . default . emit . test ( {
76
+ baseUrl : options . baseUrl ? options . baseUrl : project . url ,
77
+ test : test ,
78
+ tests : project . tests ,
79
+ project : project
80
+ } )
81
+ fs . writeFileSync ( path . join (
82
+ options . buildFolderPath ,
83
+ results . filename
84
+ ) , results . body ) ;
97
85
}
98
- _config . capabilities [ 'bstack:options' ] [ 'sessionName' ] = test . name
99
- var packageJson = JSON . parse ( fs . readFileSync ( __dirname + '/package.json' ) ) ;
100
- _config . capabilities [ 'browserstack-side-runner-version' ] = packageJson . version
101
- const result = await emitTest ( {
102
- baseUrl : options . baseUrl ? options . baseUrl : project . url ,
103
- test : test ,
104
- tests : project . tests ,
105
- beforeEachOptions : {
106
- capabilities : _config . capabilities ,
107
- gridUrl : _config . server ,
108
- } , } ) ;
109
- var filename = path . join ( options . buildFolderPath , testFileInc + result . filename ) ;
110
- testFileInc ++ ;
111
- fs . writeFileSync ( filename , result . body ) ;
112
- mocha . addFile ( filename ) ;
113
- resolve ( ) } ) )
114
- } )
115
- } ) ;
116
- Promise . all ( promises ) . then ( ( ) => {
117
- mocha . run ( function ( failures ) {
118
- process . exitCode = failures ? 1 : 0 ; // exit with non-zero status if there were failures
119
- if ( ! options . debug ) rimraf . sync ( options . buildFolderPath )
120
- } ) ;
86
+ }
87
+
88
+ }
89
+
90
+ var reporter = [ ]
91
+ if ( options . outputFormat && options . outputFile )
92
+ reporter = [ '--reporter' , options . outputFormat , '--reporter-options' , 'output=' + options . outputFile ]
93
+
94
+ const testSuiteProcess = spawn . sync ( 'npx' , [ 'browserstack-node-sdk' , 'mocha' , '_generated' , '--timeouts' , options . testTimeout , '-g' , options . filter , '--browserstack.config' , options . browserstackConfig , ...reporter ] , { stdio : 'inherit' , env : { ...process . env , testTimeout : options . testTimeout } } ) ;
121
95
122
- } )
96
+ if ( ! options . debug )
97
+ {
98
+ rimraf . sync ( options . buildFolderPath )
99
+ }
100
+ exit ( testSuiteProcess . status )
0 commit comments