@@ -2,170 +2,154 @@ const base = require("@playwright/test");
2
2
const cp = require ( "child_process" ) ;
3
3
const { _android } = require ( "playwright" ) ;
4
4
const clientPlaywrightVersion = cp
5
- . execSync ( "npx playwright --version" )
6
- . toString ( )
7
- . trim ( )
8
- . split ( " " ) [ 1 ] ;
5
+ . execSync ( "npx playwright --version" )
6
+ . toString ( )
7
+ . trim ( )
8
+ . split ( " " ) [ 1 ] ;
9
9
const BrowserStackLocal = require ( "browserstack-local" ) ;
10
10
const util = require ( "util" ) ;
11
11
12
-
13
12
// BrowserStack Specific Capabilities.
14
13
// Set 'browserstack.local:true For Local testing
15
14
const caps = {
16
- osVersion : "13.0" ,
17
- deviceName : "Samsung Galaxy S23" , // "Samsung Galaxy S22 Ultra", "Google Pixel 7 Pro", "OnePlus 9", etc.
18
- browserName : "chrome" ,
19
- realMobile : "true" ,
20
- name : "My android playwright test" ,
21
- build : "playwright-build-1" ,
22
- "browserstack.username" : process . env . BROWSERSTACK_USERNAME || "<USERNAME>" ,
23
- "browserstack.accessKey" :
24
- process . env . BROWSERSTACK_ACCESS_KEY || "<ACCESS_KEY>" ,
25
- ' browserstack.local' : process . env . BROWSERSTACK_LOCAL || false
15
+ osVersion : "13.0" ,
16
+ deviceName : "Samsung Galaxy S23" , // "Samsung Galaxy S22 Ultra", "Google Pixel 7 Pro", "OnePlus 9", etc.
17
+ browserName : "chrome" ,
18
+ realMobile : "true" ,
19
+ name : "My android playwright test" ,
20
+ build : "playwright-build-1" ,
21
+ "browserstack.username" : process . env . BROWSERSTACK_USERNAME || "<USERNAME>" ,
22
+ "browserstack.accessKey" :
23
+ process . env . BROWSERSTACK_ACCESS_KEY || "<ACCESS_KEY>" ,
24
+ " browserstack.local" : process . env . BROWSERSTACK_LOCAL || false ,
26
25
} ;
27
26
28
27
exports . bsLocal = new BrowserStackLocal . Local ( ) ;
29
28
30
29
// replace YOUR_ACCESS_KEY with your key. You can also set an environment variable - "BROWSERSTACK_ACCESS_KEY".
31
30
exports . BS_LOCAL_ARGS = {
32
- key : process . env . BROWSERSTACK_ACCESS_KEY || "ACCESSKEY" ,
31
+ key : process . env . BROWSERSTACK_ACCESS_KEY || "ACCESSKEY" ,
33
32
} ;
34
33
35
34
// Patching the capabilities dynamically according to the project name.
36
35
const patchMobileCaps = ( name , title ) => {
37
- let combination = name . split ( / @ b r o w s e r s t a c k / ) [ 0 ] ;
38
- let [ browerCaps , osCaps ] = combination . split ( / : / ) ;
39
- let [ browser , deviceName ] = browerCaps . split ( / @ / ) ;
40
- let osCapsSplit = osCaps . split ( / / ) ;
41
- let os = osCapsSplit . shift ( ) ;
42
- let osVersion = osCapsSplit . join ( " " ) ;
43
- caps . browser = browser ? browser : "chrome" ;
44
- caps . deviceName = deviceName ? deviceName : "Samsung Galaxy S22 Ultra" ;
45
- caps . osVersion = osVersion ? osVersion : "12.0" ;
46
- caps . name = title ;
47
- caps . realMobile = "true" ;
36
+ let combination = name . split ( / @ b r o w s e r s t a c k / ) [ 0 ] ;
37
+ let [ browerCaps , osCaps ] = combination . split ( / : / ) ;
38
+ let [ browser , deviceName ] = browerCaps . split ( / @ / ) ;
39
+ let osCapsSplit = osCaps . split ( / / ) ;
40
+ let os = osCapsSplit . shift ( ) ;
41
+ let osVersion = osCapsSplit . join ( " " ) ;
42
+ caps . browser = browser ? browser : "chrome" ;
43
+ caps . deviceName = deviceName ? deviceName : "Samsung Galaxy S22 Ultra" ;
44
+ caps . osVersion = osVersion ? osVersion : "12.0" ;
45
+ caps . name = title ;
46
+ caps . realMobile = "true" ;
48
47
} ;
49
48
50
49
const patchCaps = ( name , title ) => {
51
- let combination = name . split ( / @ b r o w s e r s t a c k / ) [ 0 ] ;
52
- let [ browerCaps , osCaps ] = combination . split ( / : / ) ;
53
- let [ browser , browser_version ] = browerCaps . split ( / @ / ) ;
54
- let osCapsSplit = osCaps . split ( / / ) ;
55
- let os = osCapsSplit . shift ( ) ;
56
- let os_version = osCapsSplit . join ( " " ) ;
57
- caps . browser = browser ? browser : "chrome" ;
58
- caps . browser_version = browser_version ? browser_version : "latest" ;
59
- caps . os = os ? os : "osx" ;
60
- caps . os_version = os_version ? os_version : "catalina" ;
61
- caps . name = title ;
50
+ let combination = name . split ( / @ b r o w s e r s t a c k / ) [ 0 ] ;
51
+ let [ browerCaps , osCaps ] = combination . split ( / : / ) ;
52
+ let [ browser , browser_version ] = browerCaps . split ( / @ / ) ;
53
+ let osCapsSplit = osCaps . split ( / / ) ;
54
+ let os = osCapsSplit . shift ( ) ;
55
+ let os_version = osCapsSplit . join ( " " ) ;
56
+ caps . browser = browser ? browser : "chrome" ;
57
+ caps . browser_version = browser_version ? browser_version : "latest" ;
58
+ caps . os = os ? os : "osx" ;
59
+ caps . os_version = os_version ? os_version : "catalina" ;
60
+ caps . name = title ;
62
61
} ;
63
62
64
- const isHash = ( entity ) => Boolean ( entity && typeof ( entity ) === "object" && ! Array . isArray ( entity ) ) ;
65
- const nestedKeyValue = ( hash , keys ) => keys . reduce ( ( hash , key ) => ( isHash ( hash ) ? hash [ key ] : undefined ) , hash ) ;
66
- const isUndefined = val => ( val === undefined || val === null || val === '' ) ;
63
+ const isHash = ( entity ) =>
64
+ Boolean ( entity && typeof entity === "object" && ! Array . isArray ( entity ) ) ;
65
+ const nestedKeyValue = ( hash , keys ) =>
66
+ keys . reduce ( ( hash , key ) => ( isHash ( hash ) ? hash [ key ] : undefined ) , hash ) ;
67
+ const isUndefined = ( val ) => val === undefined || val === null || val === "" ;
67
68
const evaluateSessionStatus = ( status ) => {
68
- if ( ! isUndefined ( status ) ) {
69
- status = status . toLowerCase ( ) ;
70
- }
71
- if ( status === "passed" ) {
72
- return "passed" ;
73
- } else if ( status === "failed" || status === "timedout" ) {
74
- return "failed" ;
75
- } else {
76
- return "" ;
77
- }
78
- }
69
+ if ( ! isUndefined ( status ) ) {
70
+ status = status . toLowerCase ( ) ;
71
+ }
72
+ if ( status === "passed" ) {
73
+ return "passed" ;
74
+ } else if ( status === "failed" || status === "timedout" ) {
75
+ return "failed" ;
76
+ } else {
77
+ return "" ;
78
+ }
79
+ } ;
79
80
80
81
exports . test = base . test . extend ( {
81
- page : async ( { playwright, baseURL } , use , testInfo ) => {
82
- if ( testInfo . project . name . match ( / b r o w s e r s t a c k / ) ) {
83
-
84
- let combination = testInfo . project . name . split ( / @ b r o w s e r s t a c k / ) [ 0 ] ;
85
- let [ browerCaps , osCaps ] = combination . split ( / : / ) ;
86
-
82
+ page : async ( { page, playwright } , use , testInfo ) => {
83
+ if ( testInfo . project . name . match ( / b r o w s e r s t a c k / ) ) {
84
+ let vBrowser , vContext , vDevice ;
85
+ const isMobile = testInfo . project . name . match ( / b r o w s e r s t a c k - m o b i l e / ) ;
86
+ if ( isMobile ) {
87
+ patchMobileCaps (
88
+ testInfo . project . name ,
89
+ `${ testInfo . file } - ${ testInfo . title } `
90
+ ) ;
91
+ vDevice = await playwright . _android . connect (
92
+ `wss://cdp.browserstack.com/playwright?caps=${ encodeURIComponent (
93
+ JSON . stringify ( caps )
94
+ ) } `
95
+ ) ;
96
+ await vDevice . shell ( "am force-stop com.android.chrome" ) ;
97
+ vContext = await vDevice . launchBrowser ( ) ;
98
+ } else {
99
+ patchCaps ( testInfo . project . name , `${ testInfo . title } ` ) ;
100
+ delete caps . osVersion ;
101
+ delete caps . deviceName ;
102
+ delete caps . realMobile ;
103
+ vBrowser = await playwright . chromium . connect ( {
104
+ wsEndpoint :
105
+ `wss://cdp.browserstack.com/playwright?caps=` +
106
+ `${ encodeURIComponent ( JSON . stringify ( caps ) ) } ` ,
107
+ } ) ;
108
+ vContext = await vBrowser . newContext ( testInfo . project . use ) ;
109
+ }
110
+ const vPage = await vContext . newPage ( ) ;
111
+ await use ( vPage ) ;
87
112
88
- if ( osCaps . includes ( "Windows" ) || osCaps . includes ( "OSX" ) || osCaps . includes ( "OS X" ) ) {
89
- patchCaps ( testInfo . project . name , `${ testInfo . title } ` ) ;
90
- delete caps . osVersion ;
91
- delete caps . deviceName ;
92
- delete caps . realMobile ;
93
- //delete caps.os_version;
94
-
95
- const vBrowser = await playwright . chromium . connect ( {
96
- wsEndpoint :
97
- `wss://cdp.browserstack.com/playwright?caps=` +
98
- `${ encodeURIComponent ( JSON . stringify ( caps ) ) } ` ,
99
- } ) ;
100
- const vContext = await vBrowser . newContext ( testInfo . project . use ) ;
101
- const vPage = await vContext . newPage ( ) ;
102
- await use ( vPage ) ;
103
-
104
- await vPage . close ( ) ;
105
- await vBrowser . close ( ) ;
113
+ await vPage . close ( ) ;
106
114
107
- } else {
108
-
109
- patchMobileCaps (
110
- testInfo . project . name ,
111
- `${ testInfo . title } `
112
- ) ;
113
- const device = await base . _android . connect (
114
- `wss://cdp.browserstack.com/playwright?caps=${ encodeURIComponent (
115
- JSON . stringify ( caps )
116
- ) } `
117
- ) ;
118
- await device . shell ( "am force-stop com.android.chrome" ) ;
119
- const context = await device . launchBrowser ( {
120
- baseURL : baseURL ,
121
- } ) ;
122
- const page = await context . newPage ( ) ;
123
- await use ( page ) ;
115
+ if ( isMobile ) {
116
+ await vDevice . close ( ) ;
117
+ } else {
118
+ await vBrowser . close ( ) ;
119
+ }
120
+ } else {
121
+ use ( page ) ;
122
+ }
123
+ } ,
124
124
125
- await context . close ( ) ;
126
- await device . close ( ) ;
127
- }
128
- }
125
+ beforeEach : [
126
+ async ( { page } , use ) => {
127
+ await page
128
+ . context ( )
129
+ . tracing . start ( { screenshots : true , snapshots : true , sources : true } ) ;
130
+ await use ( ) ;
129
131
} ,
132
+ { auto : true } ,
133
+ ] ,
130
134
131
- beforeEach : [
132
- async ( { page } , use ) => {
133
- await page
134
- . context ( )
135
- . tracing . start ( { screenshots : true , snapshots : true , sources : true } ) ;
136
- await use ( ) ;
137
- } ,
138
- { auto : true } ,
139
- ] ,
140
-
141
- afterEach : [
142
- async ( { page } , use , testInfo ) => {
143
- await use ( ) ;
144
- if ( testInfo . status == "failed" ) {
145
- await page
146
- . context ( )
147
- . tracing . stop ( { path : `${ testInfo . outputDir } /trace.zip` } ) ;
148
- await page . screenshot ( { path : `${ testInfo . outputDir } /screenshot.png` } ) ;
149
- await testInfo . attach ( "screenshot" , {
150
- path : `${ testInfo . outputDir } /screenshot.png` ,
151
- contentType : "image/png" ,
152
- } ) ;
153
- await testInfo . attach ( "trace" , {
154
- path : `${ testInfo . outputDir } /trace.zip` ,
155
- contentType : "application/zip" ,
156
- } ) ;
157
- }
158
- } ,
159
- { auto : true } ,
160
- ] ,
135
+ afterEach : [
136
+ async ( { page } , use , testInfo ) => {
137
+ await use ( ) ;
138
+ if ( testInfo . status == "failed" ) {
139
+ await page
140
+ . context ( )
141
+ . tracing . stop ( { path : `${ testInfo . outputDir } /trace.zip` } ) ;
142
+ await page . screenshot ( { path : `${ testInfo . outputDir } /screenshot.png` } ) ;
143
+ await testInfo . attach ( "screenshot" , {
144
+ path : `${ testInfo . outputDir } /screenshot.png` ,
145
+ contentType : "image/png" ,
146
+ } ) ;
147
+ await testInfo . attach ( "trace" , {
148
+ path : `${ testInfo . outputDir } /trace.zip` ,
149
+ contentType : "application/zip" ,
150
+ } ) ;
151
+ }
152
+ } ,
153
+ { auto : true } ,
154
+ ] ,
161
155
} ) ;
162
-
163
- exports . getMobileEndpoint = ( name , title ) => {
164
- patchMobileCaps ( name , title ) ;
165
- delete caps . os_version ;
166
- delete caps . os ;
167
- const cdpUrl = `wss://cdp.browserstack.com/playwright?caps=${ encodeURIComponent (
168
- JSON . stringify ( caps )
169
- ) } `;
170
- return cdpUrl ;
171
- } ;
0 commit comments