@e2e-dev/github 0.3.2 → 0.3.3

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/dist/.build.json CHANGED
@@ -1 +1 @@
1
- {"version":"0.3.2"}
1
+ {"version":"0.3.3"}
package/dist/merge.d.ts CHANGED
@@ -11,13 +11,19 @@ import type { Report } from 'e2e';
11
11
  /**
12
12
  * The rerun folded into the run it selected from. A result the rerun has
13
13
  * under the same id is folded with it; a test the rerun left out keeps what
14
- * the run before said. Results the rerun has no id for at all, the further
14
+ * the run before said, or what the rerun carries for it when an earlier run
15
+ * left it owed (`run.carried`), and so do the serial groups those results'
16
+ * attempts live on. Results the rerun has no id for at all, the further
15
17
  * repeats of a `--repeat-each` first pass a plain rerun ran once, fold into
16
18
  * the rerun's first result of that test, or stay as carried rows when the
17
19
  * rerun left the test out. A run before of another project leaves the rerun
18
20
  * as it is. The outcome is the rerun's unless a carried result failed, as a
19
- * test another filter kept out of the rerun can have: then the page is red,
20
- * since it lists a failure. The start is the run before's, so the footer's
21
- * duration spans both.
21
+ * test another filter kept out of the rerun can have, or the rerun carries
22
+ * a test it owed and never ran, a failure limit's skip among them, or a
23
+ * suite hook failure whose scope it did not run again (`run.carried`). Then
24
+ * the page is red, since the suite is not known to pass. A carried test the
25
+ * first pass interrupted reached no verdict: it leaves the outcome alone and
26
+ * the page reads interrupted, not green. The start is the run before's, so
27
+ * the footer's duration spans both.
22
28
  */
23
29
  export declare function foldLastRun(current: Report, lastRun: Report): Report;
package/dist/merge.js CHANGED
@@ -7,8 +7,8 @@
7
7
  * passed reads as flaky with both runs' attempts. Rendering only: nothing
8
8
  * here is written back to a report file.
9
9
  */
10
- /** Statuses that count as a failure of the run, the ones `--last-failed` runs again. */
11
- const FAILED_STATUSES = new Set(['failed', 'timed-out', 'interrupted']);
10
+ /** Statuses that count as a failure of the run. `--last-failed` also runs an interrupted test again, but that one reached no verdict. */
11
+ const FAILED_STATUSES = new Set(['failed', 'timed-out']);
12
12
  /**
13
13
  * A test per target and agent, whatever its `--repeat-each` run: the identity
14
14
  * `--last-failed` selects by, so a rerun without the flag runs once a test any
@@ -20,14 +20,16 @@ function testKey(result) {
20
20
  /**
21
21
  * The rerun's result with the run before's attempts in front of its own:
22
22
  * the same test's result there, and the further repeats the rerun has no
23
- * result of its own for. A pass after a failure there is flaky.
23
+ * result of its own for. A pass after a failure there is flaky; an
24
+ * interrupted rerun of a test that failed there keeps that failure.
24
25
  */
25
26
  function foldRerun(current, history) {
26
27
  if (history.length === 0)
27
28
  return current;
28
29
  const before = history.toSorted((a, b) => a.repeat - b.repeat);
29
30
  const attempts = [...before.flatMap((result) => result.attempts), ...current.attempts];
30
- const status = current.status === 'passed' && before.some((result) => FAILED_STATUSES.has(result.status)) ? 'flaky' : current.status;
31
+ const failure = before.findLast((result) => FAILED_STATUSES.has(result.status));
32
+ const status = failure === undefined ? current.status : current.status === 'passed' ? 'flaky' : current.status === 'interrupted' ? failure.status : current.status;
31
33
  return { ...current, status, attempts };
32
34
  }
