@dxos/test-utils 0.8.3 → 0.8.4-main.1068cf700f

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.
@@ -1,4 +1,4 @@
1
- // packages/common/test-utils/src/resource.ts
1
+ // src/resource.ts
2
2
  import { onTestFinished } from "vitest";
3
3
  var openAndClose = async (...resources) => {
4
4
  for (const resourceLike of resources) {
@@ -1 +1 @@
1
- {"inputs":{"packages/common/test-utils/src/resource.ts":{"bytes":1545,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"packages/common/test-utils/src/index.ts":{"bytes":466,"imports":[{"path":"packages/common/test-utils/src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"packages/common/test-utils/src/lock.ts":{"bytes":2031,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"packages/common/test-utils/src/playwright.ts":{"bytes":8379,"imports":[{"path":"@nx/devkit","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"packages/common/test-utils/src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"packages/common/test-utils/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":798},"packages/common/test-utils/dist/lib/browser/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"packages/common/test-utils/src/index.ts","inputs":{"packages/common/test-utils/src/resource.ts":{"bytesInOutput":214},"packages/common/test-utils/src/index.ts":{"bytesInOutput":0}},"bytes":322},"packages/common/test-utils/dist/lib/browser/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5324},"packages/common/test-utils/dist/lib/browser/playwright.mjs":{"imports":[{"path":"@nx/devkit","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":"packages/common/test-utils/src/playwright.ts","inputs":{"packages/common/test-utils/src/playwright.ts":{"bytesInOutput":1838},"packages/common/test-utils/src/lock.ts":{"bytesInOutput":416}},"bytes":2487}}}
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":2018,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":15669,"imports":[{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@playwright/test","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":8987},"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":"@playwright/test","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":3706},"src/lock.ts":{"bytesInOutput":389}},"bytes":4247}}}
@@ -1,45 +1,106 @@
1
- // packages/common/test-utils/src/playwright.ts
2
- import { workspaceRoot } from "@nx/devkit";
3
- import { join, relative } from "@dxos/node-std/path";
1
+ // src/playwright.ts
2
+ import { existsSync, readFileSync } from "@dxos/node-std/fs";
3
+ import { dirname, join, resolve } from "@dxos/node-std/path";
4
+ import { devices } from "@playwright/test";
4
5
  import pkgUp from "pkg-up";
5
6
 
6
- // packages/common/test-utils/src/lock.ts
7
+ // src/lock.ts
7
8
  import { trigger } from "@dxos/async";
8
9
  var Lock = class {
9
- constructor() {
10
- this._lastPromise = Promise.resolve();
11
- }
10
+ _lastPromise = Promise.resolve();
12
11
  async executeSynchronized(fun) {
13
12
  const prevPromise = this._lastPromise;
14
- const [getPromise, resolve] = trigger();
13
+ const [getPromise, resolve2] = trigger();
15
14
  this._lastPromise = getPromise();
16
15
  await prevPromise;
17
16
  try {
18
17
  const value = await fun();
19
18
  return value;
20
19
  } finally {
21
- resolve();
20
+ resolve2();
22
21
  }
23
22
  }
24
23
  };
25
24
 
26
- // packages/common/test-utils/src/playwright.ts
27
- var e2ePreset = (cwd) => {
25
+ // src/playwright.ts
26
+ var findWorkspaceRoot = (startDir) => {
27
+ let dir = resolve(startDir);
28
+ while (dir !== "/") {
29
+ try {
30
+ const workspaceYamlPath = join(dir, "pnpm-workspace.yaml");
31
+ if (existsSync(workspaceYamlPath)) {
32
+ return dir;
33
+ }
34
+ const pkgPath = join(dir, "package.json");
35
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
36
+ if (pkg.workspaces) {
37
+ return dir;
38
+ }
39
+ } catch {
40
+ }
41
+ const parent = dirname(dir);
42
+ if (parent === dir) {
43
+ break;
44
+ }
45
+ dir = parent;
46
+ }
47
+ throw new Error("Could not find pnpm workspace root");
48
+ };
49
+ var e2ePreset = (testDir) => {
28
50
  const packageJson = pkgUp.sync({
29
- cwd
51
+ cwd: testDir
30
52
  });
31
53
  const packageDir = packageJson.split("/").slice(0, -1).join("/");
32
- const packageDirRelative = relative(workspaceRoot, packageDir);
33
- const testResultsDir = join(workspaceRoot, "test-results", packageDirRelative, "results.xml");
54
+ const packageDirName = packageDir.split("/").pop();
55
+ if (!packageDirName) {
56
+ throw new Error("packageDirName not found");
57
+ }
58
+ const workspaceRoot = findWorkspaceRoot(packageDir);
59
+ const testResultOuputDir = join(workspaceRoot, "test-results/playwright/output", packageDirName);
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
+ });
34
84
  return {
85
+ testDir,
86
+ outputDir: testResultOuputDir,
87
+ // Run tests in files in parallel.
88
+ fullyParallel: true,
89
+ // Fail the build on CI if you accidentally left test.only in the source code.
90
+ forbidOnly: !!process.env.CI,
91
+ // Retry on CI only.
92
+ retries: process.env.CI ? 2 : 0,
93
+ // Opt out of parallel tests on CI.
94
+ workers: process.env.CI ? 1 : void 0,
95
+ // Reporter to use. See https://playwright.dev/docs/test-reporters.
35
96
  reporter: process.env.CI ? [
36
97
  [
37
98
  "list"
38
99
  ],
39
100
  [
40
- "junit",
101
+ "json",
41
102
  {
42
- outputFile: testResultsDir
103
+ outputFile: reporterOutputFile
43
104
  }
44
105
  ]
45
106
  ] : [
@@ -49,7 +110,8 @@ var e2ePreset = (cwd) => {
49
110
  ],
50
111
  use: {
51
112
  trace: "retain-on-failure"
52
- }
113
+ },
114
+ projects
53
115
  };
54
116
  };
55
117
  var setupPage = async (browser, options = {}) => {
@@ -90,7 +152,7 @@ var setupPage = async (browser, options = {}) => {
90
152
  page
91
153
  };
92
154
  };
93
- var storybookUrl = (storyId) => `http://localhost:9009/iframe.html?id=${storyId}&viewMode=story`;
155
+ var storybookUrl = (storyId, port = 9009) => `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;
94
156
  export {
95
157
  e2ePreset,
96
158
  setupPage,
@@ -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 { workspaceRoot } from '@nx/devkit';\nimport { type Browser, type BrowserContext, type PlaywrightTestConfig, type Page } from '@playwright/test';\nimport { join, relative } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nexport const e2ePreset = (cwd: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirRelative = relative(workspaceRoot, packageDir);\n const testResultsDir = join(workspaceRoot, 'test-results', packageDirRelative, 'results.xml');\n\n return {\n reporter: process.env.CI ? [['list'], ['junit', { outputFile: testResultsDir }]] : [['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) => `http://localhost:9009/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": ";AAMA,SAASA,qBAAqB;AAE9B,SAASC,MAAMC,gBAAgB;AAC/B,OAAOC,WAAW;;;ACLlB,SAASC,eAAe;AAGjB,IAAMC,OAAN,MAAMA;EAAN;AACGC,wBAAeC,QAAQC,QAAO;;EAEtC,MAAMC,oBAAuBC,KAAmC;AAC9D,UAAMC,cAAc,KAAKL;AACzB,UAAM,CAACM,YAAYJ,OAAAA,IAAWK,QAAAA;AAC9B,SAAKP,eAAeM,WAAAA;AAEpB,UAAMD;AACN,QAAI;AACF,YAAMG,QAAQ,MAAMJ,IAAAA;AACpB,aAAOI;IACT,UAAA;AACEN,cAAAA;IACF;EACF;AACF;;;ADVO,IAAMO,YAAY,CAACC,QAAAA;AACxB,QAAMC,cAAcC,MAAMC,KAAK;IAAEH;EAAI,CAAA;AACrC,QAAMI,aAAaH,YAAaI,MAAM,GAAA,EAAKC,MAAM,GAAG,EAAC,EAAGC,KAAK,GAAA;AAC7D,QAAMC,qBAAqBC,SAASC,eAAeN,UAAAA;AACnD,QAAMO,iBAAiBJ,KAAKG,eAAe,gBAAgBF,oBAAoB,aAAA;AAE/E,SAAO;IACLI,UAAUC,QAAQC,IAAIC,KAAK;MAAC;QAAC;;MAAS;QAAC;QAAS;UAAEC,YAAYL;QAAe;;QAAM;MAAC;QAAC;;;IACrFM,KAAK;MACHC,OAAO;IACT;EACF;AACF;AAQO,IAAMC,YAAY,OAAOC,SAAmCC,UAAwB,CAAC,MAAC;AAC3F,QAAM,EAAEC,KAAKC,YAAYC,aAAY,IAAKH;AAE1C,QAAMI,UAAU,gBAAgBL,UAAU,MAAMA,QAAQM,WAAU,IAAKN;AACvE,QAAMO,OAAO,MAAMF,QAAQG,QAAO;AAElC,MAAIJ,cAAc;AAChB,UAAMG,KAAKE,gBAAgBL,YAAAA;EAC7B;AAGA,MAAID,YAAY;AACd,UAAMO,OAAO,IAAIC,KAAAA;AAEjBJ,SAAKK,GAAG,aAAa,OAAOC,UAAAA;AAC1B,YAAMH,KAAKI,oBAAoB,YAAA;AAE7BC,gBAAQC,IAAIH,KAAAA;MACd,CAAA;IACF,CAAA;AAEAN,SAAKK,GAAG,WAAW,OAAOK,QAAAA;AACxB,UAAI;AACF,cAAMC,cAAcC,QAAQC,IAAIH,IAAII,KAAI,EAAGC,IAAI,CAACC,MAAMA,EAAEC,UAAS,CAAA,CAAA;AACjE,cAAMd,KAAKI,oBAAoB,YAAA;AAC7B,gBAAMO,OAAO,MAAMH;AAEnB,cAAIG,KAAKI,SAAS,GAAG;AACnBV,oBAAQC,IAAG,GAAIK,IAAAA;UACjB,OAAO;AACLN,oBAAQC,IAAIC,GAAAA;UACd;QACF,CAAA;MACF,SAASS,KAAK;AACZX,gBAAQF,MAAM,2BAA2Ba,GAAAA;MAC3C;IACF,CAAA;EACF;AAEA,MAAIxB,KAAK;AACP,UAAMK,KAAKoB,KAAKzB,GAAAA;EAClB;AAEA,SAAO;IAAEG;IAASE;EAAK;AACzB;AAEO,IAAMqB,eAAe,CAACC,YAAoB,wCAAwCA,OAAAA;",
6
- "names": ["workspaceRoot", "join", "relative", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "trigger", "value", "e2ePreset", "cwd", "packageJson", "pkgUp", "sync", "packageDir", "split", "slice", "join", "packageDirRelative", "relative", "workspaceRoot", "testResultsDir", "reporter", "process", "env", "CI", "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"]
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, devices } 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 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 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 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": ["existsSync", "readFileSync", "dirname", "join", "resolve", "devices", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "trigger", "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", "undefined", "reporter", "outputFile", "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,6 +1,6 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
- // packages/common/test-utils/src/resource.ts
3
+ // src/resource.ts
4
4
  import { onTestFinished } from "vitest";
5
5
  var openAndClose = async (...resources) => {
6
6
  for (const resourceLike of resources) {
@@ -1 +1 @@
1
- {"inputs":{"packages/common/test-utils/src/resource.ts":{"bytes":1545,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"packages/common/test-utils/src/index.ts":{"bytes":466,"imports":[{"path":"packages/common/test-utils/src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"packages/common/test-utils/src/lock.ts":{"bytes":2031,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"packages/common/test-utils/src/playwright.ts":{"bytes":8379,"imports":[{"path":"@nx/devkit","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"packages/common/test-utils/src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"packages/common/test-utils/dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":800},"packages/common/test-utils/dist/lib/node-esm/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"packages/common/test-utils/src/index.ts","inputs":{"packages/common/test-utils/src/resource.ts":{"bytesInOutput":214},"packages/common/test-utils/src/index.ts":{"bytesInOutput":0}},"bytes":415},"packages/common/test-utils/dist/lib/node-esm/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5326},"packages/common/test-utils/dist/lib/node-esm/playwright.mjs":{"imports":[{"path":"@nx/devkit","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":"packages/common/test-utils/src/playwright.ts","inputs":{"packages/common/test-utils/src/playwright.ts":{"bytesInOutput":1828},"packages/common/test-utils/src/lock.ts":{"bytesInOutput":416}},"bytes":2570}}}
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":2018,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":15669,"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@playwright/test","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":8989},"dist/lib/node-esm/playwright.mjs":{"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@playwright/test","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":3686},"src/lock.ts":{"bytesInOutput":389}},"bytes":4320}}}
@@ -1,47 +1,108 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
- // packages/common/test-utils/src/playwright.ts
4
- import { workspaceRoot } from "@nx/devkit";
5
- import { join, relative } from "node:path";
3
+ // src/playwright.ts
4
+ import { existsSync, readFileSync } from "node:fs";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { devices } from "@playwright/test";
6
7
  import pkgUp from "pkg-up";
7
8
 
8
- // packages/common/test-utils/src/lock.ts
9
+ // src/lock.ts
9
10
  import { trigger } from "@dxos/async";
10
11
  var Lock = class {
11
- constructor() {
12
- this._lastPromise = Promise.resolve();
13
- }
12
+ _lastPromise = Promise.resolve();
14
13
  async executeSynchronized(fun) {
15
14
  const prevPromise = this._lastPromise;
16
- const [getPromise, resolve] = trigger();
15
+ const [getPromise, resolve2] = trigger();
17
16
  this._lastPromise = getPromise();
18
17
  await prevPromise;
19
18
  try {
20
19
  const value = await fun();
21
20
  return value;
22
21
  } finally {
23
- resolve();
22
+ resolve2();
24
23
  }
25
24
  }
26
25
  };
27
26
 
28
- // packages/common/test-utils/src/playwright.ts
29
- var e2ePreset = (cwd) => {
27
+ // src/playwright.ts
28
+ var findWorkspaceRoot = (startDir) => {
29
+ let dir = resolve(startDir);
30
+ while (dir !== "/") {
31
+ try {
32
+ const workspaceYamlPath = join(dir, "pnpm-workspace.yaml");
33
+ if (existsSync(workspaceYamlPath)) {
34
+ return dir;
35
+ }
36
+ const pkgPath = join(dir, "package.json");
37
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
38
+ if (pkg.workspaces) {
39
+ return dir;
40
+ }
41
+ } catch {
42
+ }
43
+ const parent = dirname(dir);
44
+ if (parent === dir) {
45
+ break;
46
+ }
47
+ dir = parent;
48
+ }
49
+ throw new Error("Could not find pnpm workspace root");
50
+ };
51
+ var e2ePreset = (testDir) => {
30
52
  const packageJson = pkgUp.sync({
31
- cwd
53
+ cwd: testDir
32
54
  });
33
55
  const packageDir = packageJson.split("/").slice(0, -1).join("/");
34
- const packageDirRelative = relative(workspaceRoot, packageDir);
35
- const testResultsDir = join(workspaceRoot, "test-results", packageDirRelative, "results.xml");
56
+ const packageDirName = packageDir.split("/").pop();
57
+ if (!packageDirName) {
58
+ throw new Error("packageDirName not found");
59
+ }
60
+ const workspaceRoot = findWorkspaceRoot(packageDir);
61
+ const testResultOuputDir = join(workspaceRoot, "test-results/playwright/output", packageDirName);
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
+ });
36
86
  return {
87
+ testDir,
88
+ outputDir: testResultOuputDir,
89
+ // Run tests in files in parallel.
90
+ fullyParallel: true,
91
+ // Fail the build on CI if you accidentally left test.only in the source code.
92
+ forbidOnly: !!process.env.CI,
93
+ // Retry on CI only.
94
+ retries: process.env.CI ? 2 : 0,
95
+ // Opt out of parallel tests on CI.
96
+ workers: process.env.CI ? 1 : void 0,
97
+ // Reporter to use. See https://playwright.dev/docs/test-reporters.
37
98
  reporter: process.env.CI ? [
38
99
  [
39
100
  "list"
40
101
  ],
41
102
  [
42
- "junit",
103
+ "json",
43
104
  {
44
- outputFile: testResultsDir
105
+ outputFile: reporterOutputFile
45
106
  }
46
107
  ]
47
108
  ] : [
@@ -51,7 +112,8 @@ var e2ePreset = (cwd) => {
51
112
  ],
52
113
  use: {
53
114
  trace: "retain-on-failure"
54
- }
115
+ },
116
+ projects
55
117
  };
56
118
  };
57
119
  var setupPage = async (browser, options = {}) => {
@@ -92,7 +154,7 @@ var setupPage = async (browser, options = {}) => {
92
154
  page
93
155
  };
94
156
  };
95
- var storybookUrl = (storyId) => `http://localhost:9009/iframe.html?id=${storyId}&viewMode=story`;
157
+ var storybookUrl = (storyId, port = 9009) => `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;
96
158
  export {
97
159
  e2ePreset,
98
160
  setupPage,
@@ -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 { workspaceRoot } from '@nx/devkit';\nimport { type Browser, type BrowserContext, type PlaywrightTestConfig, type Page } from '@playwright/test';\nimport { join, relative } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nexport const e2ePreset = (cwd: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirRelative = relative(workspaceRoot, packageDir);\n const testResultsDir = join(workspaceRoot, 'test-results', packageDirRelative, 'results.xml');\n\n return {\n reporter: process.env.CI ? [['list'], ['junit', { outputFile: testResultsDir }]] : [['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) => `http://localhost:9009/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": ";;;AAMA,SAASA,qBAAqB;AAE9B,SAASC,MAAMC,gBAAgB;AAC/B,OAAOC,WAAW;;;ACLlB,SAASC,eAAe;AAGjB,IAAMC,OAAN,MAAMA;EAAN;AACGC,wBAAeC,QAAQC,QAAO;;EAEtC,MAAMC,oBAAuBC,KAAmC;AAC9D,UAAMC,cAAc,KAAKL;AACzB,UAAM,CAACM,YAAYJ,OAAAA,IAAWK,QAAAA;AAC9B,SAAKP,eAAeM,WAAAA;AAEpB,UAAMD;AACN,QAAI;AACF,YAAMG,QAAQ,MAAMJ,IAAAA;AACpB,aAAOI;IACT,UAAA;AACEN,cAAAA;IACF;EACF;AACF;;;ADVO,IAAMO,YAAY,CAACC,QAAAA;AACxB,QAAMC,cAAcC,MAAMC,KAAK;IAAEH;EAAI,CAAA;AACrC,QAAMI,aAAaH,YAAaI,MAAM,GAAA,EAAKC,MAAM,GAAG,EAAC,EAAGC,KAAK,GAAA;AAC7D,QAAMC,qBAAqBC,SAASC,eAAeN,UAAAA;AACnD,QAAMO,iBAAiBJ,KAAKG,eAAe,gBAAgBF,oBAAoB,aAAA;AAE/E,SAAO;IACLI,UAAUC,QAAQC,IAAIC,KAAK;MAAC;QAAC;;MAAS;QAAC;QAAS;UAAEC,YAAYL;QAAe;;QAAM;MAAC;QAAC;;;IACrFM,KAAK;MACHC,OAAO;IACT;EACF;AACF;AAQO,IAAMC,YAAY,OAAOC,SAAmCC,UAAwB,CAAC,MAAC;AAC3F,QAAM,EAAEC,KAAKC,YAAYC,aAAY,IAAKH;AAE1C,QAAMI,UAAU,gBAAgBL,UAAU,MAAMA,QAAQM,WAAU,IAAKN;AACvE,QAAMO,OAAO,MAAMF,QAAQG,QAAO;AAElC,MAAIJ,cAAc;AAChB,UAAMG,KAAKE,gBAAgBL,YAAAA;EAC7B;AAGA,MAAID,YAAY;AACd,UAAMO,OAAO,IAAIC,KAAAA;AAEjBJ,SAAKK,GAAG,aAAa,OAAOC,UAAAA;AAC1B,YAAMH,KAAKI,oBAAoB,YAAA;AAE7BC,gBAAQC,IAAIH,KAAAA;MACd,CAAA;IACF,CAAA;AAEAN,SAAKK,GAAG,WAAW,OAAOK,QAAAA;AACxB,UAAI;AACF,cAAMC,cAAcC,QAAQC,IAAIH,IAAII,KAAI,EAAGC,IAAI,CAACC,MAAMA,EAAEC,UAAS,CAAA,CAAA;AACjE,cAAMd,KAAKI,oBAAoB,YAAA;AAC7B,gBAAMO,OAAO,MAAMH;AAEnB,cAAIG,KAAKI,SAAS,GAAG;AACnBV,oBAAQC,IAAG,GAAIK,IAAAA;UACjB,OAAO;AACLN,oBAAQC,IAAIC,GAAAA;UACd;QACF,CAAA;MACF,SAASS,KAAK;AACZX,gBAAQF,MAAM,2BAA2Ba,GAAAA;MAC3C;IACF,CAAA;EACF;AAEA,MAAIxB,KAAK;AACP,UAAMK,KAAKoB,KAAKzB,GAAAA;EAClB;AAEA,SAAO;IAAEG;IAASE;EAAK;AACzB;AAEO,IAAMqB,eAAe,CAACC,YAAoB,wCAAwCA,OAAAA;",
6
- "names": ["workspaceRoot", "join", "relative", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "trigger", "value", "e2ePreset", "cwd", "packageJson", "pkgUp", "sync", "packageDir", "split", "slice", "join", "packageDirRelative", "relative", "workspaceRoot", "testResultsDir", "reporter", "process", "env", "CI", "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"]
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, devices } 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 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 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 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": ["existsSync", "readFileSync", "dirname", "join", "resolve", "devices", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "trigger", "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", "undefined", "reporter", "outputFile", "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,5 +1,5 @@
1
- import { type Browser, type BrowserContext, type PlaywrightTestConfig, type Page } from '@playwright/test';
2
- export declare const e2ePreset: (cwd: string) => PlaywrightTestConfig;
1
+ import { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig } from '@playwright/test';
2
+ export declare const e2ePreset: (testDir: string) => PlaywrightTestConfig;
3
3
  export type SetupOptions = {
4
4
  url?: string;
5
5
  bridgeLogs?: boolean;
@@ -9,5 +9,5 @@ export declare const setupPage: (browser: Browser | BrowserContext, options?: Se
9
9
  context: BrowserContext;
10
10
  page: Page;
11
11
  }>;
12
- export declare const storybookUrl: (storyId: string) => string;
12
+ export declare const storybookUrl: (storyId: string, port?: number) => string;
13
13
  //# sourceMappingURL=playwright.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/playwright.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM3G,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,KAAG,oBAYvC,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,WAAqE,CAAC"}
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,EAAW,MAAM,kBAAkB,CAAC;AAgCpH,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,oBA0D3C,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"}