Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

68 řádky
2.4 KiB

  1. import fs from 'node:fs'
  2. import path from 'node:path'
  3. import { fileURLToPath } from 'node:url'
  4. import { expect, test as base, type Page, type TestInfo } from '@playwright/test'
  5. const screenshotDirectory = fileURLToPath(new URL('../artifacts/screenshots/', import.meta.url))
  6. const safeName = (value: string) => value
  7. .normalize('NFKC')
  8. .replace(/[^\p{L}\p{N}._-]+/gu, '-')
  9. .replace(/^-+|-+$/g, '')
  10. .slice(0, 120)
  11. const stableTestName = (testInfo: TestInfo) => {
  12. const fileStem = path.basename(testInfo.file, path.extname(testInfo.file))
  13. return safeName(`${testInfo.project.name}--${fileStem}--${testInfo.title}`).slice(0, 110) || 'unnamed-test'
  14. }
  15. export async function captureScreenshot(page: Page, testInfo: TestInfo, label: string) {
  16. fs.mkdirSync(screenshotDirectory, { recursive: true })
  17. const testName = stableTestName(testInfo)
  18. const artifactName = safeName(label).slice(0, 70) || 'success'
  19. const screenshotPath = path.join(screenshotDirectory, `${testName}--${artifactName}.png`)
  20. await page.screenshot({
  21. path: screenshotPath,
  22. fullPage: true,
  23. animations: 'disabled',
  24. caret: 'hide',
  25. })
  26. await testInfo.attach(`success-${artifactName}`, { path: screenshotPath, contentType: 'image/png' })
  27. return screenshotPath
  28. }
  29. export const test = base
  30. test.beforeEach(async ({}, testInfo) => {
  31. fs.mkdirSync(screenshotDirectory, { recursive: true })
  32. const prefix = `${stableTestName(testInfo)}--`
  33. for (const filename of fs.readdirSync(screenshotDirectory)) {
  34. if (filename.startsWith(prefix) && filename.endsWith('.png')) {
  35. fs.rmSync(path.join(screenshotDirectory, filename), { force: true })
  36. }
  37. }
  38. })
  39. test.afterEach(async ({ page }, testInfo) => {
  40. if (testInfo.status === testInfo.expectedStatus || page.isClosed()) return
  41. fs.mkdirSync(screenshotDirectory, { recursive: true })
  42. const title = safeName(testInfo.titlePath.join('--')) || 'failed-test'
  43. const filename = `${title}--retry-${testInfo.retry}--${Date.now()}.png`
  44. const screenshotPath = path.join(screenshotDirectory, filename)
  45. try {
  46. await page.screenshot({ path: screenshotPath, fullPage: true })
  47. await testInfo.attach('failure-screenshot', { path: screenshotPath, contentType: 'image/png' })
  48. } catch (error) {
  49. await testInfo.attach('failure-screenshot-error', {
  50. body: Buffer.from(String(error)),
  51. contentType: 'text/plain',
  52. })
  53. }
  54. })
  55. export { expect }