33
35
  /**
@@ -41,18 +43,21 @@ function foldGroup(current, before) {
41
43
  const attempts = [...before.attempts, ...current.attempts].map((attempt, index) => ({ ...attempt, index }));
42
44
  return { ...current, attempts };
43
45
  }
44
- /** The counts the way the runner tallies them, over the folded results. */
46
+ /** The counts the way the runner tallies them, over the folded results: the status counts are over the selected ones. */
45
47
  function summarize(results, base) {
46
- const summary = { ...base, discovered: results.length, selected: 0, executed: 0, passed: 0, failed: 0, flaky: 0, skipped: 0 };
48
+ const summary = { ...base, discovered: results.length, selected: 0, executed: 0, passed: 0, failed: 0, interrupted: 0, flaky: 0, skipped: 0 };
47
49
  for (const result of results) {
48
- if (result.selected)
49
- summary.selected += 1;
50
50
  if (result.attempts.length > 0 || (result.serialGroupId !== undefined && result.status !== 'skipped'))
51
51
  summary.executed += 1;
52
+ if (!result.selected)
53
+ continue;
54
+ summary.selected += 1;
52
55
  if (result.status === 'passed')
53
56
  summary.passed += 1;
54
57
  else if (result.status === 'flaky')
55
58
  summary.flaky += 1;
59
+ else if (result.status === 'interrupted')
60
+ summary.interrupted += 1;
56
61
  else if (FAILED_STATUSES.has(result.status))
57
62
  summary.failed += 1;
58
63
  else
@@ -63,22 +68,32 @@ function summarize(results, base) {
63
68
  /**
64
69
  * The rerun folded into the run it selected from. A result the rerun has
65
70
  * under the same id is folded with it; a test the rerun left out keeps what
66
- * the run before said. Results the rerun has no id for at all, the further
71
+ * the run before said, or what the rerun carries for it when an earlier run
72
+ * left it owed (`run.carried`), and so do the serial groups those results'
73
+ * attempts live on. Results the rerun has no id for at all, the further
67
74
  * repeats of a `--repeat-each` first pass a plain rerun ran once, fold into
68
75
  * the rerun's first result of that test, or stay as carried rows when the
69
76
  * rerun left the test out. A run before of another project leaves the rerun
70
77
  * as it is. The outcome is the rerun's unless a carried result failed, as a
71
- * test another filter kept out of the rerun can have: then the page is red,
72
- * since it lists a failure. The start is the run before's, so the footer's
73
- * duration spans both.
78
+ * test another filter kept out of the rerun can have, or the rerun carries
79
+ * a test it owed and never ran, a failure limit's skip among them, or a
80
+ * suite hook failure whose scope it did not run again (`run.carried`). Then
81
+ * the page is red, since the suite is not known to pass. A carried test the
82
+ * first pass interrupted reached no verdict: it leaves the outcome alone and
83
+ * the page reads interrupted, not green. The start is the run before's, so
84
+ * the footer's duration spans both.
74
85
  */
75
86
  export function foldLastRun(current, lastRun) {
76
87
  if (lastRun.run.project.id !== current.run.project.id)
77
88
  return current;
89
+ const carried = current.run.carried;
90
+ const carriedById = new Map((carried?.results ?? []).map((result) => [result.id, result]));
78
91
  const currentIds = new Set(current.run.results.map((result) => result.id));
79
- const beforeById = new Map(lastRun.run.results.map((result) => [result.id, result]));
92
+ // The run before's own carried rows stand for the tests it left out, over their filtered rows.
93
+ const before = [...lastRun.run.results, ...(lastRun.run.carried?.results ?? [])];
94
+ const beforeById = new Map(before.map((result) => [result.id, result]));
80
95
  const leftovers = new Map();
81
- for (const result of lastRun.run.results) {
96
+ for (const result of beforeById.values()) {
82
97
  if (currentIds.has(result.id))
83
98
  continue;
84
99
  const key = testKey(result);
@@ -91,26 +106,31 @@ export function foldLastRun(current, lastRun) {
91
106
  }
92
107
  const results = [];
93
108
  for (const result of current.run.results) {
94
- const before = beforeById.get(result.id);
109
+ const previous = beforeById.get(result.id);
95
110
  if (!result.selected) {
96
- results.push(before ?? result);
111
+ results.push(carriedById.get(result.id) ?? previous ?? result);
97
112
  continue;
98
113
  }
99
114
  const key = testKey(result);
100
115
  const extra = firstOfKey.get(key) === result.id ? (leftovers.get(key) ?? []) : [];
101
116
  if (extra.length > 0)
102
117
  leftovers.delete(key);
103
- results.push(foldRerun(result, before === undefined ? extra : [before, ...extra]));
118
+ results.push(foldRerun(result, previous === undefined ? extra : [previous, ...extra]));
104
119
  }
105
120
  for (const extra of leftovers.values())
106
121
  results.push(...extra);
107
- const beforeGroups = new Map(lastRun.run.serialGroups.map((group) => [group.id, group]));
122
+ const beforeGroups = new Map([...lastRun.run.serialGroups, ...(lastRun.run.carried?.serialGroups ?? [])].map((group) => [group.id, group]));
108
123
  const currentGroupIds = new Set(current.run.serialGroups.map((group) => group.id));
124
+ const carriedGroups = (carried?.serialGroups ?? []).filter((group) => !currentGroupIds.has(group.id) && !beforeGroups.has(group.id));
109
125
  const serialGroups = [
110
- ...lastRun.run.serialGroups.filter((group) => !currentGroupIds.has(group.id)),
126
+ ...[...beforeGroups.values()].filter((group) => !currentGroupIds.has(group.id)),
127
+ ...carriedGroups,
111
128
  ...current.run.serialGroups.map((group) => foldGroup(group, beforeGroups.get(group.id))),
112
129
  ];
113
- const carriedFailure = results.some((result) => result.selected && FAILED_STATUSES.has(result.status));
130
+ const carriedErrors = carried?.errors ?? [];
131
+ const carriedFailure = carriedErrors.length > 0 ||
132
+ [...carriedById.values()].some((result) => result.status !== 'interrupted') ||
133
+ results.some((result) => result.selected && FAILED_STATUSES.has(result.status));
114
134
  return {
115
135
  ...current,
116
136
  run: {
@@ -120,6 +140,7 @@ export function foldLastRun(current, lastRun) {
120
140
  startedAt: lastRun.run.startedAt,
121
141
  serialGroups,
122
142
  results,
143
+ errors: [...current.run.errors, ...carriedErrors],
123
144
  summary: summarize(results, current.run.summary),
124
145
  },
125
146
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e2e-dev/github",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "GitHub reporter for e2e: one pull request comment per run, from GitHub Actions",
5
5
  "keywords": [
6
6
  "e2e",
@@ -46,7 +46,7 @@
46
46
  "e2e": ">=0.15.0 <1"
47
47
  },
48
48
  "devDependencies": {
49
- "e2e": "0.16.0",
49
+ "e2e": "0.17.0",
50
50
  "@types/node": "26.6.2",
51
51
  "typescript": "7.0.2",
52
52
  "vitest": "5.0.1"