@@ -14,90 +14,91 @@ export function SaucelabsLauncher(args,
1414 captureTimeoutLauncherDecorator ,
1515 retryLauncherDecorator ) {
1616
17- // Apply base class mixins. This would be nice to have typed, but this is a low-priority now.
18- baseLauncherDecorator ( this ) ;
19- captureTimeoutLauncherDecorator ( this ) ;
20- retryLauncherDecorator ( this ) ;
21-
22- // initiate driver with null to not close the tunnel too early
23- connectedDrivers . set ( this . id , null )
24-
25- const log = logger . create ( 'SaucelabsLauncher' ) ;
26- const {
27- startConnect,
28- sauceConnectOptions,
29- seleniumCapabilities,
30- browserName
31- } = processConfig ( config , args ) ;
32-
33- // Setup Browser name that will be printed out by Karma.
34- this . name = browserName + ' on SauceLabs' ;
35-
36- // Listen for the start event from Karma. I know, the API is a bit different to how you
37- // would expect, but we need to follow this approach unless we want to spend more work
38- // improving type safety.
39- this . on ( 'start' , async ( pageUrl : string ) => {
40- if ( startConnect ) {
41- try {
42- // In case the "startConnect" option has been enabled, establish a tunnel and wait
43- // for it being ready. In case a tunnel is already active, this will just continue
44- // without establishing a new one.
45- await sauceConnect . establishTunnel ( seleniumCapabilities , sauceConnectOptions ) ;
46- } catch ( error ) {
47- log . error ( error ) ;
48-
49- this . _done ( 'failure' ) ;
50- return ;
51- }
52- }
53-
54- try {
55- // See the following link for public API of the selenium server.
56- // https://wiki.saucelabs.com/display/DOCS/Instant+Selenium+Node.js+Tests
57- const driver = await remote ( seleniumCapabilities ) ;
58-
59- // Keep track of all connected drivers because it's possible that there are multiple
60- // driver instances (e.g. when running with concurrency)
61- connectedDrivers . set ( this . id , driver ) ;
62-
63- const sessionId = driver . sessionId
64-
65- log . info ( '%s session at https://saucelabs.com/tests/%s' , browserName , sessionId ) ;
66- log . debug ( 'Opening "%s" on the selenium client' , pageUrl ) ;
67-
68- // Store the information about the current session in the browserMap. This is necessary
69- // because otherwise the Saucelabs reporter is not able to report results.
70- browserMap . set ( this . id , {
71- sessionId,
72- username : seleniumCapabilities . user ,
73- accessKey : seleniumCapabilities . key ,
74- region : seleniumCapabilities . region ,
75- headless : seleniumCapabilities . headless
76- } ) ;
77-
78- await driver . url ( pageUrl ) ;
79- } catch ( e ) {
80- log . error ( e ) ;
81-
82- // Notify karma about the failure.
83- this . _done ( 'failure' ) ;
84- }
85- } ) ;
86-
87- this . on ( 'kill' , async ( done : ( ) => void ) => {
88- try {
89- const driver = connectedDrivers . get ( this . id ) ;
90- await driver . deleteSession ( ) ;
91- } catch ( e ) {
92- // We need to ignore the exception here because we want to make sure that Karma is still
93- // able to retry connecting if Saucelabs itself terminated the session (and not Karma)
94- // For example if the "idleTimeout" is exceeded and Saucelabs errored the session. See:
95- // https://wiki.saucelabs.com/display/DOCS/Test+Didn%27t+See+a+New+Command+for+90+Seconds
96- log . error ( 'Could not quit the Saucelabs selenium connection. Failure message:' ) ;
97- log . error ( e ) ;
98- }
99-
100- connectedDrivers . delete ( this . id )
101- return process . nextTick ( done ) ;
102- } )
17+ // Apply base class mixins. This would be nice to have typed, but this is a low-priority now.
18+ baseLauncherDecorator ( this ) ;
19+ captureTimeoutLauncherDecorator ( this ) ;
20+ retryLauncherDecorator ( this ) ;
21+
22+ // initiate driver with null to not close the tunnel too early
23+ connectedDrivers . set ( this . id , null )
24+
25+ const log = logger . create ( 'SaucelabsLauncher' ) ;
26+ const {
27+ startConnect,
28+ sauceConnectOptions,
29+ seleniumCapabilities,
30+ browserName
31+ } = processConfig ( config , args ) ;
32+
33+ // Setup Browser name that will be printed out by Karma.
34+ this . name = browserName + ' on SauceLabs' ;
35+
36+ // Listen for the start event from Karma. I know, the API is a bit different to how you
37+ // would expect, but we need to follow this approach unless we want to spend more work
38+ // improving type safety.
39+ this . on ( 'start' , async ( pageUrl : string ) => {
40+ if ( startConnect ) {
41+ try {
42+ // In case the "startConnect" option has been enabled, establish a tunnel and wait
43+ // for it being ready. In case a tunnel is already active, this will just continue
44+ // without establishing a new one.
45+ await sauceConnect . establishTunnel ( seleniumCapabilities , sauceConnectOptions ) ;
46+ } catch ( error ) {
47+ log . error ( error ) ;
48+
49+ this . _done ( 'failure' ) ;
50+ return ;
51+ }
52+ }
53+
54+ try {
55+ // See the following link for public API of the selenium server.
56+ // https://wiki.saucelabs.com/display/DOCS/Instant+Selenium+Node.js+Tests
57+ const driver = await remote ( seleniumCapabilities ) ;
58+
59+ // Keep track of all connected drivers because it's possible that there are multiple
60+ // driver instances (e.g. when running with concurrency)
61+ connectedDrivers . set ( this . id , driver ) ;
62+
63+ const sessionId = driver . sessionId
64+
65+ log . info ( '%s session at https://saucelabs.com/tests/%s' , browserName , sessionId ) ;
66+ log . debug ( 'Opening "%s" on the selenium client' , pageUrl ) ;
67+
68+ // Store the information about the current session in the browserMap. This is necessary
69+ // because otherwise the Saucelabs reporter is not able to report results.
70+ browserMap . set ( this . id , {
71+ sessionId,
72+ username : seleniumCapabilities . user ,
73+ accessKey : seleniumCapabilities . key ,
74+ region : seleniumCapabilities . region ,
75+ headless : seleniumCapabilities . headless ,
76+ driver,
77+ } ) ;
78+
79+ await driver . url ( pageUrl ) ;
80+ } catch ( e ) {
81+ log . error ( e ) ;
82+
83+ // Notify karma about the failure.
84+ this . _done ( 'failure' ) ;
85+ }
86+ } ) ;
87+
88+ this . on ( 'kill' , async ( done : ( ) => void ) => {
89+ try {
90+ const driver = connectedDrivers . get ( this . id ) ;
91+ await driver . deleteSession ( ) ;
92+ } catch ( e ) {
93+ // We need to ignore the exception here because we want to make sure that Karma is still
94+ // able to retry connecting if Saucelabs itself terminated the session (and not Karma)
95+ // For example if the "idleTimeout" is exceeded and Saucelabs errored the session. See:
96+ // https://wiki.saucelabs.com/display/DOCS/Test+Didn%27t+See+a+New+Command+for+90+Seconds
97+ log . error ( 'Could not quit the Saucelabs selenium connection. Failure message:' ) ;
98+ log . error ( e ) ;
99+ }
100+
101+ connectedDrivers . delete ( this . id )
102+ return process . nextTick ( done ) ;
103+ } )
103104}
0 commit comments