@dxos/test-utils 0.8.4-main.dedc0f3 → 0.8.4-main.e00bdcdb52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/resource.ts"],
4
4
  "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { onTestFinished } from 'vitest';\n\ninterface ResourceLike {\n open(): Promise<any>;\n close(): Promise<any>;\n}\n\n// TODO(burdon): Replace with abstraction relating to Context object?\nexport const openAndClose = async (...resources: ResourceLike[]) => {\n for (const resourceLike of resources) {\n await resourceLike.open();\n onTestFinished(() => resourceLike.close());\n }\n};\n"],
5
- "mappings": ";AAIA,SAASA,sBAAsB;AAQxB,IAAMC,eAAe,UAAUC,cAAAA;AACpC,aAAWC,gBAAgBD,WAAW;AACpC,UAAMC,aAAaC,KAAI;AACvBC,mBAAe,MAAMF,aAAaG,MAAK,CAAA;EACzC;AACF;",
6
- "names": ["onTestFinished", "openAndClose", "resources", "resourceLike", "open", "onTestFinished", "close"]
5
+ "mappings": ";AAIA,SAASA,sBAAsB;AAQxB,IAAMC,eAAe,UAAUC,cAAAA;AACpC,aAAWC,gBAAgBD,WAAW;AACpC,UAAMC,aAAaC,KAAI;AACvBJ,mBAAe,MAAMG,aAAaE,MAAK,CAAA;EACzC;AACF;",
6
+ "names": ["onTestFinished", "openAndClose", "resources", "resourceLike", "open", "close"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"src/resource.ts":{"bytes":1532,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":453,"imports":[{"path":"src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"src/lock.ts":{"bytes":2395,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":13695,"imports":[{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":798},"dist/lib/browser/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"src/index.ts","inputs":{"src/resource.ts":{"bytesInOutput":214},"src/index.ts":{"bytesInOutput":0}},"bytes":295},"dist/lib/browser/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":8085},"dist/lib/browser/playwright.mjs":{"imports":[{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["e2ePreset","setupPage","storybookUrl"],"entryPoint":"src/playwright.ts","inputs":{"src/playwright.ts":{"bytesInOutput":3164},"src/lock.ts":{"bytesInOutput":686}},"bytes":4002}}}
1
+ {"inputs":{"src/resource.ts":{"bytes":1452,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":376,"imports":[{"path":"src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"src/lock.ts":{"bytes":1942,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":16626,"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":780},"dist/lib/browser/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"src/index.ts","inputs":{"src/resource.ts":{"bytesInOutput":214},"src/index.ts":{"bytesInOutput":0}},"bytes":295},"dist/lib/browser/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9381},"dist/lib/browser/playwright.mjs":{"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["e2ePreset","setupPage","storybookUrl"],"entryPoint":"src/playwright.ts","inputs":{"src/playwright.ts":{"bytesInOutput":4090},"src/lock.ts":{"bytesInOutput":389}},"bytes":4631}}}
@@ -1,24 +1,13 @@
1
1
  // src/playwright.ts
2
+ import { devices } from "@playwright/test";
2
3
  import { existsSync, readFileSync } from "@dxos/node-std/fs";
3
4
  import { dirname, join, resolve } from "@dxos/node-std/path";
4
5
  import pkgUp from "pkg-up";
5
6
 
6
7
  // src/lock.ts
7
8
  import { trigger } from "@dxos/async";
8
- function _define_property(obj, key, value) {
9
- if (key in obj) {
10
- Object.defineProperty(obj, key, {
11
- value,
12
- enumerable: true,
13
- configurable: true,
14
- writable: true
15
- });
16
- } else {
17
- obj[key] = value;
18
- }
19
- return obj;
20
- }
21
9
  var Lock = class {
10
+ _lastPromise = Promise.resolve();
22
11
  async executeSynchronized(fun) {
23
12
  const prevPromise = this._lastPromise;
24
13
  const [getPromise, resolve2] = trigger();
@@ -31,9 +20,6 @@ var Lock = class {
31
20
  resolve2();
32
21
  }
33
22
  }
34
- constructor() {
35
- _define_property(this, "_lastPromise", Promise.resolve());
36
- }
37
23
  };
38
24
 
39
25
  // src/playwright.ts
@@ -72,6 +58,29 @@ var e2ePreset = (testDir) => {
72
58
  const workspaceRoot = findWorkspaceRoot(packageDir);
73
59
  const testResultOuputDir = join(workspaceRoot, "test-results/playwright/output", packageDirName);
74
60
  const reporterOutputFile = join(workspaceRoot, "test-results/playwright/report", `${packageDirName}.json`);
61
+ const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? "all" : "chromium");
62
+ const projects = [
63
+ {
64
+ name: "chromium",
65
+ use: {
66
+ ...devices["Desktop Chrome"]
67
+ }
68
+ },
69
+ {
70
+ name: "firefox",
71
+ use: {
72
+ ...devices["Desktop Firefox"]
73
+ }
74
+ },
75
+ {
76
+ name: "webkit",
77
+ use: {
78
+ ...devices["Desktop Safari"]
79
+ }
80
+ }
81
+ ].filter((project) => {
82
+ return browser === "all" || project.name === browser;
83
+ });
75
84
  return {
76
85
  testDir,
77
86
  outputDir: testResultOuputDir,
@@ -80,9 +89,12 @@ var e2ePreset = (testDir) => {
80
89
  // Fail the build on CI if you accidentally left test.only in the source code.
81
90
  forbidOnly: !!process.env.CI,
82
91
  // Retry on CI only.
92
+ // TODO(wittjosiah): Trunk suggests not retrying for better flaky test detection.
93
+ // This is forgone for now as its unclear why some tests are flaky primarily on CI.
94
+ // For the time being, a test is considered flaky if it can't pass within 2 retries.
83
95
  retries: process.env.CI ? 2 : 0,
84
96
  // Opt out of parallel tests on CI.
85
- workers: process.env.CI ? 1 : void 0,
97
+ workers: process.env.CI ? 1 : 4,
86
98
  // Reporter to use. See https://playwright.dev/docs/test-reporters.
87
99
  reporter: process.env.CI ? [
88
100
  [
@@ -93,6 +105,12 @@ var e2ePreset = (testDir) => {
93
105
  {
94
106
  outputFile: reporterOutputFile
95
107
  }
108
+ ],
109
+ [
110
+ "junit",
111
+ {
112
+ outputFile: reporterOutputFile.replace(/\.json$/, ".xml")
113
+ }
96
114
  ]
97
115
  ] : [
98
116
  [
@@ -101,7 +119,8 @@ var e2ePreset = (testDir) => {
101
119
  ],
102
120
  use: {
103
121
  trace: "retain-on-failure"
104
- }
122
+ },
123
+ projects
105
124
  };
106
125
  };
107
126
  var setupPage = async (browser, options = {}) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/playwright.ts", "../../../src/lock.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\n/* eslint-disable no-console */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig } from '@playwright/test';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nconst findWorkspaceRoot = (startDir: string): string => {\n let dir = resolve(startDir);\n while (dir !== '/') {\n try {\n // Check for pnpm-workspace.yaml first (modern pnpm approach)\n const workspaceYamlPath = join(dir, 'pnpm-workspace.yaml');\n if (existsSync(workspaceYamlPath)) {\n return dir;\n }\n\n // Check for package.json with workspaces field (legacy approach)\n const pkgPath = join(dir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n if (pkg.workspaces) {\n return dir;\n }\n } catch {}\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error('Could not find pnpm workspace root');\n};\n\nexport const e2ePreset = (testDir: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd: testDir });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirName = packageDir.split('/').pop();\n if (!packageDirName) {\n throw new Error('packageDirName not found');\n }\n\n const workspaceRoot = findWorkspaceRoot(packageDir);\n const testResultOuputDir = join(workspaceRoot, 'test-results/playwright/output', packageDirName);\n const reporterOutputFile = join(workspaceRoot, 'test-results/playwright/report', `${packageDirName}.json`);\n\n return {\n testDir,\n outputDir: testResultOuputDir,\n // Run tests in files in parallel.\n fullyParallel: true,\n // Fail the build on CI if you accidentally left test.only in the source code.\n forbidOnly: !!process.env.CI,\n // Retry on CI only.\n retries: process.env.CI ? 2 : 0,\n // Opt out of parallel tests on CI.\n workers: process.env.CI ? 1 : undefined,\n // Reporter to use. See https://playwright.dev/docs/test-reporters.\n reporter: process.env.CI\n ? [\n ['list'],\n [\n 'json',\n {\n outputFile: reporterOutputFile,\n },\n ],\n ]\n : [['list']],\n use: {\n trace: 'retain-on-failure',\n },\n };\n};\n\nexport type SetupOptions = {\n url?: string;\n bridgeLogs?: boolean;\n viewportSize?: Parameters<Page['setViewportSize']>[0];\n};\n\nexport const setupPage = async (browser: Browser | BrowserContext, options: SetupOptions = {}) => {\n const { url, bridgeLogs, viewportSize } = options;\n\n const context = 'newContext' in browser ? await browser.newContext() : browser;\n const page = await context.newPage();\n\n if (viewportSize) {\n await page.setViewportSize(viewportSize);\n }\n\n // TODO(wittjosiah): Remove?\n if (bridgeLogs) {\n const lock = new Lock();\n\n page.on('pageerror', async (error) => {\n await lock.executeSynchronized(async () => {\n // eslint-disable-next-line no-console\n console.log(error);\n });\n });\n\n page.on('console', async (msg) => {\n try {\n const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));\n await lock.executeSynchronized(async () => {\n const args = await argsPromise;\n\n if (args.length > 0) {\n console.log(...args);\n } else {\n console.log(msg);\n }\n });\n } catch (err) {\n console.error('Failed to parse message', err);\n }\n });\n }\n\n if (url) {\n await page.goto(url);\n }\n\n return { context, page };\n};\n\nexport const storybookUrl = (storyId: string, port = 9009) =>\n `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { trigger } from '@dxos/async';\n\n// Copied from @dxos/async.\nexport class Lock {\n private _lastPromise = Promise.resolve();\n\n async executeSynchronized<T>(fun: () => Promise<T>): Promise<T> {\n const prevPromise = this._lastPromise;\n const [getPromise, resolve] = trigger();\n this._lastPromise = getPromise();\n\n await prevPromise;\n try {\n const value = await fun();\n return value;\n } finally {\n resolve();\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["existsSync", "readFileSync", "dirname", "join", "resolve", "pkgUp", "trigger", "Lock", "executeSynchronized", "fun", "prevPromise", "_lastPromise", "getPromise", "resolve", "trigger", "value", "Promise", "findWorkspaceRoot", "startDir", "dir", "resolve", "workspaceYamlPath", "join", "existsSync", "pkgPath", "pkg", "JSON", "parse", "readFileSync", "workspaces", "parent", "dirname", "Error", "e2ePreset", "testDir", "packageJson", "pkgUp", "sync", "cwd", "packageDir", "split", "slice", "packageDirName", "pop", "workspaceRoot", "testResultOuputDir", "reporterOutputFile", "outputDir", "fullyParallel", "forbidOnly", "process", "env", "CI", "retries", "workers", "undefined", "reporter", "outputFile", "use", "trace", "setupPage", "browser", "options", "url", "bridgeLogs", "viewportSize", "context", "newContext", "page", "newPage", "setViewportSize", "lock", "Lock", "on", "error", "executeSynchronized", "console", "log", "msg", "argsPromise", "Promise", "all", "args", "map", "x", "jsonValue", "length", "err", "goto", "storybookUrl", "storyId", "port"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\n/* eslint-disable no-console */\n\nimport { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig, devices } from '@playwright/test';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nconst findWorkspaceRoot = (startDir: string): string => {\n let dir = resolve(startDir);\n while (dir !== '/') {\n try {\n // Check for pnpm-workspace.yaml first (modern pnpm approach)\n const workspaceYamlPath = join(dir, 'pnpm-workspace.yaml');\n if (existsSync(workspaceYamlPath)) {\n return dir;\n }\n\n // Check for package.json with workspaces field (legacy approach)\n const pkgPath = join(dir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n if (pkg.workspaces) {\n return dir;\n }\n } catch {}\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error('Could not find pnpm workspace root');\n};\n\nexport const e2ePreset = (testDir: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd: testDir });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirName = packageDir.split('/').pop();\n if (!packageDirName) {\n throw new Error('packageDirName not found');\n }\n\n const workspaceRoot = findWorkspaceRoot(packageDir);\n const testResultOuputDir = join(workspaceRoot, 'test-results/playwright/output', packageDirName);\n const reporterOutputFile = join(workspaceRoot, 'test-results/playwright/report', `${packageDirName}.json`);\n\n const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? 'all' : 'chromium');\n const projects = [\n {\n name: 'chromium',\n use: { ...devices['Desktop Chrome'] },\n },\n {\n name: 'firefox',\n use: { ...devices['Desktop Firefox'] },\n },\n {\n name: 'webkit',\n use: { ...devices['Desktop Safari'] },\n },\n ].filter((project) => {\n return browser === 'all' || project.name === browser;\n });\n\n return {\n testDir,\n outputDir: testResultOuputDir,\n // Run tests in files in parallel.\n fullyParallel: true,\n // Fail the build on CI if you accidentally left test.only in the source code.\n forbidOnly: !!process.env.CI,\n // Retry on CI only.\n // TODO(wittjosiah): Trunk suggests not retrying for better flaky test detection.\n // This is forgone for now as its unclear why some tests are flaky primarily on CI.\n // For the time being, a test is considered flaky if it can't pass within 2 retries.\n retries: process.env.CI ? 2 : 0,\n // Opt out of parallel tests on CI.\n workers: process.env.CI ? 1 : 4,\n // Reporter to use. See https://playwright.dev/docs/test-reporters.\n reporter: process.env.CI\n ? [\n ['list'],\n [\n 'json',\n {\n outputFile: reporterOutputFile,\n },\n ],\n ['junit', { outputFile: reporterOutputFile.replace(/\\.json$/, '.xml') }],\n ]\n : [['list']],\n use: {\n trace: 'retain-on-failure',\n },\n projects,\n };\n};\n\nexport type SetupOptions = {\n url?: string;\n bridgeLogs?: boolean;\n viewportSize?: Parameters<Page['setViewportSize']>[0];\n};\n\nexport const setupPage = async (browser: Browser | BrowserContext, options: SetupOptions = {}) => {\n const { url, bridgeLogs, viewportSize } = options;\n\n const context = 'newContext' in browser ? await browser.newContext() : browser;\n const page = await context.newPage();\n\n if (viewportSize) {\n await page.setViewportSize(viewportSize);\n }\n\n // TODO(wittjosiah): Remove?\n if (bridgeLogs) {\n const lock = new Lock();\n\n page.on('pageerror', async (error) => {\n await lock.executeSynchronized(async () => {\n // eslint-disable-next-line no-console\n console.log(error);\n });\n });\n\n page.on('console', async (msg) => {\n try {\n const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));\n await lock.executeSynchronized(async () => {\n const args = await argsPromise;\n\n if (args.length > 0) {\n console.log(...args);\n } else {\n console.log(msg);\n }\n });\n } catch (err) {\n console.error('Failed to parse message', err);\n }\n });\n }\n\n if (url) {\n await page.goto(url);\n }\n\n return { context, page };\n};\n\nexport const storybookUrl = (storyId: string, port = 9009) =>\n `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { trigger } from '@dxos/async';\n\n// Copied from @dxos/async.\nexport class Lock {\n private _lastPromise = Promise.resolve();\n\n async executeSynchronized<T>(fun: () => Promise<T>): Promise<T> {\n const prevPromise = this._lastPromise;\n const [getPromise, resolve] = trigger();\n this._lastPromise = getPromise();\n\n await prevPromise;\n try {\n const value = await fun();\n return value;\n } finally {\n resolve();\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["devices", "existsSync", "readFileSync", "dirname", "join", "resolve", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "value", "findWorkspaceRoot", "startDir", "dir", "resolve", "workspaceYamlPath", "join", "existsSync", "pkgPath", "pkg", "JSON", "parse", "readFileSync", "workspaces", "parent", "dirname", "Error", "e2ePreset", "testDir", "packageJson", "pkgUp", "sync", "cwd", "packageDir", "split", "slice", "packageDirName", "pop", "workspaceRoot", "testResultOuputDir", "reporterOutputFile", "browser", "process", "env", "PLAYWRIGHT_BROWSER", "CI", "projects", "name", "use", "devices", "filter", "project", "outputDir", "fullyParallel", "forbidOnly", "retries", "workers", "reporter", "outputFile", "replace", "trace", "setupPage", "options", "url", "bridgeLogs", "viewportSize", "context", "newContext", "page", "newPage", "setViewportSize", "lock", "Lock", "on", "error", "executeSynchronized", "console", "log", "msg", "argsPromise", "Promise", "all", "args", "map", "x", "jsonValue", "length", "err", "goto", "storybookUrl", "storyId", "port"]
7
7
  }
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/resource.ts"],
4
4
  "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { onTestFinished } from 'vitest';\n\ninterface ResourceLike {\n open(): Promise<any>;\n close(): Promise<any>;\n}\n\n// TODO(burdon): Replace with abstraction relating to Context object?\nexport const openAndClose = async (...resources: ResourceLike[]) => {\n for (const resourceLike of resources) {\n await resourceLike.open();\n onTestFinished(() => resourceLike.close());\n }\n};\n"],
5
- "mappings": ";;;AAIA,SAASA,sBAAsB;AAQxB,IAAMC,eAAe,UAAUC,cAAAA;AACpC,aAAWC,gBAAgBD,WAAW;AACpC,UAAMC,aAAaC,KAAI;AACvBC,mBAAe,MAAMF,aAAaG,MAAK,CAAA;EACzC;AACF;",
6
- "names": ["onTestFinished", "openAndClose", "resources", "resourceLike", "open", "onTestFinished", "close"]
5
+ "mappings": ";;;AAIA,SAASA,sBAAsB;AAQxB,IAAMC,eAAe,UAAUC,cAAAA;AACpC,aAAWC,gBAAgBD,WAAW;AACpC,UAAMC,aAAaC,KAAI;AACvBJ,mBAAe,MAAMG,aAAaE,MAAK,CAAA;EACzC;AACF;",
6
+ "names": ["onTestFinished", "openAndClose", "resources", "resourceLike", "open", "close"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"src/resource.ts":{"bytes":1532,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":453,"imports":[{"path":"src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"src/lock.ts":{"bytes":2395,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":13695,"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":800},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"src/index.ts","inputs":{"src/resource.ts":{"bytesInOutput":214},"src/index.ts":{"bytesInOutput":0}},"bytes":388},"dist/lib/node-esm/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":8087},"dist/lib/node-esm/playwright.mjs":{"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["e2ePreset","setupPage","storybookUrl"],"entryPoint":"src/playwright.ts","inputs":{"src/playwright.ts":{"bytesInOutput":3144},"src/lock.ts":{"bytesInOutput":686}},"bytes":4075}}}
1
+ {"inputs":{"src/resource.ts":{"bytes":1452,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":376,"imports":[{"path":"src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"src/lock.ts":{"bytes":1942,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":16626,"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":782},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"src/index.ts","inputs":{"src/resource.ts":{"bytesInOutput":214},"src/index.ts":{"bytesInOutput":0}},"bytes":388},"dist/lib/node-esm/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9383},"dist/lib/node-esm/playwright.mjs":{"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["e2ePreset","setupPage","storybookUrl"],"entryPoint":"src/playwright.ts","inputs":{"src/playwright.ts":{"bytesInOutput":4070},"src/lock.ts":{"bytesInOutput":389}},"bytes":4704}}}
@@ -1,26 +1,15 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
3
  // src/playwright.ts
4
+ import { devices } from "@playwright/test";
4
5
  import { existsSync, readFileSync } from "node:fs";
5
6
  import { dirname, join, resolve } from "node:path";
6
7
  import pkgUp from "pkg-up";
7
8
 
8
9
  // src/lock.ts
9
10
  import { trigger } from "@dxos/async";
10
- function _define_property(obj, key, value) {
11
- if (key in obj) {
12
- Object.defineProperty(obj, key, {
13
- value,
14
- enumerable: true,
15
- configurable: true,
16
- writable: true
17
- });
18
- } else {
19
- obj[key] = value;
20
- }
21
- return obj;
22
- }
23
11
  var Lock = class {
12
+ _lastPromise = Promise.resolve();
24
13
  async executeSynchronized(fun) {
25
14
  const prevPromise = this._lastPromise;
26
15
  const [getPromise, resolve2] = trigger();
@@ -33,9 +22,6 @@ var Lock = class {
33
22
  resolve2();
34
23
  }
35
24
  }
36
- constructor() {
37
- _define_property(this, "_lastPromise", Promise.resolve());
38
- }
39
25
  };
40
26
 
41
27
  // src/playwright.ts
@@ -74,6 +60,29 @@ var e2ePreset = (testDir) => {
74
60
  const workspaceRoot = findWorkspaceRoot(packageDir);
75
61
  const testResultOuputDir = join(workspaceRoot, "test-results/playwright/output", packageDirName);
76
62
  const reporterOutputFile = join(workspaceRoot, "test-results/playwright/report", `${packageDirName}.json`);
63
+ const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? "all" : "chromium");
64
+ const projects = [
65
+ {
66
+ name: "chromium",
67
+ use: {
68
+ ...devices["Desktop Chrome"]
69
+ }
70
+ },
71
+ {
72
+ name: "firefox",
73
+ use: {
74
+ ...devices["Desktop Firefox"]
75
+ }
76
+ },
77
+ {
78
+ name: "webkit",
79
+ use: {
80
+ ...devices["Desktop Safari"]
81
+ }
82
+ }
83
+ ].filter((project) => {
84
+ return browser === "all" || project.name === browser;
85
+ });
77
86
  return {
78
87
  testDir,
79
88
  outputDir: testResultOuputDir,
@@ -82,9 +91,12 @@ var e2ePreset = (testDir) => {
82
91
  // Fail the build on CI if you accidentally left test.only in the source code.
83
92
  forbidOnly: !!process.env.CI,
84
93
  // Retry on CI only.
94
+ // TODO(wittjosiah): Trunk suggests not retrying for better flaky test detection.
95
+ // This is forgone for now as its unclear why some tests are flaky primarily on CI.
96
+ // For the time being, a test is considered flaky if it can't pass within 2 retries.
85
97
  retries: process.env.CI ? 2 : 0,
86
98
  // Opt out of parallel tests on CI.
87
- workers: process.env.CI ? 1 : void 0,
99
+ workers: process.env.CI ? 1 : 4,
88
100
  // Reporter to use. See https://playwright.dev/docs/test-reporters.
89
101
  reporter: process.env.CI ? [
90
102
  [
@@ -95,6 +107,12 @@ var e2ePreset = (testDir) => {
95
107
  {
96
108
  outputFile: reporterOutputFile
97
109
  }
110
+ ],
111
+ [
112
+ "junit",
113
+ {
114
+ outputFile: reporterOutputFile.replace(/\.json$/, ".xml")
115
+ }
98
116
  ]
99
117
  ] : [
100
118
  [
@@ -103,7 +121,8 @@ var e2ePreset = (testDir) => {
103
121
  ],
104
122
  use: {
105
123
  trace: "retain-on-failure"
106
- }
124
+ },
125
+ projects
107
126
  };
108
127
  };
109
128
  var setupPage = async (browser, options = {}) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/playwright.ts", "../../../src/lock.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\n/* eslint-disable no-console */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig } from '@playwright/test';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nconst findWorkspaceRoot = (startDir: string): string => {\n let dir = resolve(startDir);\n while (dir !== '/') {\n try {\n // Check for pnpm-workspace.yaml first (modern pnpm approach)\n const workspaceYamlPath = join(dir, 'pnpm-workspace.yaml');\n if (existsSync(workspaceYamlPath)) {\n return dir;\n }\n\n // Check for package.json with workspaces field (legacy approach)\n const pkgPath = join(dir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n if (pkg.workspaces) {\n return dir;\n }\n } catch {}\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error('Could not find pnpm workspace root');\n};\n\nexport const e2ePreset = (testDir: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd: testDir });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirName = packageDir.split('/').pop();\n if (!packageDirName) {\n throw new Error('packageDirName not found');\n }\n\n const workspaceRoot = findWorkspaceRoot(packageDir);\n const testResultOuputDir = join(workspaceRoot, 'test-results/playwright/output', packageDirName);\n const reporterOutputFile = join(workspaceRoot, 'test-results/playwright/report', `${packageDirName}.json`);\n\n return {\n testDir,\n outputDir: testResultOuputDir,\n // Run tests in files in parallel.\n fullyParallel: true,\n // Fail the build on CI if you accidentally left test.only in the source code.\n forbidOnly: !!process.env.CI,\n // Retry on CI only.\n retries: process.env.CI ? 2 : 0,\n // Opt out of parallel tests on CI.\n workers: process.env.CI ? 1 : undefined,\n // Reporter to use. See https://playwright.dev/docs/test-reporters.\n reporter: process.env.CI\n ? [\n ['list'],\n [\n 'json',\n {\n outputFile: reporterOutputFile,\n },\n ],\n ]\n : [['list']],\n use: {\n trace: 'retain-on-failure',\n },\n };\n};\n\nexport type SetupOptions = {\n url?: string;\n bridgeLogs?: boolean;\n viewportSize?: Parameters<Page['setViewportSize']>[0];\n};\n\nexport const setupPage = async (browser: Browser | BrowserContext, options: SetupOptions = {}) => {\n const { url, bridgeLogs, viewportSize } = options;\n\n const context = 'newContext' in browser ? await browser.newContext() : browser;\n const page = await context.newPage();\n\n if (viewportSize) {\n await page.setViewportSize(viewportSize);\n }\n\n // TODO(wittjosiah): Remove?\n if (bridgeLogs) {\n const lock = new Lock();\n\n page.on('pageerror', async (error) => {\n await lock.executeSynchronized(async () => {\n // eslint-disable-next-line no-console\n console.log(error);\n });\n });\n\n page.on('console', async (msg) => {\n try {\n const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));\n await lock.executeSynchronized(async () => {\n const args = await argsPromise;\n\n if (args.length > 0) {\n console.log(...args);\n } else {\n console.log(msg);\n }\n });\n } catch (err) {\n console.error('Failed to parse message', err);\n }\n });\n }\n\n if (url) {\n await page.goto(url);\n }\n\n return { context, page };\n};\n\nexport const storybookUrl = (storyId: string, port = 9009) =>\n `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { trigger } from '@dxos/async';\n\n// Copied from @dxos/async.\nexport class Lock {\n private _lastPromise = Promise.resolve();\n\n async executeSynchronized<T>(fun: () => Promise<T>): Promise<T> {\n const prevPromise = this._lastPromise;\n const [getPromise, resolve] = trigger();\n this._lastPromise = getPromise();\n\n await prevPromise;\n try {\n const value = await fun();\n return value;\n } finally {\n resolve();\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["existsSync", "readFileSync", "dirname", "join", "resolve", "pkgUp", "trigger", "Lock", "executeSynchronized", "fun", "prevPromise", "_lastPromise", "getPromise", "resolve", "trigger", "value", "Promise", "findWorkspaceRoot", "startDir", "dir", "resolve", "workspaceYamlPath", "join", "existsSync", "pkgPath", "pkg", "JSON", "parse", "readFileSync", "workspaces", "parent", "dirname", "Error", "e2ePreset", "testDir", "packageJson", "pkgUp", "sync", "cwd", "packageDir", "split", "slice", "packageDirName", "pop", "workspaceRoot", "testResultOuputDir", "reporterOutputFile", "outputDir", "fullyParallel", "forbidOnly", "process", "env", "CI", "retries", "workers", "undefined", "reporter", "outputFile", "use", "trace", "setupPage", "browser", "options", "url", "bridgeLogs", "viewportSize", "context", "newContext", "page", "newPage", "setViewportSize", "lock", "Lock", "on", "error", "executeSynchronized", "console", "log", "msg", "argsPromise", "Promise", "all", "args", "map", "x", "jsonValue", "length", "err", "goto", "storybookUrl", "storyId", "port"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\n/* eslint-disable no-console */\n\nimport { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig, devices } from '@playwright/test';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nconst findWorkspaceRoot = (startDir: string): string => {\n let dir = resolve(startDir);\n while (dir !== '/') {\n try {\n // Check for pnpm-workspace.yaml first (modern pnpm approach)\n const workspaceYamlPath = join(dir, 'pnpm-workspace.yaml');\n if (existsSync(workspaceYamlPath)) {\n return dir;\n }\n\n // Check for package.json with workspaces field (legacy approach)\n const pkgPath = join(dir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n if (pkg.workspaces) {\n return dir;\n }\n } catch {}\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error('Could not find pnpm workspace root');\n};\n\nexport const e2ePreset = (testDir: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd: testDir });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirName = packageDir.split('/').pop();\n if (!packageDirName) {\n throw new Error('packageDirName not found');\n }\n\n const workspaceRoot = findWorkspaceRoot(packageDir);\n const testResultOuputDir = join(workspaceRoot, 'test-results/playwright/output', packageDirName);\n const reporterOutputFile = join(workspaceRoot, 'test-results/playwright/report', `${packageDirName}.json`);\n\n const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? 'all' : 'chromium');\n const projects = [\n {\n name: 'chromium',\n use: { ...devices['Desktop Chrome'] },\n },\n {\n name: 'firefox',\n use: { ...devices['Desktop Firefox'] },\n },\n {\n name: 'webkit',\n use: { ...devices['Desktop Safari'] },\n },\n ].filter((project) => {\n return browser === 'all' || project.name === browser;\n });\n\n return {\n testDir,\n outputDir: testResultOuputDir,\n // Run tests in files in parallel.\n fullyParallel: true,\n // Fail the build on CI if you accidentally left test.only in the source code.\n forbidOnly: !!process.env.CI,\n // Retry on CI only.\n // TODO(wittjosiah): Trunk suggests not retrying for better flaky test detection.\n // This is forgone for now as its unclear why some tests are flaky primarily on CI.\n // For the time being, a test is considered flaky if it can't pass within 2 retries.\n retries: process.env.CI ? 2 : 0,\n // Opt out of parallel tests on CI.\n workers: process.env.CI ? 1 : 4,\n // Reporter to use. See https://playwright.dev/docs/test-reporters.\n reporter: process.env.CI\n ? [\n ['list'],\n [\n 'json',\n {\n outputFile: reporterOutputFile,\n },\n ],\n ['junit', { outputFile: reporterOutputFile.replace(/\\.json$/, '.xml') }],\n ]\n : [['list']],\n use: {\n trace: 'retain-on-failure',\n },\n projects,\n };\n};\n\nexport type SetupOptions = {\n url?: string;\n bridgeLogs?: boolean;\n viewportSize?: Parameters<Page['setViewportSize']>[0];\n};\n\nexport const setupPage = async (browser: Browser | BrowserContext, options: SetupOptions = {}) => {\n const { url, bridgeLogs, viewportSize } = options;\n\n const context = 'newContext' in browser ? await browser.newContext() : browser;\n const page = await context.newPage();\n\n if (viewportSize) {\n await page.setViewportSize(viewportSize);\n }\n\n // TODO(wittjosiah): Remove?\n if (bridgeLogs) {\n const lock = new Lock();\n\n page.on('pageerror', async (error) => {\n await lock.executeSynchronized(async () => {\n // eslint-disable-next-line no-console\n console.log(error);\n });\n });\n\n page.on('console', async (msg) => {\n try {\n const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));\n await lock.executeSynchronized(async () => {\n const args = await argsPromise;\n\n if (args.length > 0) {\n console.log(...args);\n } else {\n console.log(msg);\n }\n });\n } catch (err) {\n console.error('Failed to parse message', err);\n }\n });\n }\n\n if (url) {\n await page.goto(url);\n }\n\n return { context, page };\n};\n\nexport const storybookUrl = (storyId: string, port = 9009) =>\n `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { trigger } from '@dxos/async';\n\n// Copied from @dxos/async.\nexport class Lock {\n private _lastPromise = Promise.resolve();\n\n async executeSynchronized<T>(fun: () => Promise<T>): Promise<T> {\n const prevPromise = this._lastPromise;\n const [getPromise, resolve] = trigger();\n this._lastPromise = getPromise();\n\n await prevPromise;\n try {\n const value = await fun();\n return value;\n } finally {\n resolve();\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["devices", "existsSync", "readFileSync", "dirname", "join", "resolve", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "value", "findWorkspaceRoot", "startDir", "dir", "resolve", "workspaceYamlPath", "join", "existsSync", "pkgPath", "pkg", "JSON", "parse", "readFileSync", "workspaces", "parent", "dirname", "Error", "e2ePreset", "testDir", "packageJson", "pkgUp", "sync", "cwd", "packageDir", "split", "slice", "packageDirName", "pop", "workspaceRoot", "testResultOuputDir", "reporterOutputFile", "browser", "process", "env", "PLAYWRIGHT_BROWSER", "CI", "projects", "name", "use", "devices", "filter", "project", "outputDir", "fullyParallel", "forbidOnly", "retries", "workers", "reporter", "outputFile", "replace", "trace", "setupPage", "options", "url", "bridgeLogs", "viewportSize", "context", "newContext", "page", "newPage", "setViewportSize", "lock", "Lock", "on", "error", "executeSynchronized", "console", "log", "msg", "argsPromise", "Promise", "all", "args", "map", "x", "jsonValue", "length", "err", "goto", "storybookUrl", "storyId", "port"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/lock.ts"],"names":[],"mappings":"AAOA,qBAAa,IAAI;IACf,OAAO,CAAC,YAAY,CAAqB;IAEnC,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAahE"}
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/lock.ts"],"names":[],"mappings":"AAOA,qBAAa,IAAI;IACf,OAAO,CAAC,YAAY,CAAqB;IAEnC,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAY9D;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/playwright.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAgC3G,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,oBAuC3C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,SAAS,OAAO,GAAG,cAAc,EAAE,UAAS,YAAiB;;;EA4C5F,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,aAAW,WACY,CAAC"}
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/playwright.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK,oBAAoB,EAAW,MAAM,kBAAkB,CAAC;AAkCpH,eAAO,MAAM,SAAS,YAAa,MAAM,KAAG,oBA8D3C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF,eAAO,MAAM,SAAS,YAAmB,OAAO,GAAG,cAAc,YAAW,YAAY;;;EA4CvF,CAAC;AAEF,eAAO,MAAM,YAAY,YAAa,MAAM,0BACyB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../../src/resource.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;CACvB;AAGD,eAAO,MAAM,YAAY,GAAU,GAAG,WAAW,YAAY,EAAE,kBAK9D,CAAC"}
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../../src/resource.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;CACvB;AAGD,eAAO,MAAM,YAAY,iBAAwB,YAAY,EAAE,kBAK9D,CAAC"}