-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #66 from LambdaTest/stage
Release v3.0.1
- Loading branch information
Showing
11 changed files
with
168 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,130 @@ | ||
import { Browser } from "@playwright/test" | ||
import { Browser, BrowserContext, Page } from "@playwright/test" | ||
import { Context } from "../types.js" | ||
import { delDir, scrollToBottomAndBackToTop, launchBrowsers, closeBrowsers } from "./utils.js" | ||
import * as utils from "./utils.js" | ||
import constants from './constants.js' | ||
import chalk from 'chalk'; | ||
|
||
|
||
export async function captureScreenshots(ctx: Context): Promise<number> { | ||
// Clean up directory to store screenshots | ||
delDir('screenshots'); | ||
|
||
let browsers: Record<string,Browser> = {}; | ||
let capturedScreenshots: number = 0; | ||
async function captureScreenshotsForConfig( | ||
ctx: Context, | ||
browsers: Record<string, Browser>, | ||
{name, url, waitForTimeout}: Record<string, any>, | ||
browserName: string, | ||
renderViewports: Array<Record<string,any>> | ||
): Promise<void> { | ||
let pageOptions = { waitUntil: process.env.SMARTUI_PAGE_WAIT_UNTIL_EVENT || 'load' }; | ||
let totalScreenshots: number = ctx.webStaticConfig.length * | ||
(((ctx.config.web?.browsers?.length * ctx.config.web?.viewports?.length) || 0) + (ctx.config.mobile?.devices?.length || 0)); | ||
let ssId = name.toLowerCase().replace(/\s/g, '_'); | ||
let context: BrowserContext; | ||
let page: Page; | ||
|
||
try { | ||
browsers = await launchBrowsers(ctx); | ||
|
||
for (let staticConfig of ctx.webStaticConfig) { | ||
let screenshotId = staticConfig.name.toLowerCase().replace(/\s/g, '_'); | ||
|
||
// capture screenshots for web config | ||
if (ctx.config.web) { | ||
for (let browserName of ctx.config.web.browsers) { | ||
const browser: Browser = browsers[browserName]; | ||
const context = await browser.newContext(); | ||
const page = await context.newPage(); | ||
|
||
await page.goto(staticConfig.url.trim(), pageOptions); | ||
for (let { width, height } of ctx.config.web.viewports) { | ||
let ssPath = `screenshots/${screenshotId}/${browserName}-${width}x${height}-${screenshotId}.png`; | ||
await page.setViewportSize({ width, height: height || constants.MIN_VIEWPORT_HEIGHT }); | ||
if (height === 0) await page.evaluate(scrollToBottomAndBackToTop); | ||
await page.waitForTimeout(staticConfig.waitForTimeout || 0); | ||
await page.screenshot({ path: ssPath, fullPage: height ? false: true }); | ||
|
||
browserName = browserName === constants.SAFARI ? constants.PW_WEBKIT : browserName; | ||
await ctx.client.uploadScreenshot(ctx.build, ssPath, staticConfig.name, browserName, `${width}${height ? `x${height}` : ``}`, ctx.log); | ||
capturedScreenshots++; | ||
|
||
ctx.task.output = chalk.gray(`screenshots captured: ${capturedScreenshots}/${totalScreenshots}`); | ||
} | ||
|
||
await page.close(); | ||
await context.close(); | ||
} | ||
} | ||
const browser = browsers[browserName]; | ||
context = await browser?.newContext(); | ||
page = await context?.newPage(); | ||
|
||
await page?.goto(url.trim(), pageOptions); | ||
for (let { viewport, viewportString, fullPage } of renderViewports) { | ||
let ssPath = `screenshots/${ssId}/${`${browserName}-${viewport.width}x${viewport.height}`}-${ssId}.png`; | ||
await page?.setViewportSize({ width: viewport.width, height: viewport.height || constants.MIN_VIEWPORT_HEIGHT }); | ||
if (fullPage) await page?.evaluate(utils.scrollToBottomAndBackToTop); | ||
await page?.waitForTimeout(waitForTimeout || 0); | ||
await page?.screenshot({ path: ssPath, fullPage }); | ||
|
||
await ctx.client.uploadScreenshot(ctx.build, ssPath, name, browserName, viewportString, ctx.log); | ||
} | ||
} catch (error) { | ||
throw new Error(`captureScreenshotsForConfig failed for browser ${browserName}; error: ${error}`); | ||
} finally { | ||
await page?.close(); | ||
await context?.close(); | ||
} | ||
|
||
} | ||
|
||
async function captureScreenshotsAsync( | ||
ctx: Context, | ||
staticConfig: Record<string, any>, | ||
browsers: Record<string, Browser> | ||
): Promise<void[]> { | ||
let capturePromises: Array<Promise<void>> = []; | ||
|
||
// capture screenshots for web config | ||
if (ctx.config.web) { | ||
for (let browserName of ctx.config.web.browsers) { | ||
let webRenderViewports = utils.getWebRenderViewports(ctx); | ||
capturePromises.push(captureScreenshotsForConfig(ctx, browsers, staticConfig, browserName, webRenderViewports)) | ||
} | ||
} | ||
// capture screenshots for mobile config | ||
if (ctx.config.mobile) { | ||
let mobileRenderViewports = utils.getMobileRenderViewports(ctx); | ||
if (mobileRenderViewports[constants.MOBILE_OS_IOS].length) { | ||
capturePromises.push(captureScreenshotsForConfig(ctx, browsers, staticConfig, constants.SAFARI, mobileRenderViewports[constants.MOBILE_OS_IOS])) | ||
} | ||
if (mobileRenderViewports[constants.MOBILE_OS_ANDROID].length) { | ||
capturePromises.push(captureScreenshotsForConfig(ctx, browsers, staticConfig, constants.CHROME, mobileRenderViewports[constants.MOBILE_OS_ANDROID])) | ||
} | ||
} | ||
|
||
// capture screenshots for mobile config | ||
if (ctx.config.mobile) { | ||
let contextChrome = await browsers[constants.CHROME]?.newContext(); | ||
let contextSafari = await browsers[constants.SAFARI]?.newContext(); | ||
let pageChrome = await contextChrome?.newPage(); | ||
let pageSafari = await contextSafari?.newPage(); | ||
return Promise.all(capturePromises); | ||
} | ||
|
||
async function captureScreenshotsSync( | ||
ctx: Context, | ||
staticConfig: Record<string, any>, | ||
browsers: Record<string, Browser> | ||
): Promise<void> { | ||
// capture screenshots for web config | ||
if (ctx.config.web) { | ||
for (let browserName of ctx.config.web.browsers) { | ||
let webRenderViewports = utils.getWebRenderViewports(ctx); | ||
await captureScreenshotsForConfig(ctx, browsers, staticConfig, browserName, webRenderViewports); | ||
} | ||
} | ||
// capture screenshots for mobile config | ||
if (ctx.config.mobile) { | ||
let mobileRenderViewports = utils.getMobileRenderViewports(ctx); | ||
if (mobileRenderViewports[constants.MOBILE_OS_IOS].length) { | ||
await captureScreenshotsForConfig(ctx, browsers, staticConfig, constants.SAFARI, mobileRenderViewports[constants.MOBILE_OS_IOS]); | ||
} | ||
if (mobileRenderViewports[constants.MOBILE_OS_ANDROID].length) { | ||
await captureScreenshotsForConfig(ctx, browsers, staticConfig, constants.CHROME, mobileRenderViewports[constants.MOBILE_OS_ANDROID]); | ||
} | ||
} | ||
} | ||
|
||
await pageChrome?.goto(staticConfig.url.trim(), pageOptions); | ||
await pageSafari?.goto(staticConfig.url.trim(), pageOptions); | ||
for (let device of ctx.config.mobile.devices) { | ||
let ssPath = `screenshots/${screenshotId}/${device.replace(/\s/g, '_')}_${screenshotId}.png`; | ||
let { width, height } = constants.SUPPORTED_MOBILE_DEVICES[device].viewport; | ||
let portrait = (ctx.config.mobile.orientation === constants.MOBILE_ORIENTATION_PORTRAIT) ? true : false; | ||
export async function captureScreenshots(ctx: Context): Promise<Record<string,any>> { | ||
// Clean up directory to store screenshots | ||
utils.delDir('screenshots'); | ||
|
||
if (constants.SUPPORTED_MOBILE_DEVICES[device].os === constants.MOBILE_OS_ANDROID) { | ||
await pageChrome?.setViewportSize({ width: portrait ? width : height, height: portrait ? height : width }); | ||
if (ctx.config.mobile.fullPage) await pageChrome?.evaluate(scrollToBottomAndBackToTop); | ||
await pageChrome?.waitForTimeout(staticConfig.waitForTimeout || 0); | ||
await pageChrome?.screenshot({ path: ssPath, fullPage: ctx.config.mobile.fullPage }); | ||
await ctx.client.uploadScreenshot(ctx.build, ssPath, staticConfig.name, constants.CHROME, `${device} (${ctx.config.mobile.orientation})`, ctx.log); | ||
} else { | ||
await pageSafari?.setViewportSize({ width: portrait ? width : height, height: portrait ? height : width }); | ||
if (ctx.config.mobile.fullPage) await pageChrome?.evaluate(scrollToBottomAndBackToTop); | ||
await pageSafari?.waitForTimeout(staticConfig.waitForTimeout || 0); | ||
await pageSafari?.screenshot({ path: ssPath, fullPage: ctx.config.mobile.fullPage }); | ||
await ctx.client.uploadScreenshot(ctx.build, ssPath, staticConfig.name, constants.PW_WEBKIT, `${device} (${ctx.config.mobile.orientation})`, ctx.log); | ||
} | ||
let browsers: Record<string,Browser> = {}; | ||
let capturedScreenshots: number = 0; | ||
let output: string = ''; | ||
|
||
capturedScreenshots++; | ||
ctx.task.output = chalk.gray(`screenshots captured: ${capturedScreenshots}/${totalScreenshots}`); | ||
} | ||
try { | ||
browsers = await utils.launchBrowsers(ctx); | ||
} catch (error) { | ||
await utils.closeBrowsers(browsers); | ||
ctx.log.debug(error) | ||
throw new Error(`Failed launching browsers`); | ||
} | ||
|
||
await pageChrome?.close(); | ||
await pageSafari?.close(); | ||
await contextChrome?.close(); | ||
await contextSafari?.close(); | ||
} | ||
for (let staticConfig of ctx.webStaticConfig) { | ||
try { | ||
if (ctx.options.parallel) await captureScreenshotsAsync(ctx, staticConfig, browsers); | ||
else await captureScreenshotsSync(ctx, staticConfig, browsers); | ||
|
||
output += (`${chalk.gray(staticConfig.name)} ${chalk.green('\u{2713}')}\n`); | ||
ctx.task.output = output; | ||
capturedScreenshots++; | ||
} catch (error) { | ||
ctx.log.debug(`screenshot capture failed for ${JSON.stringify(staticConfig)}; error: ${error}`); | ||
output += `${chalk.gray(staticConfig.name)} ${chalk.red('\u{2717}')}\n`; | ||
ctx.task.output = output; | ||
} | ||
|
||
await closeBrowsers(browsers); | ||
delDir('screenshots'); | ||
} catch (error) { | ||
await closeBrowsers(browsers); | ||
delDir('screenshots'); | ||
throw error; | ||
} | ||
|
||
return capturedScreenshots; | ||
await utils.closeBrowsers(browsers); | ||
utils.delDir('screenshots'); | ||
|
||
return { capturedScreenshots, output }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.