playwright-reborn 0.2.2 → 0.2.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.4
4
+
5
+ - Refresh the report UI with a persistent sidebar, dashboard overview, and clearer test exploration.
6
+ - Add Tags and Sort dropdowns, remembered light and dark themes, improved filter controls, and responsive long-name handling.
7
+
8
+ ## 0.2.3
9
+
10
+ - `steps: 'user'` leaves expectations and `test.attach` calls out of the step tree.
11
+ - Protect unrelated output folders, symbolic links, and project ancestors; custom report filenames can be replaced on later runs.
12
+ - Build reports in a temporary folder before replacing the previous report, preserving attachment sources and the last report when assets are missing.
13
+ - Keep interrupted outcomes separate from skipped tests and explain unexpected passes on tests marked to fail.
14
+ - Remove duplicate step attachments, normalize embedded image MIME types, and preserve UTF-8 across log chunks.
15
+ - Capture failing final attempts consistently in `last` mode; automatic opening defaults to `never` in CI.
16
+ - Fix hash navigation, browser back, malformed IDs, pending searches, log links, and keyboard focus; add filter reset and useful empty states.
17
+ - Improve status colors, run status, contrast, spacing, mobile navigation, long content, chart sizing, and screenshot presentation.
18
+ - Bound test and timeline rendering to batches of 200 and support prototype-like filenames and a project named `all`.
19
+ - Add reporter/fixture integration coverage and reusable browser regression checks; stop verification when the build or demo outcomes are wrong.
20
+
3
21
  ## 0.2.2
4
22
 
5
23
  - The company name has a subtitle. The default is Test Automation.
package/README.md CHANGED
@@ -61,9 +61,9 @@ Pass any of these next to the reporter. Omitted settings use the default.
61
61
  | Setting | Default | Allowed |
62
62
  |---|---|---|
63
63
  | `company` | Project folder name | Any name. This is the large title. It does not change when a run fails. |
64
- | `accent` | `green` | `green`, `red`, `blue`, `amber`, `violet`. Colors the light field, failure marks, and links. |
65
- | `open` | `on-failure` | `always`, `never`, `on-failure`. When to open the HTML file after the run. Use `never` when `CI` is set. |
66
- | `outputFolder` | `reborn-report` | A folder path. Each run replaces that folder. If you leave this unset, a sharded run writes `reborn-report-shard-1` and so on. |
64
+ | `accent` | `green` | `green`, `red`, `blue`, `amber`, `violet`. Colors the light field, selection, charts, and links. Failures stay coral and flaky results stay amber for consistent recognition. |
65
+ | `open` | `on-failure`, or `never` in CI | `always`, `never`, `on-failure`. When to open the HTML file after the run. Use `never` when `CI` is set. |
66
+ | `outputFolder` | `reborn-report` | A dedicated folder path. Each run replaces its previous report. Existing empty folders are accepted; unrelated non-empty folders and symbolic links are refused. If you leave this unset, a sharded run writes `reborn-report-shard-1` and so on. |
67
67
  | `reportFileName` | `index.html` | One `.html` file name, with no folders. Jenkins HTML Publisher can point at this file. |
68
68
  | `inline` | `true` | `true` or `false`. `true` writes one HTML file with the CSS, script, and fonts inside it, and embeds screenshots. Traces and other files stay as relative links in the report folder. |
69
69
  | `overview` | `chart` | `chart` or `timeline`. Which view the overview opens on. The buttons on the page can still switch it. |
@@ -76,7 +76,7 @@ Pass any of these next to the reporter. Omitted settings use the default.
76
76
  | `commitShort` | `true` | `true` shows the first 7 characters of the commit. `false` shows the full value. |
77
77
  | `ignoreTags` | `^@?HC2T-` | A pattern for tags to hide, or `false` to keep every tag. |
78
78
  | `screenshots` | `failure` | `off`, `failure`, `last`, or `steps`. When the fixture takes a picture. The reporter sets `REBORN_SCREENSHOTS` in `onBegin`. Do not set that variable yourself. The Screenshots page stays in the report either way. |
79
- | `steps` | `user` | `user` or `all`. `user` keeps the steps you wrote and the expectations, and leaves hooks and Playwright's own API calls out. `all` keeps those calls too. |
79
+ | `steps` | `user` | `user` or `all`. `user` shows the steps a person would follow. It leaves expectations, `test.attach` calls, hooks, and Playwright's own API calls out. `all` keeps those calls too. |
80
80
  | `showLogs` | `true` | `true` or `false`. `false` leaves the Logs page out. |
