|
- import fs from 'node:fs'
- import path from 'node:path'
- import { fileURLToPath } from 'node:url'
-
- import { expect, test as base, type Page, type TestInfo } from '@playwright/test'
-
- const screenshotDirectory = fileURLToPath(new URL('../artifacts/screenshots/', import.meta.url))
-
- const safeName = (value: string) => value
- .normalize('NFKC')
- .replace(/[^\p{L}\p{N}._-]+/gu, '-')
- .replace(/^-+|-+$/g, '')
- .slice(0, 120)
-
- const stableTestName = (testInfo: TestInfo) => {
- const fileStem = path.basename(testInfo.file, path.extname(testInfo.file))
- return safeName(`${testInfo.project.name}--${fileStem}--${testInfo.title}`).slice(0, 110) || 'unnamed-test'
- }
-
- export async function captureScreenshot(page: Page, testInfo: TestInfo, label: string) {
- fs.mkdirSync(screenshotDirectory, { recursive: true })
- const testName = stableTestName(testInfo)
- const artifactName = safeName(label).slice(0, 70) || 'success'
- const screenshotPath = path.join(screenshotDirectory, `${testName}--${artifactName}.png`)
-
- await page.screenshot({
- path: screenshotPath,
- fullPage: true,
- animations: 'disabled',
- caret: 'hide',
- })
- await testInfo.attach(`success-${artifactName}`, { path: screenshotPath, contentType: 'image/png' })
- return screenshotPath
- }
-
- export const test = base
-
- test.beforeEach(async ({}, testInfo) => {
- fs.mkdirSync(screenshotDirectory, { recursive: true })
- const prefix = `${stableTestName(testInfo)}--`
- for (const filename of fs.readdirSync(screenshotDirectory)) {
- if (filename.startsWith(prefix) && filename.endsWith('.png')) {
- fs.rmSync(path.join(screenshotDirectory, filename), { force: true })
- }
- }
- })
-
- test.afterEach(async ({ page }, testInfo) => {
- if (testInfo.status === testInfo.expectedStatus || page.isClosed()) return
-
- fs.mkdirSync(screenshotDirectory, { recursive: true })
- const title = safeName(testInfo.titlePath.join('--')) || 'failed-test'
- const filename = `${title}--retry-${testInfo.retry}--${Date.now()}.png`
- const screenshotPath = path.join(screenshotDirectory, filename)
-
- try {
- await page.screenshot({ path: screenshotPath, fullPage: true })
- await testInfo.attach('failure-screenshot', { path: screenshotPath, contentType: 'image/png' })
- } catch (error) {
- await testInfo.attach('failure-screenshot-error', {
- body: Buffer.from(String(error)),
- contentType: 'text/plain',
- })
- }
- })
-
- export { expect }
|