1- import { Browser } from "@playwright/test"
1+ import { Browser , BrowserContext , Page } from "@playwright/test"
22import { Context } from "../types.js"
3- import { delDir , scrollToBottomAndBackToTop , launchBrowsers , closeBrowsers } from "./utils.js"
3+ import * as utils from "./utils.js"
44import constants from './constants.js'
55import chalk from 'chalk' ;
66
7-
8- export async function captureScreenshots ( ctx : Context ) : Promise < number > {
9- // Clean up directory to store screenshots
10- delDir ( 'screenshots' ) ;
11-
12- let browsers : Record < string , Browser > = { } ;
13- let capturedScreenshots : number = 0 ;
7+ async function captureScreenshotsForConfig (
8+ ctx : Context ,
9+ browsers : Record < string , Browser > ,
10+ { name , url , waitForTimeout } : Record < string , any > ,
11+ browserName : string ,
12+ renderViewports : Array < Record < string , any > >
13+ ) : Promise < void > {
1414 let pageOptions = { waitUntil : process . env . SMARTUI_PAGE_WAIT_UNTIL_EVENT || 'load' } ;
15- let totalScreenshots : number = ctx . webStaticConfig . length *
16- ( ( ( ctx . config . web ?. browsers ?. length * ctx . config . web ?. viewports ?. length ) || 0 ) + ( ctx . config . mobile ?. devices ?. length || 0 ) ) ;
15+ let ssId = name . toLowerCase ( ) . replace ( / \s / g, '_' ) ;
16+ let context : BrowserContext ;
17+ let page : Page ;
1718
1819 try {
19- browsers = await launchBrowsers ( ctx ) ;
20-
21- for ( let staticConfig of ctx . webStaticConfig ) {
22- let screenshotId = staticConfig . name . toLowerCase ( ) . replace ( / \s / g, '_' ) ;
23-
24- // capture screenshots for web config
25- if ( ctx . config . web ) {
26- for ( let browserName of ctx . config . web . browsers ) {
27- const browser : Browser = browsers [ browserName ] ;
28- const context = await browser . newContext ( ) ;
29- const page = await context . newPage ( ) ;
30-
31- await page . goto ( staticConfig . url . trim ( ) , pageOptions ) ;
32- for ( let { width, height } of ctx . config . web . viewports ) {
33- let ssPath = `screenshots/${ screenshotId } /${ browserName } -${ width } x${ height } -${ screenshotId } .png` ;
34- await page . setViewportSize ( { width, height : height || constants . MIN_VIEWPORT_HEIGHT } ) ;
35- if ( height === 0 ) await page . evaluate ( scrollToBottomAndBackToTop ) ;
36- await page . waitForTimeout ( staticConfig . waitForTimeout || 0 ) ;
37- await page . screenshot ( { path : ssPath , fullPage : height ? false : true } ) ;
38-
39- browserName = browserName === constants . SAFARI ? constants . PW_WEBKIT : browserName ;
40- await ctx . client . uploadScreenshot ( ctx . build , ssPath , staticConfig . name , browserName , `${ width } ${ height ? `x${ height } ` : `` } ` , ctx . log ) ;
41- capturedScreenshots ++ ;
42-
43- ctx . task . output = chalk . gray ( `screenshots captured: ${ capturedScreenshots } /${ totalScreenshots } ` ) ;
44- }
45-
46- await page . close ( ) ;
47- await context . close ( ) ;
48- }
49- }
20+ const browser = browsers [ browserName ] ;
21+ context = await browser ?. newContext ( ) ;
22+ page = await context ?. newPage ( ) ;
23+
24+ await page ?. goto ( url . trim ( ) , pageOptions ) ;
25+ for ( let { viewport, viewportString, fullPage } of renderViewports ) {
26+ let ssPath = `screenshots/${ ssId } /${ `${ browserName } -${ viewport . width } x${ viewport . height } ` } -${ ssId } .png` ;
27+ await page ?. setViewportSize ( { width : viewport . width , height : viewport . height || constants . MIN_VIEWPORT_HEIGHT } ) ;
28+ if ( fullPage ) await page ?. evaluate ( utils . scrollToBottomAndBackToTop ) ;
29+ await page ?. waitForTimeout ( waitForTimeout || 0 ) ;
30+ await page ?. screenshot ( { path : ssPath , fullPage } ) ;
31+
32+ await ctx . client . uploadScreenshot ( ctx . build , ssPath , name , browserName , viewportString , ctx . log ) ;
33+ }
34+ } catch ( error ) {
35+ throw new Error ( `captureScreenshotsForConfig failed for browser ${ browserName } ; error: ${ error } ` ) ;
36+ } finally {
37+ await page ?. close ( ) ;
38+ await context ?. close ( ) ;
39+ }
40+
41+ }
42+
43+ async function captureScreenshotsAsync (
44+ ctx : Context ,
45+ staticConfig : Record < string , any > ,
46+ browsers : Record < string , Browser >
47+ ) : Promise < void [ ] > {
48+ let capturePromises : Array < Promise < void > > = [ ] ;
49+
50+ // capture screenshots for web config
51+ if ( ctx . config . web ) {
52+ for ( let browserName of ctx . config . web . browsers ) {
53+ let webRenderViewports = utils . getWebRenderViewports ( ctx ) ;
54+ capturePromises . push ( captureScreenshotsForConfig ( ctx , browsers , staticConfig , browserName , webRenderViewports ) )
55+ }
56+ }
57+ // capture screenshots for mobile config
58+ if ( ctx . config . mobile ) {
59+ let mobileRenderViewports = utils . getMobileRenderViewports ( ctx ) ;
60+ if ( mobileRenderViewports [ constants . MOBILE_OS_IOS ] . length ) {
61+ capturePromises . push ( captureScreenshotsForConfig ( ctx , browsers , staticConfig , constants . SAFARI , mobileRenderViewports [ constants . MOBILE_OS_IOS ] ) )
62+ }
63+ if ( mobileRenderViewports [ constants . MOBILE_OS_ANDROID ] . length ) {
64+ capturePromises . push ( captureScreenshotsForConfig ( ctx , browsers , staticConfig , constants . CHROME , mobileRenderViewports [ constants . MOBILE_OS_ANDROID ] ) )
65+ }
66+ }
5067
51- // capture screenshots for mobile config
52- if ( ctx . config . mobile ) {
53- let contextChrome = await browsers [ constants . CHROME ] ?. newContext ( ) ;
54- let contextSafari = await browsers [ constants . SAFARI ] ?. newContext ( ) ;
55- let pageChrome = await contextChrome ?. newPage ( ) ;
56- let pageSafari = await contextSafari ?. newPage ( ) ;
68+ return Promise . all ( capturePromises ) ;
69+ }
70+
71+ async function captureScreenshotsSync (
72+ ctx : Context ,
73+ staticConfig : Record < string , any > ,
74+ browsers : Record < string , Browser >
75+ ) : Promise < void > {
76+ // capture screenshots for web config
77+ if ( ctx . config . web ) {
78+ for ( let browserName of ctx . config . web . browsers ) {
79+ let webRenderViewports = utils . getWebRenderViewports ( ctx ) ;
80+ await captureScreenshotsForConfig ( ctx , browsers , staticConfig , browserName , webRenderViewports ) ;
81+ }
82+ }
83+ // capture screenshots for mobile config
84+ if ( ctx . config . mobile ) {
85+ let mobileRenderViewports = utils . getMobileRenderViewports ( ctx ) ;
86+ if ( mobileRenderViewports [ constants . MOBILE_OS_IOS ] . length ) {
87+ await captureScreenshotsForConfig ( ctx , browsers , staticConfig , constants . SAFARI , mobileRenderViewports [ constants . MOBILE_OS_IOS ] ) ;
88+ }
89+ if ( mobileRenderViewports [ constants . MOBILE_OS_ANDROID ] . length ) {
90+ await captureScreenshotsForConfig ( ctx , browsers , staticConfig , constants . CHROME , mobileRenderViewports [ constants . MOBILE_OS_ANDROID ] ) ;
91+ }
92+ }
93+ }
5794
58- await pageChrome ?. goto ( staticConfig . url . trim ( ) , pageOptions ) ;
59- await pageSafari ?. goto ( staticConfig . url . trim ( ) , pageOptions ) ;
60- for ( let device of ctx . config . mobile . devices ) {
61- let ssPath = `screenshots/${ screenshotId } /${ device . replace ( / \s / g, '_' ) } _${ screenshotId } .png` ;
62- let { width, height } = constants . SUPPORTED_MOBILE_DEVICES [ device ] . viewport ;
63- let portrait = ( ctx . config . mobile . orientation === constants . MOBILE_ORIENTATION_PORTRAIT ) ? true : false ;
95+ export async function captureScreenshots ( ctx : Context ) : Promise < Record < string , any > > {
96+ // Clean up directory to store screenshots
97+ utils . delDir ( 'screenshots' ) ;
6498
65- if ( constants . SUPPORTED_MOBILE_DEVICES [ device ] . os === constants . MOBILE_OS_ANDROID ) {
66- await pageChrome ?. setViewportSize ( { width : portrait ? width : height , height : portrait ? height : width } ) ;
67- if ( ctx . config . mobile . fullPage ) await pageChrome ?. evaluate ( scrollToBottomAndBackToTop ) ;
68- await pageChrome ?. waitForTimeout ( staticConfig . waitForTimeout || 0 ) ;
69- await pageChrome ?. screenshot ( { path : ssPath , fullPage : ctx . config . mobile . fullPage } ) ;
70- await ctx . client . uploadScreenshot ( ctx . build , ssPath , staticConfig . name , constants . CHROME , `${ device } (${ ctx . config . mobile . orientation } )` , ctx . log ) ;
71- } else {
72- await pageSafari ?. setViewportSize ( { width : portrait ? width : height , height : portrait ? height : width } ) ;
73- if ( ctx . config . mobile . fullPage ) await pageChrome ?. evaluate ( scrollToBottomAndBackToTop ) ;
74- await pageSafari ?. waitForTimeout ( staticConfig . waitForTimeout || 0 ) ;
75- await pageSafari ?. screenshot ( { path : ssPath , fullPage : ctx . config . mobile . fullPage } ) ;
76- await ctx . client . uploadScreenshot ( ctx . build , ssPath , staticConfig . name , constants . PW_WEBKIT , `${ device } (${ ctx . config . mobile . orientation } )` , ctx . log ) ;
77- }
99+ let browsers : Record < string , Browser > = { } ;
100+ let capturedScreenshots : number = 0 ;
101+ let output : string = '' ;
78102
79- capturedScreenshots ++ ;
80- ctx . task . output = chalk . gray ( `screenshots captured: ${ capturedScreenshots } /${ totalScreenshots } ` ) ;
81- }
103+ try {
104+ browsers = await utils . launchBrowsers ( ctx ) ;
105+ } catch ( error ) {
106+ await utils . closeBrowsers ( browsers ) ;
107+ ctx . log . debug ( error )
108+ throw new Error ( `Failed launching browsers` ) ;
109+ }
82110
83- await pageChrome ?. close ( ) ;
84- await pageSafari ?. close ( ) ;
85- await contextChrome ?. close ( ) ;
86- await contextSafari ?. close ( ) ;
87- }
111+ for ( let staticConfig of ctx . webStaticConfig ) {
112+ try {
113+ if ( ctx . options . parallel ) await captureScreenshotsAsync ( ctx , staticConfig , browsers ) ;
114+ else await captureScreenshotsSync ( ctx , staticConfig , browsers ) ;
115+
116+ output += ( `${ chalk . gray ( staticConfig . name ) } ${ chalk . green ( '\u{2713}' ) } \n` ) ;
117+ ctx . task . output = output ;
118+ capturedScreenshots ++ ;
119+ } catch ( error ) {
120+ ctx . log . debug ( `screenshot capture failed for ${ JSON . stringify ( staticConfig ) } ; error: ${ error } ` ) ;
121+ output += `${ chalk . gray ( staticConfig . name ) } ${ chalk . red ( '\u{2717}' ) } \n` ;
122+ ctx . task . output = output ;
88123 }
89-
90- await closeBrowsers ( browsers ) ;
91- delDir ( 'screenshots' ) ;
92- } catch ( error ) {
93- await closeBrowsers ( browsers ) ;
94- delDir ( 'screenshots' ) ;
95- throw error ;
96124 }
97125
98- return capturedScreenshots ;
126+ await utils . closeBrowsers ( browsers ) ;
127+ utils . delDir ( 'screenshots' ) ;
128+
129+ return { capturedScreenshots, output } ;
99130}
0 commit comments