81
81
  | `showFiles` | `true` | `true` or `false`. `false` leaves the Files page out. |
82
82
  | `suite` | empty | Suite name shown on the overview. |
@@ -94,17 +94,20 @@ The reporter cannot photograph the page. Import the fixture in the tests that sh
94
94
  ```ts
95
95
  import { test, expect, step } from 'playwright-reborn/fixture';
96
96
 
97
- const order = await step('read the receipt', async () => {
98
- return page.locator('#order').textContent();
97
+ test('receipt shows the order id', async ({ page }) => {
98
+ await page.setContent('<p id="order">1842</p>');
99
+ const order = await step('read the receipt', async () => {
100
+ return page.locator('#order').textContent();
101
+ });
102
+ expect(order).toBe('1842');
99
103
  });
100
- await expect(order).toBe('1842');
101
104
  ```
102
105
 
103
106
  `step` returns the value of its body, the same way `test.step` does. `test` is a normal Playwright test object, so a suite can `test.extend(...)` with its own fixtures.
104
107
 
105
108
  The page fixture keeps each screenshot on the test that is running, including when tests run in parallel.
106
109
 
107
- `failure` and `last` take one picture at the end of an attempt, for tests that use `page`. `steps` also takes a picture after each `step()`. A plain `test.step` is not photographed. Turn Playwright's own `screenshot` option off if you do not want a second copy of the same picture.
110
+ `failure` takes a picture of failing attempts. `last` takes one picture at the end of every attempt, for tests that use `page`; failing attempts appear under Last failing step. `steps` also takes a picture after each `step()`. A plain `test.step` is not photographed. Turn Playwright's own `screenshot` option off if you do not want a second copy of the same picture.
108
111
 
109
112
  Files larger than 25MB are listed and not copied.
110
113
 
