image_utils.ts (1789B)
1 import * as fs from 'fs'; 2 3 import { Page } from 'playwright-core'; 4 import { PNG } from 'pngjs'; 5 import { screenshot, WindowInfo } from 'screenshot-ftw'; 6 7 // eslint-disable-next-line ban/ban 8 const waitMS = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); 9 10 export function readPng(filename: string) { 11 const data = fs.readFileSync(filename); 12 return PNG.sync.read(data); 13 } 14 15 export function writePng(filename: string, width: number, height: number, data: Buffer) { 16 const png = new PNG({ colorType: 6, width, height }); 17 for (let i = 0; i < data.byteLength; ++i) { 18 png.data[i] = data[i]; 19 } 20 const buffer = PNG.sync.write(png); 21 fs.writeFileSync(filename, buffer); 22 } 23 24 export class ScreenshotManager { 25 window?: WindowInfo; 26 27 async init(page: Page) { 28 // set the title to some random number so we can find the window by title 29 const title: string = await page.evaluate(() => { 30 const title = `t-${Math.random()}`; 31 document.title = title; 32 return title; 33 }); 34 35 // wait for the window to show up 36 let window; 37 for (let i = 0; !window && i < 100; ++i) { 38 await waitMS(50); 39 const windows = await screenshot.getWindows(); 40 window = windows.find(window => window.title.includes(title)); 41 } 42 if (!window) { 43 throw Error(`could not find window: ${title}`); 44 } 45 this.window = window; 46 } 47 48 async takeScreenshot(page: Page, screenshotName: string) { 49 // await page.screenshot({ path: screenshotName }); 50 51 // we need to set the url and title since the screenshot will include the chrome 52 await page.evaluate(() => { 53 document.title = 'screenshot'; 54 window.history.replaceState({}, '', '/screenshot'); 55 }); 56 await screenshot.captureWindowById(screenshotName, this.window!.id); 57 } 58 }