fixtures.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import * as fs from 'fs'
  2. import * as path from 'path'
  3. import { test as base, expect, ConsoleMessage } from '@playwright/test';
  4. import { ElectronApplication, Page, BrowserContext, _electron as electron } from 'playwright'
  5. import { loadLocalGraph, randomString } from './utils';
  6. let electronApp: ElectronApplication
  7. let context: BrowserContext
  8. let page: Page
  9. let repoName = randomString(10)
  10. let testTmpDir = path.resolve(__dirname, '../tmp')
  11. if (fs.existsSync(testTmpDir)) {
  12. fs.rmdirSync(testTmpDir, { recursive: true })
  13. }
  14. export let graphDir = path.resolve(testTmpDir, "e2e-test", repoName)
  15. // NOTE: This following is a console log watcher for error logs.
  16. // Save and print all logs when error happens.
  17. let logs: string
  18. const consoleLogWatcher = (msg: ConsoleMessage) => {
  19. // console.log(msg.text())
  20. logs += msg.text() + '\n'
  21. expect(msg.text(), logs).not.toMatch(/^(Failed to|Uncaught)/)
  22. // youtube video
  23. if (!logs.match(/^Error with Permissions-Policy header: Unrecognized feature/)) {
  24. expect(logs).not.toMatch(/^Error/)
  25. }
  26. // NOTE: React warnings will be logged as error.
  27. // expect(msg.type()).not.toBe('error')
  28. }
  29. base.beforeAll(async () => {
  30. if (electronApp) {
  31. return
  32. }
  33. console.log(`Creating test graph directory: ${graphDir}`)
  34. fs.mkdirSync(graphDir, {
  35. recursive: true,
  36. });
  37. electronApp = await electron.launch({
  38. cwd: "./static",
  39. args: ["electron.js"],
  40. locale: 'en',
  41. })
  42. context = electronApp.context()
  43. await context.tracing.start({ screenshots: true, snapshots: true });
  44. // NOTE: The following ensures App first start with the correct path.
  45. const info = await electronApp.evaluate(async ({ app }) => {
  46. return {
  47. "appPath": app.getAppPath(),
  48. "appData": app.getPath("appData"),
  49. "userData": app.getPath("userData"),
  50. "appName": app.getName(),
  51. }
  52. })
  53. console.log("Test start with:", info)
  54. page = await electronApp.firstWindow()
  55. // Direct Electron console to watcher
  56. page.on('console', consoleLogWatcher)
  57. page.on('crash', () => {
  58. expect(false, "Page must not crash").toBeTruthy()
  59. })
  60. page.on('pageerror', (err) => {
  61. console.log(err)
  62. expect(false, 'Page must not have errors!').toBeTruthy()
  63. })
  64. await page.waitForLoadState('domcontentloaded')
  65. // await page.waitForFunction(() => window.document.title != "Loading")
  66. // NOTE: The following ensures first start.
  67. // await page.waitForSelector('text=This is a demo graph, changes will not be saved until you open a local folder')
  68. await page.waitForSelector(':has-text("Loading")', {
  69. state: "hidden",
  70. timeout: 1000 * 15,
  71. });
  72. page.once('load', async () => {
  73. console.log('Page loaded!')
  74. await page.screenshot({ path: 'startup.png' })
  75. })
  76. await loadLocalGraph(page, graphDir);
  77. })
  78. base.beforeEach(async () => {
  79. // discard any dialog by ESC
  80. if (page) {
  81. await page.keyboard.press('Escape')
  82. await page.keyboard.press('Escape')
  83. }
  84. })
  85. base.afterAll(async () => {
  86. // if (electronApp) {
  87. // await electronApp.close()
  88. //}
  89. })
  90. // hijack electron app into the test context
  91. export const test = base.extend<{ page: Page, context: BrowserContext, app: ElectronApplication, graphDir: string }>({
  92. page: async ({ }, use) => {
  93. await use(page);
  94. },
  95. context: async ({ }, use) => {
  96. await use(context);
  97. },
  98. app: async ({ }, use) => {
  99. await use(electronApp);
  100. },
  101. graphDir: async ({ }, use) => {
  102. await use(graphDir);
  103. },
  104. });