@@ -122,7 +125,21 @@ publishHTML([
122
125
 
123
126
  `inline: true` is the default, so that HTML file opens from a Jenkins artifact or from disk without a CDN and without `assets/report.css`. Keep the report folder together if the Files page should still download traces and video. Those links are relative paths inside the folder.
124
127
 
125
- Set `open: 'never'` when `CI` is set so the reporter does not launch a browser on the agent.
128
+ When `CI` is set, automatic opening defaults to `never`. An explicit `open` option still wins.
129
+
130
+ ## Development and verification
131
+
132
+ Run `npm test` to build and run the unit tests plus real Playwright reporter/fixture integration tests. The integration tests stub browser I/O and check parallel screenshot isolation, return values, failures, and every screenshot mode.
133
+
134
+ Run `npm run verify` for the full demo and browser checks. The demo deliberately includes one failed test and one flaky test. The verifier requires those exact outcomes and fails on additional failures. `REBORN_BROWSER_EXECUTABLE` selects a browser executable for both the demo and verifier; `REBORN_BROWSER_CDP_URL` can connect the verifier to an existing compatible browser.
135
+
136
+ To check an existing exported report in your normal browser without launching Playwright, run:
137
+
138
+ ```bash
139
+ npm run verify:browser -- reborn-report/index.html /tmp/reborn-browser-checks.html
140
+ ```
141
+
142
+ Open the generated HTML file. It runs the same interaction regressions in browser frames, including navigation, keyboard focus, filters, empty reports, pagination, and long content at 320px, 390px, and 768px widths. This verifier expects the demo report's logs and screenshots. Both reports and this verification page work from disk.
126
143
 
127
144
  ## License
128
145
 
package/dist/fixture.js CHANGED
@@ -35,10 +35,11 @@ exports.test = test_1.test.extend({
35
35
  try {
36
36
  await use(page);
37
37
  const mode = screenshotMode();
38
- const failed = testInfo.status === 'failed' || testInfo.status === 'timedOut';
39
- if (mode === 'last' || (mode === 'steps' && !failed))
38
+ const failed = testInfo.status === 'failed' || testInfo.status === 'timedOut' || testInfo.status === 'interrupted'
39
+ || (testInfo.status === 'passed' && testInfo.expectedStatus === 'failed');
40
+ if ((mode === 'last' || mode === 'steps') && !failed)
40
41
  await shot('reborn:last', testInfo);
41
- if ((mode === 'failure' || mode === 'steps') && failed)
42
+ if ((mode === 'failure' || mode === 'last' || mode === 'steps') && failed)
42
43
  await shot('reborn:failure', testInfo);
43
44
  }
44
45
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"fixture.js","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":";;;AA2CA,oBAYC;AAvDD,2CAAuE;AAyC9D,uFAzCc,aAAM,OAyCd;AAxCf,uCAA8D;AAE9D,KAAK,UAAU,IAAI,CAAC,IAAY,EAAE,QAAmB;IACnD,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,CAAC;YACH,IAAI,GAAG,YAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,iBAAO,EAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;AACH,CAAC;AAED,SAAS,cAAc;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS,CAAC;AACrD,CAAC;AAEY,QAAA,IAAI,GAAG,WAAI,CAAC,MAAM,CAAC;IAC9B,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;QACtC,IAAA,sBAAY,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC;YAChB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC;YAC9E,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC;gBAAE,MAAM,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC1F,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,MAAM;gBAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACjG,CAAC;gBAAS,CAAC;YACT,IAAA,oBAAU,EAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAII,KAAK,UAAU,IAAI,CAAI,KAAa,EAAE,IAA0B;IACrE,MAAM,QAAQ,GAAG,YAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,YAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACjC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;YAC3B,IAAI,cAAc,EAAE,KAAK,OAAO;gBAAE,MAAM,IAAI,CAAC,eAAe,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/E,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,cAAc,EAAE,KAAK,OAAO;gBAAE,MAAM,IAAI,CAAC,eAAe,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/E,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"fixture.js","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":";;;AA4CA,oBAYC;AAxDD,2CAAuE;AA0C9D,uFA1Cc,aAAM,OA0Cd;AAzCf,uCAA8D;AAE9D,KAAK,UAAU,IAAI,CAAC,IAAY,EAAE,QAAmB;IACnD,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,CAAC;YACH,IAAI,GAAG,YAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,iBAAO,EAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;AACH,CAAC;AAED,SAAS,cAAc;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS,CAAC;AACrD,CAAC;AAEY,QAAA,IAAI,GAAG,WAAI,CAAC,MAAM,CAAC;IAC9B,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;QACtC,IAAA,sBAAY,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC;YAChB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,IAAI,QAAQ,CAAC,MAAM,KAAK,aAAa;mBAC7G,CAAC,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC;YAC5E,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC1F,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,MAAM;gBAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACpH,CAAC;gBAAS,CAAC;YACT,IAAA,oBAAU,EAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAII,KAAK,UAAU,IAAI,CAAI,KAAa,EAAE,IAA0B;IACrE,MAAM,QAAQ,GAAG,YAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,YAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACjC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;YAC3B,IAAI,cAAc,EAAE,KAAK,OAAO;gBAAE,MAAM,IAAI,CAAC,eAAe,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/E,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,cAAc,EAAE,KAAK,OAAO;gBAAE,MAAM,IAAI,CAAC,eAAe,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/E,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/format.js CHANGED
@@ -11,9 +11,11 @@ exports.attachmentKind = attachmentKind;
11
11
  exports.parseShotName = parseShotName;
12
12
  exports.durationBand = durationBand;
13
13
  exports.safeFileName = safeFileName;
14
+ const node_string_decoder_1 = require("node:string_decoder");
15
+ const node_util_1 = require("node:util");
14
16
  const LOG_LIMIT = 100_000;
15
17
  function stripAnsi(value) {
16
- return value.replace(/\u001b\[[0-9;]*m/g, '');
18
+ return (0, node_util_1.stripVTControlCharacters)(value);
17
19
  }
18
20
  function capText(value, limit = LOG_LIMIT) {
19
21
  if (value.length <= limit)
@@ -23,7 +25,18 @@ function capText(value, limit = LOG_LIMIT) {
23
25
  function joinChunks(chunks) {
24
26
  if (!chunks || chunks.length === 0)
25
27
  return '';
26
- const text = chunks.map((chunk) => (typeof chunk === 'string' ? chunk : chunk.toString('utf8'))).join('');
28
+ let decoder = new node_string_decoder_1.StringDecoder('utf8');
29
+ let text = '';
30
+ for (const chunk of chunks) {
31
+ if (typeof chunk === 'string') {
32
+ text += decoder.end() + chunk;
33
+ decoder = new node_string_decoder_1.StringDecoder('utf8');
34
+ }
35
+ else {
36
+ text += decoder.write(chunk);
37
+ }
38
+ }
39
+ text += decoder.end();
27
40
  return capText(stripAnsi(text));
28
41
  }
29
42
  function embedJson(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
package/dist/options.js CHANGED
@@ -11,7 +11,7 @@ function parseOptions(options = {}) {
11
11
  if (options === null || typeof options !== 'object' || Array.isArray(options)) {
12
12
  throw new Error('Reborn options must be an object.');
13
13
  }
14
- const open = options.open ?? 'on-failure';
14
+ const open = options.open ?? (process.env.CI ? 'never' : 'on-failure');
15
15
  if (!OPENS.has(open)) {
16
16
  throw new Error('Reborn open must be "always", "never", or "on-failure".');
17
17
  }
@@ -34,7 +34,8 @@ function parseOptions(options = {}) {
34
34
  const showCredit = flag(options.showCredit, 'showCredit', false);
35
35
  const showPlaywrightVersion = flag(options.showPlaywrightVersion, 'showPlaywrightVersion', false);
36
36
  const showProjects = flag(options.showProjects, 'showProjects', false);
37
- const showProjectFilter = showProjects && flag(options.showProjectFilter, 'showProjectFilter', false);
37
+ const projectFilter = flag(options.showProjectFilter, 'showProjectFilter', false);
38
+ const showProjectFilter = showProjects && projectFilter;
38
39
  const commitShort = flag(options.commitShort, 'commitShort', true);
39
40
  const overview = options.overview ?? 'chart';
40
41
  if (!OVERVIEWS.has(overview)) {
@@ -50,7 +51,7 @@ function parseOptions(options = {}) {
50
51
  throw new Error('Reborn outputFolder must be a non-empty path.');
51
52
  }
52
53
  const reportFileName = options.reportFileName ?? 'index.html';
53
- if (!/^[A-Za-z0-9._-]+\.html$/.test(reportFileName)) {
54
+ if (typeof reportFileName !== 'string' || !/^[A-Za-z0-9._-]+\.html$/.test(reportFileName)) {
54
55
  throw new Error('Reborn reportFileName must be a single .html file name.');
55
56
  }
56
57
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
package/dist/paths.js CHANGED
@@ -10,7 +10,7 @@ const promises_1 = __importDefault(require("node:fs/promises"));
10
10
  const node_path_1 = __importDefault(require("node:path"));
11
11
  function relativePosix(rootDir, file) {
12
12
  const relative = node_path_1.default.relative(rootDir, file);
13
- if (!relative || relative.startsWith('..') || node_path_1.default.isAbsolute(relative)) {
13
+ if (!relative || relative === '..' || relative.startsWith(`..${node_path_1.default.sep}`) || node_path_1.default.isAbsolute(relative)) {
14
14
  return file.split(node_path_1.default.sep).join('/');
15
15
  }
16
16
  return relative.split(node_path_1.default.sep).join('/');
@@ -27,6 +27,10 @@ function resolveOutputFolder(rootDir, outputFolder) {
27
27
  if (resolved === root) {
28
28
  throw new Error('Reborn output folder must not be the project root.');
29
29
  }
30
+ const fromOutput = node_path_1.default.relative(resolved, root);
31
+ if (fromOutput && fromOutput !== '..' && !fromOutput.startsWith(`..${node_path_1.default.sep}`) && !node_path_1.default.isAbsolute(fromOutput)) {
32
+ throw new Error('Reborn output folder must not be an ancestor of the project root.');
33
+ }
30
34
  return resolved;
31
35
  }
32
36
  const relative = node_path_1.default.relative(root, resolved);
@@ -36,32 +40,36 @@ function resolveOutputFolder(rootDir, outputFolder) {
36
40
  return resolved;
37
41
  }
38
42
  async function isRebornReport(dir) {
39
- try {
40
- const html = await promises_1.default.readFile(node_path_1.default.join(dir, 'index.html'), 'utf8');
41
- return html.includes('id="reborn-data"');
42
- }
43
- catch {
44
- return false;
43
+ const entries = await promises_1.default.readdir(dir, { withFileTypes: true });
44
+ for (const entry of entries) {
45
+ if (!entry.isFile() || !entry.name.endsWith('.html'))
46
+ continue;
47
+ const html = await promises_1.default.readFile(node_path_1.default.join(dir, entry.name), 'utf8');
48
+ if (html.includes('<script id="reborn-data" type="application/json">'))
49
+ return true;
45
50
  }
51
+ return false;
46
52
  }
47
53
  async function prepareOutput(dir) {
48
54
  let stat;
49
55
  try {
50
- stat = await promises_1.default.stat(dir);
56
+ stat = await promises_1.default.lstat(dir);
51
57
  }
52
58
  catch (error) {
53
59
  const code = typeof error === 'object' && error && 'code' in error ? error.code : undefined;
54
60
  if (code !== 'ENOENT')
55
61
  throw error;
56
62
  }
63
+ if (stat?.isSymbolicLink()) {
64
+ throw new Error(`Refusing to replace symbolic link ${dir}.`);
65
+ }
57
66
  if (stat && !stat.isDirectory()) {
58
67
  throw new Error(`Reborn output folder ${dir} exists and is not a directory.`);
59
68
  }
60
69
  if (stat) {
61
- const base = node_path_1.default.basename(dir);
62
- const named = base === 'reborn-report' || base.startsWith('reborn-report-');
70
+ const empty = (await promises_1.default.readdir(dir)).length === 0;
63
71
  const ours = await isRebornReport(dir);
64
- if (!named && !ours) {
72
+ if (!empty && !ours) {
65
73
  throw new Error(`Refusing to replace ${dir} because it is not a Reborn report folder.`);
66
74
  }
67
75
  await promises_1.default.rm(dir, { recursive: true, force: true });
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
package/dist/render.js CHANGED
@@ -35,10 +35,11 @@ function renderHtml(json, assets) {
35
35
  <title>Report</title>
36
36
  ${style}
37
37
  </head>
38
- <body style="margin:0;background:#080808;color:#f0f0f0">
38
+ <body style="margin:0;background:#f3f7fd;color:#17324f">
39
39
  <div class="light"></div>
40
40
  <a class="skip" href="#tests">Skip to tests</a>
41
41
  <main class="page" id="app"></main>
42
+ <noscript><p style="padding:24px">Enable JavaScript to view this report.</p></noscript>
42
43
  <script id="reborn-data" type="application/json">${json}</script>
43
44
  ${script}
44
45
  </body>
@@ -66,16 +67,10 @@ async function tooLarge(file) {
66
67
  return false;
67
68
  }
68
69
  }
69
- function markOmitted(report, target) {
70
- for (const test of report.tests) {
71
- for (const attempt of test.attempts) {
72
- for (const attachment of attempt.attachments) {
73
- if (attachment.path !== target)
74
- continue;
75
- attachment.omitted = true;
76
- attachment.path = '';
77
- }
78
- }
70
+ function markOmitted(attachments) {
71
+ for (const attachment of attachments) {
72
+ attachment.omitted = true;
73
+ attachment.path = '';
79
74
  }
80
75
  }
81
76
  async function writePending(outputDir, file) {
@@ -98,15 +93,9 @@ async function fileBody(file) {
98
93
  return promises_1.default.readFile(file.sourcePath);
99
94
  throw new Error('Attachment had no file and no body.');
100
95
  }
101
- function replacePath(report, target, next) {
102
- for (const test of report.tests) {
103
- for (const attempt of test.attempts) {
104
- for (const attachment of attempt.attachments) {
105
- if (attachment.path === target)
106
- attachment.path = next;
107
- }
108
- }
109
- }
96
+ function replacePath(attachments, next) {
97
+ for (const attachment of attachments)
98
+ attachment.path = next;
110
99
  }
111
100
  function isImage(file) {
112
101
  return (file.contentType || '').toLowerCase().startsWith('image/');
@@ -127,7 +116,7 @@ async function replaceFontFiles(css, fontDir) {
127
116
  }
128
117
  return embedFontUrls(css, (file) => uris.get(file) || `fonts/${file}`);
129
118
  }
130
- async function writeReport(outputDir, report, files, uiDir, output = { inline: true, reportFileName: 'index.html' }) {
119
+ async function writeReportContents(outputDir, report, files, uiDir, output = { inline: true, reportFileName: 'index.html' }) {
131
120
  const stylesheet = node_path_1.default.join(uiDir, 'report.css');
132
121
  const script = node_path_1.default.join(uiDir, 'report.js');
133
122
  try {
@@ -137,7 +126,6 @@ async function writeReport(outputDir, report, files, uiDir, output = { inline: t
137
126
  catch {
138
127
  throw new Error('Reborn UI assets are missing. Build the package before running tests.');
139
128
  }
140
- await (0, paths_1.prepareOutput)(outputDir);
141
129
  const assets = node_path_1.default.join(outputDir, 'assets');
142
130
  await promises_1.default.mkdir(node_path_1.default.join(assets, 'attachments'), { recursive: true });
143
131
  await promises_1.default.mkdir(node_path_1.default.join(assets, 'fonts'), { recursive: true });
@@ -149,17 +137,28 @@ async function writeReport(outputDir, report, files, uiDir, output = { inline: t
149
137
  await promises_1.default.copyFile(script, node_path_1.default.join(assets, 'report.js'));
150
138
  await promises_1.default.cp(node_path_1.default.join(uiDir, 'fonts'), node_path_1.default.join(assets, 'fonts'), { recursive: true });
151
139
  }
140
+ const attachmentIndex = new Map();
141
+ for (const test of report.tests) {
142
+ for (const attempt of test.attempts) {
143
+ for (const attachment of attempt.attachments) {
144
+ const entries = attachmentIndex.get(attachment.path) || [];
145
+ entries.push(attachment);
146
+ attachmentIndex.set(attachment.path, entries);
147
+ }
148
+ }
149
+ }
152
150
  for (const file of files) {
151
+ const attachments = attachmentIndex.get(file.target) || [];
153
152
  if (await tooLarge(file)) {
154
- markOmitted(report, file.target);
153
+ markOmitted(attachments);
155
154
  report.warnings.push(`Did not copy ${file.name} because it is larger than 25MB.`);
156
155
  continue;
157
156
  }
158
157
  try {
159
158
  if (output.inline && isImage(file)) {
160
159
  const body = await fileBody(file);
161
- const type = file.contentType || 'image/png';
162
- replacePath(report, file.target, `data:${type};base64,${body.toString('base64')}`);
160
+ const type = (0, format_1.baseType)(file.contentType || 'image/png');
161
+ replacePath(attachments, `data:${type};base64,${body.toString('base64')}`);
163
162
  continue;
164
163
  }
165
164
  await writePending(outputDir, file);
@@ -179,4 +178,23 @@ async function writeReport(outputDir, report, files, uiDir, output = { inline: t
179
178
  await promises_1.default.writeFile(indexPath, renderHtml(json, documentAssets), 'utf8');
180
179
  return indexPath;
181
180
  }
181
+ async function writeReport(outputDir, report, files, uiDir, output = { inline: true, reportFileName: 'index.html' }) {
182
+ if (!/^[A-Za-z0-9._-]+\.html$/.test(output.reportFileName)) {
183
+ throw new Error('Reborn reportFileName must be a single .html file name.');
184
+ }
185
+ // Build before replacing the old report: attachments may live inside it, and
186
+ // missing assets should leave the last successful report available.
187
+ await promises_1.default.mkdir(node_path_1.default.dirname(outputDir), { recursive: true });
188
+ const staging = await promises_1.default.mkdtemp(node_path_1.default.join(node_path_1.default.dirname(outputDir), '.reborn-staging-'));
189
+ try {
190
+ await writeReportContents(staging, report, files, uiDir, output);
191
+ await (0, paths_1.prepareOutput)(outputDir);
192
+ await promises_1.default.rmdir(outputDir);
193
+ await promises_1.default.rename(staging, outputDir);
194
+ return node_path_1.default.join(outputDir, output.reportFileName);
195
+ }
196
+ finally {
197
+ await promises_1.default.rm(staging, { recursive: true, force: true });
198
+ }
199
+ }
182
200
  //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,7 @@ export type SourceTest = {
58
58
  }[];
59
59
  tags: string[];
60
60
  outcome(): 'skipped' | 'expected' | 'unexpected' | 'flaky';
61
+ expectedStatus?: Attempt['status'];
61
62
  results: SourceResult[];
62
63
  };
63
64
  export type BuildInput = {
package/dist/serialize.js CHANGED
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.buildReport = buildReport;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
+ const node_crypto_1 = require("node:crypto");
8
9
  const format_1 = require("./format");
9
10
  const paths_1 = require("./paths");
10
11
  const status_1 = require("./status");
@@ -67,13 +68,15 @@ function simplifyError(error, rootDir) {
67
68
  }
68
69
  return simplified;
69
70
  }
71
+ // Playwright records these around the steps a person would follow.
72
+ const PLAYWRIGHT_STEP = new Set(['pw:api', 'fixture', 'expect', 'test.attach']);
70
73
  function mapSteps(steps, rootDir, depth, detail) {
71
74
  if (!steps || depth > 12)
72
75
  return [];
73
76
  const mapped = [];
74
77
  for (const step of steps) {
75
78
  const kids = mapSteps(step.steps, rootDir, depth + 1, detail);
76
- const hide = detail === 'user' && (step.category === 'pw:api' || step.category === 'fixture');
79
+ const hide = detail === 'user' && PLAYWRIGHT_STEP.has(step.category);
77
80
  const quietHook = detail === 'user' && step.category === 'hook' && !step.error;
78
81
  if (hide || quietHook) {
79
82
  mapped.push(...kids);
@@ -102,18 +105,19 @@ function mapSteps(steps, rootDir, depth, detail) {
102
105
  function collectAttachments(result) {
103
106
  const found = [];
104
107
  const seen = new Set();
105
- const visit = (attachments) => {
108
+ const visit = (attachments, primary = false) => {
106
109
  for (const attachment of attachments || []) {
107
- const key = attachment.path
108
- ? `path:${attachment.path}`
109
- : `body:${attachment.name}:${attachment.contentType}:${attachment.body?.length || 0}:${found.length}`;
110
- if (seen.has(key))
110
+ const source = attachment.path || (attachment.body ? (0, node_crypto_1.createHash)('sha256').update(attachment.body).digest('hex') : 'empty');
111
+ const key = `${attachment.name}:${attachment.contentType}:${source}`;
112
+ // The reporter can receive cloned buffers on both the result and the
113
+ // step. Preserve deliberate repeats in the result, but omit step copies.
114
+ if (!primary && seen.has(key))
111
115
  continue;
112
116
  seen.add(key);
113
117
  found.push(attachment);
114
118
  }
115
119
  };
116
- visit(result.attachments);
120
+ visit(result.attachments, true);
117
121
  const visitSteps = (steps) => {
118
122
  for (const step of steps || []) {
119
123
  visit(step.attachments);
@@ -127,6 +131,8 @@ function buildReport(input) {
127
131
  const files = [];
128
132
  let fileIndex = 0;
129
133
  const seenIds = new Map();
134
+ const originalIds = new Set(input.tests.map((test) => test.id));
135
+ const usedIds = new Set();
130
136
  const sorted = [...input.tests].sort((a, b) => {
131
137
  const aStart = a.results[0]?.startTime ? a.results[0].startTime.getTime() : Number.POSITIVE_INFINITY;
132
138
  const bStart = b.results[0]?.startTime ? b.results[0].startTime.getTime() : Number.POSITIVE_INFINITY;
@@ -137,7 +143,10 @@ function buildReport(input) {
137
143
  const tests = sorted.map((test, order) => {
138
144
  const count = seenIds.get(test.id) || 0;
139
145
  seenIds.set(test.id, count + 1);
140
- const id = count === 0 ? test.id : `${test.id}-${count}`;
146
+ let id = count === 0 ? test.id : `${test.id}-${count}`;
147
+ while ((originalIds.has(id) && id !== test.id) || usedIds.has(id))
148
+ id += '-duplicate';
149
+ usedIds.add(id);
141
150
  const results = test.results || [];
142
151
  const last = results[results.length - 1];
143
152
  const rawStatus = last?.status || 'skipped';
@@ -151,6 +160,9 @@ function buildReport(input) {
151
160
  const attempts = results.map((result) => {
152
161
  const errors = (result.errors && result.errors.length > 0 ? result.errors : result.error ? [result.error] : [])
153
162
  .map((error) => simplifyError(error, input.rootDir));
163
+ if (result.status === 'passed' && test.expectedStatus === 'failed') {
164
+ errors.push({ message: 'Expected to fail, but passed.' });
165
+ }
154
166
  const attachments = collectAttachments(result).map((attachment) => {
155
167
  const parsed = (0, format_1.parseShotName)(attachment.name || 'file');
156
168
  const ext = (0, format_1.extensionFor)(attachment.contentType, attachment.path);