@opice/harness 0.6.1 → 0.7.0
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/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/reporter.d.ts +21 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +34 -6
- package/dist/reporter.js.map +1 -1
- package/dist/scenario.d.ts +13 -0
- package/dist/scenario.d.ts.map +1 -1
- package/dist/scenario.js +71 -0
- package/dist/scenario.js.map +1 -1
- package/dist/tier.d.ts +44 -0
- package/dist/tier.d.ts.map +1 -0
- package/dist/tier.js +38 -0
- package/dist/tier.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +12 -1
- package/src/reporter.ts +56 -6
- package/src/scenario.ts +88 -0
- package/src/tier.ts +67 -0
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,10 @@ export { back, currentPath, currentUrl, forward, open, reload } from './navigati
|
|
|
4
4
|
export { getPage, getContext } from './context.js';
|
|
5
5
|
export { browserTest, DEFAULT_WALKTHROUGH_TIMEOUT_MS, invariant, step } from './scenario.js';
|
|
6
6
|
export type { BrowserTestMeta, StepContract } from './scenario.js';
|
|
7
|
+
export { DEFAULT_SCENARIO_TIER, DEFAULT_SELECTED_TIER, isTierSkipped, normalizeTier, parseSelectedTier, resolveSelectedTier, TIER_ORDER, } from './tier.js';
|
|
8
|
+
export type { SelectedTier, Tier } from './tier.js';
|
|
7
9
|
export { getReporter, setReporter, configureFromEnv } from './reporter.js';
|
|
8
|
-
export type { Reporter, ReporterConfig, StepEvent, ScenarioStart, ScenarioFinish } from './reporter.js';
|
|
10
|
+
export type { Reporter, ReporterConfig, StepEvent, ScenarioStart, ScenarioSkip, ScenarioFinish } from './reporter.js';
|
|
9
11
|
export { parseOpiceDsn } from './dsn.js';
|
|
10
12
|
export type { OpiceDsn } from './dsn.js';
|
|
11
13
|
export { command, call, runCommand, makeCtx, loadUserCommands, findUserCommandsFile, z } from './command.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,WAAW,EAAE,8BAA8B,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAC5F,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAElE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC1E,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,WAAW,EAAE,8BAA8B,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAC5F,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAElE,OAAO,EACN,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,GACV,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC1E,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAErH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAC5G,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC7D,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAI9C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAGzC,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { byLabel, byRole, byText } from './accessible.js';
|
|
|
3
3
|
export { back, currentPath, currentUrl, forward, open, reload } from './navigation.js';
|
|
4
4
|
export { getPage, getContext } from './context.js';
|
|
5
5
|
export { browserTest, DEFAULT_WALKTHROUGH_TIMEOUT_MS, invariant, step } from './scenario.js';
|
|
6
|
+
export { DEFAULT_SCENARIO_TIER, DEFAULT_SELECTED_TIER, isTierSkipped, normalizeTier, parseSelectedTier, resolveSelectedTier, TIER_ORDER, } from './tier.js';
|
|
6
7
|
export { getReporter, setReporter, configureFromEnv } from './reporter.js';
|
|
7
8
|
export { parseOpiceDsn } from './dsn.js';
|
|
8
9
|
export { command, call, runCommand, makeCtx, loadUserCommands, findUserCommandsFile, z } from './command.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,WAAW,EAAE,8BAA8B,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAG5F,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAG1E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAG5G,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG7D,iFAAiF;AACjF,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,WAAW,EAAE,8BAA8B,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAG5F,OAAO,EACN,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,GACV,MAAM,WAAW,CAAA;AAGlB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAG1E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAG5G,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG7D,iFAAiF;AACjF,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/reporter.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* The CLI handles end-of-run finalization: the reporter writes a
|
|
9
9
|
* handoff file under $TMPDIR with the runId and credentials, the
|
|
10
10
|
* `opice test` wrapper picks it up after `bun test` exits and POSTs
|
|
11
|
-
* /api/v1
|
|
11
|
+
* /api/v1/<slug>/runs/<id>/finish so the dashboard sees the run as completed.
|
|
12
12
|
*
|
|
13
13
|
* When env vars aren't configured, the reporter falls back to a no-op so
|
|
14
14
|
* harness behavior matches the bindx prototype.
|
|
@@ -21,6 +21,12 @@ export interface ReporterConfig {
|
|
|
21
21
|
commit?: string;
|
|
22
22
|
/** 'ci' for runs from automation, 'local' for opted-in dev runs. */
|
|
23
23
|
source?: 'ci' | 'local';
|
|
24
|
+
/**
|
|
25
|
+
* The tier this run SELECTED (from `OPICE_TIER`) — recorded on the run so the
|
|
26
|
+
* dashboard can explain why scenarios were skipped. Omitted when no tier
|
|
27
|
+
* filter was set (the run ran everything).
|
|
28
|
+
*/
|
|
29
|
+
tier?: string;
|
|
24
30
|
}
|
|
25
31
|
export interface StepEvent {
|
|
26
32
|
scenarioId: string;
|
|
@@ -72,6 +78,16 @@ export interface ScenarioStart {
|
|
|
72
78
|
seeds?: string[];
|
|
73
79
|
/** Identities / roles the scenario acts as. */
|
|
74
80
|
roles?: string[];
|
|
81
|
+
/** Declared tier (critical | standard | extended) — when it runs. */
|
|
82
|
+
tier?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A scenario the tier filter excluded from this run — registered for the record
|
|
86
|
+
* but never executed. Reported `skipped`, carrying a `reason` (which tier it
|
|
87
|
+
* declared vs the selected one) so the dashboard can explain the absence.
|
|
88
|
+
*/
|
|
89
|
+
export interface ScenarioSkip extends ScenarioStart {
|
|
90
|
+
reason?: string;
|
|
75
91
|
}
|
|
76
92
|
export interface ScenarioFinish {
|
|
77
93
|
scenarioId: string;
|
|
@@ -85,6 +101,8 @@ export interface ScenarioFinish {
|
|
|
85
101
|
}
|
|
86
102
|
export interface Reporter {
|
|
87
103
|
startScenario(input: ScenarioStart): Promise<string>;
|
|
104
|
+
/** Record a scenario the tier filter skipped (created already-finished as `skipped`). */
|
|
105
|
+
skipScenario(input: ScenarioSkip): Promise<void>;
|
|
88
106
|
recordStep(event: StepEvent): Promise<void>;
|
|
89
107
|
finishScenario(input: ScenarioFinish): Promise<void>;
|
|
90
108
|
flush(): Promise<void>;
|
|
@@ -92,6 +110,8 @@ export interface Reporter {
|
|
|
92
110
|
export declare const HANDOFF_DIR: string;
|
|
93
111
|
export interface RunHandoff {
|
|
94
112
|
endpoint: string;
|
|
113
|
+
/** Project slug — the CLI builds /api/v1/<project>/runs/<id>/finish from it. */
|
|
114
|
+
project: string;
|
|
95
115
|
apiKey: string;
|
|
96
116
|
runId: string;
|
|
97
117
|
}
|
package/dist/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,IAAI,GAAG,OAAO,CAAA;IACvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,SAAS;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAA;IAC/D,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,aAAa;IAClD,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACxB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACpD,yFAAyF;IACzF,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAYD,eAAO,MAAM,WAAW,QAAwC,CAAA;AAMhE,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACb;AA8LD,wBAAgB,WAAW,IAAI,QAAQ,CAEtC;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,QAAQ,CAiC/E"}
|
package/dist/reporter.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* The CLI handles end-of-run finalization: the reporter writes a
|
|
9
9
|
* handoff file under $TMPDIR with the runId and credentials, the
|
|
10
10
|
* `opice test` wrapper picks it up after `bun test` exits and POSTs
|
|
11
|
-
* /api/v1
|
|
11
|
+
* /api/v1/<slug>/runs/<id>/finish so the dashboard sees the run as completed.
|
|
12
12
|
*
|
|
13
13
|
* When env vars aren't configured, the reporter falls back to a no-op so
|
|
14
14
|
* harness behavior matches the bindx prototype.
|
|
@@ -18,6 +18,7 @@ import { mkdirSync, writeFileSync } from 'node:fs';
|
|
|
18
18
|
import { tmpdir } from 'node:os';
|
|
19
19
|
import path from 'node:path';
|
|
20
20
|
import { parseOpiceDsn } from './dsn.js';
|
|
21
|
+
import { resolveSelectedTier } from './tier.js';
|
|
21
22
|
/** Per-request cap, so a hung connection can't stall a scenario's afterAll. */
|
|
22
23
|
const REQUEST_TIMEOUT_MS = 10_000;
|
|
23
24
|
/** Total cap on `flush()` waiting for pending step uploads (afterAll-bounded). */
|
|
@@ -26,6 +27,7 @@ class NoopReporter {
|
|
|
26
27
|
async startScenario(input) {
|
|
27
28
|
return `noop-${input.name}-${Date.now()}`;
|
|
28
29
|
}
|
|
30
|
+
async skipScenario(_input) { }
|
|
29
31
|
async recordStep(_event) { }
|
|
30
32
|
async finishScenario(_input) { }
|
|
31
33
|
async flush() { }
|
|
@@ -49,17 +51,23 @@ class HttpReporter {
|
|
|
49
51
|
return this.runIdPromise;
|
|
50
52
|
}
|
|
51
53
|
async startRun() {
|
|
52
|
-
const response = await this.fetch('POST',
|
|
54
|
+
const response = await this.fetch('POST', `/api/v1/${this.config.projectId}/runs`, {
|
|
53
55
|
branch: this.config.branch,
|
|
54
56
|
commit: this.config.commit,
|
|
55
57
|
source: this.config.source,
|
|
58
|
+
tier: this.config.tier,
|
|
56
59
|
});
|
|
57
60
|
const runId = response['runId'];
|
|
58
61
|
// Synchronous write so the CLI can pick this up even if the test
|
|
59
62
|
// process exits abruptly (process.on('exit') runs sync).
|
|
60
63
|
try {
|
|
61
64
|
mkdirSync(HANDOFF_DIR, { recursive: true });
|
|
62
|
-
const handoff = {
|
|
65
|
+
const handoff = {
|
|
66
|
+
endpoint: this.config.endpoint,
|
|
67
|
+
project: this.config.projectId,
|
|
68
|
+
apiKey: this.config.apiKey,
|
|
69
|
+
runId,
|
|
70
|
+
};
|
|
63
71
|
writeFileSync(handoffPath(), JSON.stringify(handoff), 'utf-8');
|
|
64
72
|
}
|
|
65
73
|
catch {
|
|
@@ -69,16 +77,33 @@ class HttpReporter {
|
|
|
69
77
|
}
|
|
70
78
|
async startScenario(input) {
|
|
71
79
|
const runId = await this.ensureRun();
|
|
72
|
-
const response = await this.fetch('POST', `/api/v1/runs/${runId}/scenarios`, {
|
|
80
|
+
const response = await this.fetch('POST', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios`, {
|
|
73
81
|
name: input.name,
|
|
74
82
|
hash: input.hash,
|
|
75
83
|
testFile: input.testFile,
|
|
76
84
|
feature: input.feature,
|
|
77
85
|
seeds: input.seeds,
|
|
78
86
|
roles: input.roles,
|
|
87
|
+
tier: input.tier,
|
|
79
88
|
});
|
|
80
89
|
return response['scenarioId'];
|
|
81
90
|
}
|
|
91
|
+
async skipScenario(input) {
|
|
92
|
+
const runId = await this.ensureRun();
|
|
93
|
+
// A skipped scenario is created already-finished on the platform — no
|
|
94
|
+
// steps follow, so we don't keep the returned id.
|
|
95
|
+
await this.fetch('POST', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios`, {
|
|
96
|
+
name: input.name,
|
|
97
|
+
hash: input.hash,
|
|
98
|
+
testFile: input.testFile,
|
|
99
|
+
feature: input.feature,
|
|
100
|
+
seeds: input.seeds,
|
|
101
|
+
roles: input.roles,
|
|
102
|
+
tier: input.tier,
|
|
103
|
+
skipped: true,
|
|
104
|
+
reason: input.reason,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
82
107
|
recordStep(event) {
|
|
83
108
|
// Track synchronously so flush() awaits the entire pipeline (including
|
|
84
109
|
// encodeScreenshot's fs.readFile and the upload), not just whatever
|
|
@@ -92,7 +117,7 @@ class HttpReporter {
|
|
|
92
117
|
const screenshot = event.screenshotPath
|
|
93
118
|
? await this.encodeScreenshot(event.screenshotPath)
|
|
94
119
|
: undefined;
|
|
95
|
-
await this.fetch('POST', `/api/v1/runs/${runId}/scenarios/${event.scenarioId}/steps`, {
|
|
120
|
+
await this.fetch('POST', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios/${event.scenarioId}/steps`, {
|
|
96
121
|
attempt: event.attempt,
|
|
97
122
|
sequence: event.sequence,
|
|
98
123
|
kind: event.kind,
|
|
@@ -110,7 +135,7 @@ class HttpReporter {
|
|
|
110
135
|
const runId = await this.ensureRun();
|
|
111
136
|
// Awaited inline so the scenario status is committed before the
|
|
112
137
|
// bun:test afterAll returns.
|
|
113
|
-
await this.fetch('PATCH', `/api/v1/runs/${runId}/scenarios/${input.scenarioId}`, {
|
|
138
|
+
await this.fetch('PATCH', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios/${input.scenarioId}`, {
|
|
114
139
|
status: input.status,
|
|
115
140
|
durationMs: input.durationMs,
|
|
116
141
|
attempts: input.attempts,
|
|
@@ -222,6 +247,9 @@ export function configureFromEnv(env = process.env) {
|
|
|
222
247
|
branch: env['OPICE_BRANCH'] ?? env['GITHUB_REF_NAME'],
|
|
223
248
|
commit: env['OPICE_COMMIT'] ?? env['GITHUB_SHA'],
|
|
224
249
|
source: isCI ? 'ci' : 'local',
|
|
250
|
+
// Record the selected tier only when one was explicitly requested — a run
|
|
251
|
+
// with no OPICE_TIER ran everything and carries no tier filter.
|
|
252
|
+
tier: env['OPICE_TIER'] ? resolveSelectedTier(env) : undefined,
|
|
225
253
|
});
|
|
226
254
|
setReporter(reporter);
|
|
227
255
|
return reporter;
|
package/dist/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|
package/dist/scenario.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Tier } from './tier.js';
|
|
1
2
|
/**
|
|
2
3
|
* Scenario metadata — the **first** argument to `browserTest`.
|
|
3
4
|
*
|
|
@@ -23,6 +24,18 @@ export interface BrowserTestMeta {
|
|
|
23
24
|
hash?: string;
|
|
24
25
|
/** Feature / requirement id this scenario covers (e.g. `'F-SML-03a'`). */
|
|
25
26
|
feature?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Test tier — *when* this scenario runs (critical < standard < extended).
|
|
29
|
+
* A run selects a tier via `OPICE_TIER` / `opice test --tier`; selection is a
|
|
30
|
+
* threshold (running `standard` runs critical + standard). A scenario above
|
|
31
|
+
* the selected tier is **skipped**: reported as `skipped` (so it still shows
|
|
32
|
+
* on the dashboard) but never opens a browser. Defaults to `standard`.
|
|
33
|
+
*
|
|
34
|
+
* critical — the must-pass core, every push
|
|
35
|
+
* standard — the normal suite (default), PRs / merges
|
|
36
|
+
* extended — slow / edge / expensive, nightly or on demand
|
|
37
|
+
*/
|
|
38
|
+
tier?: Tier;
|
|
26
39
|
/**
|
|
27
40
|
* Seeds that must be loaded for this scenario to run — machine-checkable
|
|
28
41
|
* preconditions, not prose. e.g. `['initial-data', 'crm-master-data']`.
|
package/dist/scenario.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../src/scenario.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../src/scenario.ts"],"names":[],"mappings":"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"}
|
package/dist/scenario.js
CHANGED
|
@@ -4,6 +4,7 @@ import { closePage, getContext, launchPage } from './context.js';
|
|
|
4
4
|
import { screenshot } from './element.js';
|
|
5
5
|
import { getReporter } from './reporter.js';
|
|
6
6
|
import { loadUserSetup } from './setup.js';
|
|
7
|
+
import { isTierSkipped, normalizeTier, parseSelectedTier, TIER_ORDER } from './tier.js';
|
|
7
8
|
/**
|
|
8
9
|
* `bun:test` is resolved lazily, at the moment `browserTest` registers a
|
|
9
10
|
* scenario — never at module load. That keeps `@opice/harness` importable
|
|
@@ -46,6 +47,36 @@ function captureTestFile() {
|
|
|
46
47
|
}
|
|
47
48
|
return undefined;
|
|
48
49
|
}
|
|
50
|
+
// The tier this run selected (OPICE_TIER), resolved + cached once. An
|
|
51
|
+
// unrecognized value warns once and falls back to running everything.
|
|
52
|
+
let cachedSelectedTier;
|
|
53
|
+
function getSelectedTier() {
|
|
54
|
+
if (cachedSelectedTier === undefined) {
|
|
55
|
+
const parsed = parseSelectedTier();
|
|
56
|
+
if (!parsed.recognized) {
|
|
57
|
+
console.warn(`[opice] unknown OPICE_TIER="${process.env['OPICE_TIER']}" — running all tiers `
|
|
58
|
+
+ `(use one of: ${TIER_ORDER.join(', ')}).`);
|
|
59
|
+
}
|
|
60
|
+
cachedSelectedTier = parsed.tier;
|
|
61
|
+
}
|
|
62
|
+
return cachedSelectedTier;
|
|
63
|
+
}
|
|
64
|
+
// Names of scenarios skipped by the tier filter, summarized once at process
|
|
65
|
+
// exit so a tiered run prints "N skipped" instead of a line per scenario.
|
|
66
|
+
const skippedScenarioNames = [];
|
|
67
|
+
let skipSummaryHooked = false;
|
|
68
|
+
function noteSkipped(name) {
|
|
69
|
+
skippedScenarioNames.push(name);
|
|
70
|
+
if (skipSummaryHooked)
|
|
71
|
+
return;
|
|
72
|
+
skipSummaryHooked = true;
|
|
73
|
+
process.on('exit', () => {
|
|
74
|
+
if (skippedScenarioNames.length === 0)
|
|
75
|
+
return;
|
|
76
|
+
console.warn(`[opice] ${skippedScenarioNames.length} scenario(s) skipped — above the selected `
|
|
77
|
+
+ `tier '${getSelectedTier()}' (OPICE_TIER).`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
49
80
|
let currentScenarioId = null;
|
|
50
81
|
let currentScenarioStart = 0;
|
|
51
82
|
let currentScenarioFailures = 0;
|
|
@@ -100,6 +131,13 @@ export function browserTest(meta, fn) {
|
|
|
100
131
|
// An async fn is the walkthrough body (browserTest owns its test()); a sync
|
|
101
132
|
// fn is the legacy registrar (it registers its own test()/hooks).
|
|
102
133
|
const isBody = fn.constructor.name === 'AsyncFunction';
|
|
134
|
+
// Tier gate: a scenario above the selected tier is registered but not run —
|
|
135
|
+
// reported `skipped` so the dashboard shows the full inventory.
|
|
136
|
+
const scenarioTier = normalizeTier(meta.tier);
|
|
137
|
+
if (isTierSkipped(scenarioTier, getSelectedTier())) {
|
|
138
|
+
registerSkipped(meta, scenarioTier, testFile, reporter);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
103
141
|
describe(meta.name, () => {
|
|
104
142
|
beforeAll(async () => {
|
|
105
143
|
currentScenarioStart = Date.now();
|
|
@@ -115,6 +153,7 @@ export function browserTest(meta, fn) {
|
|
|
115
153
|
feature: meta.feature,
|
|
116
154
|
seeds: meta.seeds,
|
|
117
155
|
roles: meta.roles,
|
|
156
|
+
tier: scenarioTier,
|
|
118
157
|
});
|
|
119
158
|
}
|
|
120
159
|
catch {
|
|
@@ -225,6 +264,38 @@ export function browserTest(meta, fn) {
|
|
|
225
264
|
}
|
|
226
265
|
});
|
|
227
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Register a scenario the tier filter excluded. It's reported to the platform as
|
|
269
|
+
* `skipped` (so the dashboard shows it alongside what ran) but never opens a
|
|
270
|
+
* browser. The report runs in a real — instant, browser-free — `test`, not a
|
|
271
|
+
* `test.skip`: bun won't run a describe's hooks if every test in it is skipped,
|
|
272
|
+
* so a skip body is the only place left to POST from. With reporting off (local
|
|
273
|
+
* authoring), the body is a no-op against the NoopReporter.
|
|
274
|
+
*/
|
|
275
|
+
function registerSkipped(meta, tier, testFile, reporter) {
|
|
276
|
+
noteSkipped(meta.name);
|
|
277
|
+
const { describe, test } = bunTest();
|
|
278
|
+
const reason = `tier '${tier}' above the selected tier '${getSelectedTier()}'`;
|
|
279
|
+
describe(meta.name, () => {
|
|
280
|
+
test('skipped (tier)', async () => {
|
|
281
|
+
try {
|
|
282
|
+
await reporter.skipScenario({
|
|
283
|
+
name: meta.name,
|
|
284
|
+
hash: meta.hash,
|
|
285
|
+
testFile,
|
|
286
|
+
feature: meta.feature,
|
|
287
|
+
seeds: meta.seeds,
|
|
288
|
+
roles: meta.roles,
|
|
289
|
+
tier,
|
|
290
|
+
reason,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
// Best-effort: reporting a skip must never fail the run.
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
}
|
|
228
299
|
/**
|
|
229
300
|
* Open a fresh isolated browser context + page for `meta` and navigate to its
|
|
230
301
|
* scenario URL. `launchPage()` closes any previous context first, so calling
|
package/dist/scenario.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario.js","sourceRoot":"","sources":["../src/scenario.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scenario.js","sourceRoot":"","sources":["../src/scenario.ts"],"names":[],"mappings":"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"}
|
package/dist/tier.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test tiers — an ordered hierarchy for *when* a scenario runs.
|
|
3
|
+
*
|
|
4
|
+
* A scenario declares its tier in `browserTest` meta (default `standard`); a run
|
|
5
|
+
* selects a tier via `OPICE_TIER` (the `opice test --tier` flag). Selection is a
|
|
6
|
+
* THRESHOLD: running a tier runs every scenario AT OR BELOW it — the standard
|
|
7
|
+
* `smoke ⊂ regression ⊂ full` model. Scenarios above the selected tier are
|
|
8
|
+
* *skipped*: still registered and reported as `skipped` (so the dashboard shows
|
|
9
|
+
* the full inventory, not just what ran), but they never open a browser.
|
|
10
|
+
*
|
|
11
|
+
* critical — the must-pass core. Run on every push.
|
|
12
|
+
* standard — the normal suite (the default for an untagged scenario). PRs / merges.
|
|
13
|
+
* extended — slow / edge / expensive. Run nightly or on demand.
|
|
14
|
+
*
|
|
15
|
+
* OPICE_TIER=critical → critical only
|
|
16
|
+
* OPICE_TIER=standard → critical + standard
|
|
17
|
+
* OPICE_TIER=extended → everything (also the default when OPICE_TIER is unset)
|
|
18
|
+
*/
|
|
19
|
+
export type Tier = 'critical' | 'standard' | 'extended';
|
|
20
|
+
/** Tiers low → high. A scenario's index is its level; it runs when level <= selected level. */
|
|
21
|
+
export declare const TIER_ORDER: readonly Tier[];
|
|
22
|
+
/** A scenario with no declared tier sits in the middle `standard` tier. */
|
|
23
|
+
export declare const DEFAULT_SCENARIO_TIER: Tier;
|
|
24
|
+
/** With no `OPICE_TIER` set, run everything — select the widest tier. */
|
|
25
|
+
export declare const DEFAULT_SELECTED_TIER: Tier;
|
|
26
|
+
/** Normalize a scenario's declared tier, defaulting (and tolerating junk) to `standard`. */
|
|
27
|
+
export declare function normalizeTier(tier: string | undefined): Tier;
|
|
28
|
+
export interface SelectedTier {
|
|
29
|
+
tier: Tier;
|
|
30
|
+
/** false when `OPICE_TIER` held an unrecognized value (the caller may warn). */
|
|
31
|
+
recognized: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The tier selected for this run, parsed from `OPICE_TIER`. Unset → run
|
|
35
|
+
* everything. `all`/`full` are friendly aliases for the widest tier. An
|
|
36
|
+
* unrecognized value resolves to "run everything" (`recognized: false`) rather
|
|
37
|
+
* than silently dropping tests — better to over-run than to skip on a typo.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseSelectedTier(env?: NodeJS.ProcessEnv): SelectedTier;
|
|
40
|
+
/** Convenience: the resolved selected tier, ignoring whether the value was recognized. */
|
|
41
|
+
export declare function resolveSelectedTier(env?: NodeJS.ProcessEnv): Tier;
|
|
42
|
+
/** A scenario is skipped when its tier sits ABOVE the selected one. */
|
|
43
|
+
export declare function isTierSkipped(scenarioTier: Tier, selectedTier: Tier): boolean;
|
|
44
|
+
//# sourceMappingURL=tier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tier.d.ts","sourceRoot":"","sources":["../src/tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAA;AAEvD,+FAA+F;AAC/F,eAAO,MAAM,UAAU,EAAE,SAAS,IAAI,EAAyC,CAAA;AAE/E,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,EAAE,IAAiB,CAAA;AAErD,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,EAAE,IAAiB,CAAA;AAMrD,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE5D;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,IAAI,CAAA;IACV,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAA;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAMpF;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,IAAI,CAE9E;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,GAAG,OAAO,CAE7E"}
|
package/dist/tier.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Tiers low → high. A scenario's index is its level; it runs when level <= selected level. */
|
|
2
|
+
export const TIER_ORDER = ['critical', 'standard', 'extended'];
|
|
3
|
+
/** A scenario with no declared tier sits in the middle `standard` tier. */
|
|
4
|
+
export const DEFAULT_SCENARIO_TIER = 'standard';
|
|
5
|
+
/** With no `OPICE_TIER` set, run everything — select the widest tier. */
|
|
6
|
+
export const DEFAULT_SELECTED_TIER = 'extended';
|
|
7
|
+
function isTier(value) {
|
|
8
|
+
return value === 'critical' || value === 'standard' || value === 'extended';
|
|
9
|
+
}
|
|
10
|
+
/** Normalize a scenario's declared tier, defaulting (and tolerating junk) to `standard`. */
|
|
11
|
+
export function normalizeTier(tier) {
|
|
12
|
+
return isTier(tier) ? tier : DEFAULT_SCENARIO_TIER;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The tier selected for this run, parsed from `OPICE_TIER`. Unset → run
|
|
16
|
+
* everything. `all`/`full` are friendly aliases for the widest tier. An
|
|
17
|
+
* unrecognized value resolves to "run everything" (`recognized: false`) rather
|
|
18
|
+
* than silently dropping tests — better to over-run than to skip on a typo.
|
|
19
|
+
*/
|
|
20
|
+
export function parseSelectedTier(env = process.env) {
|
|
21
|
+
const raw = env['OPICE_TIER']?.trim().toLowerCase();
|
|
22
|
+
if (!raw)
|
|
23
|
+
return { tier: DEFAULT_SELECTED_TIER, recognized: true };
|
|
24
|
+
if (isTier(raw))
|
|
25
|
+
return { tier: raw, recognized: true };
|
|
26
|
+
if (raw === 'all' || raw === 'full')
|
|
27
|
+
return { tier: 'extended', recognized: true };
|
|
28
|
+
return { tier: DEFAULT_SELECTED_TIER, recognized: false };
|
|
29
|
+
}
|
|
30
|
+
/** Convenience: the resolved selected tier, ignoring whether the value was recognized. */
|
|
31
|
+
export function resolveSelectedTier(env = process.env) {
|
|
32
|
+
return parseSelectedTier(env).tier;
|
|
33
|
+
}
|
|
34
|
+
/** A scenario is skipped when its tier sits ABOVE the selected one. */
|
|
35
|
+
export function isTierSkipped(scenarioTier, selectedTier) {
|
|
36
|
+
return TIER_ORDER.indexOf(scenarioTier) > TIER_ORDER.indexOf(selectedTier);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=tier.js.map
|
package/dist/tier.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tier.js","sourceRoot":"","sources":["../src/tier.ts"],"names":[],"mappings":"AAoBA,+FAA+F;AAC/F,MAAM,CAAC,MAAM,UAAU,GAAoB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAA;AAE/E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAS,UAAU,CAAA;AAErD,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAS,UAAU,CAAA;AAErD,SAAS,MAAM,CAAC,KAAyB;IACxC,OAAO,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,CAAA;AAC5E,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,aAAa,CAAC,IAAwB;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAA;AACnD,CAAC;AAQD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACnD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA;IAClE,IAAI,MAAM,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA;IACvD,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA;IAClF,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,UAAU,EAAE,KAAK,EAAE,CAAA;AAC1D,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACvE,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AACnC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,YAAkB,EAAE,YAAkB;IACnE,OAAO,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;AAC3E,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -9,8 +9,19 @@ export { getPage, getContext } from './context.js'
|
|
|
9
9
|
export { browserTest, DEFAULT_WALKTHROUGH_TIMEOUT_MS, invariant, step } from './scenario.js'
|
|
10
10
|
export type { BrowserTestMeta, StepContract } from './scenario.js'
|
|
11
11
|
|
|
12
|
+
export {
|
|
13
|
+
DEFAULT_SCENARIO_TIER,
|
|
14
|
+
DEFAULT_SELECTED_TIER,
|
|
15
|
+
isTierSkipped,
|
|
16
|
+
normalizeTier,
|
|
17
|
+
parseSelectedTier,
|
|
18
|
+
resolveSelectedTier,
|
|
19
|
+
TIER_ORDER,
|
|
20
|
+
} from './tier.js'
|
|
21
|
+
export type { SelectedTier, Tier } from './tier.js'
|
|
22
|
+
|
|
12
23
|
export { getReporter, setReporter, configureFromEnv } from './reporter.js'
|
|
13
|
-
export type { Reporter, ReporterConfig, StepEvent, ScenarioStart, ScenarioFinish } from './reporter.js'
|
|
24
|
+
export type { Reporter, ReporterConfig, StepEvent, ScenarioStart, ScenarioSkip, ScenarioFinish } from './reporter.js'
|
|
14
25
|
|
|
15
26
|
export { parseOpiceDsn } from './dsn.js'
|
|
16
27
|
export type { OpiceDsn } from './dsn.js'
|
package/src/reporter.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* The CLI handles end-of-run finalization: the reporter writes a
|
|
9
9
|
* handoff file under $TMPDIR with the runId and credentials, the
|
|
10
10
|
* `opice test` wrapper picks it up after `bun test` exits and POSTs
|
|
11
|
-
* /api/v1
|
|
11
|
+
* /api/v1/<slug>/runs/<id>/finish so the dashboard sees the run as completed.
|
|
12
12
|
*
|
|
13
13
|
* When env vars aren't configured, the reporter falls back to a no-op so
|
|
14
14
|
* harness behavior matches the bindx prototype.
|
|
@@ -19,6 +19,7 @@ import { mkdirSync, writeFileSync } from 'node:fs'
|
|
|
19
19
|
import { tmpdir } from 'node:os'
|
|
20
20
|
import path from 'node:path'
|
|
21
21
|
import { parseOpiceDsn } from './dsn.js'
|
|
22
|
+
import { resolveSelectedTier } from './tier.js'
|
|
22
23
|
|
|
23
24
|
/** Per-request cap, so a hung connection can't stall a scenario's afterAll. */
|
|
24
25
|
const REQUEST_TIMEOUT_MS = 10_000
|
|
@@ -33,6 +34,12 @@ export interface ReporterConfig {
|
|
|
33
34
|
commit?: string
|
|
34
35
|
/** 'ci' for runs from automation, 'local' for opted-in dev runs. */
|
|
35
36
|
source?: 'ci' | 'local'
|
|
37
|
+
/**
|
|
38
|
+
* The tier this run SELECTED (from `OPICE_TIER`) — recorded on the run so the
|
|
39
|
+
* dashboard can explain why scenarios were skipped. Omitted when no tier
|
|
40
|
+
* filter was set (the run ran everything).
|
|
41
|
+
*/
|
|
42
|
+
tier?: string
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
export interface StepEvent {
|
|
@@ -86,6 +93,17 @@ export interface ScenarioStart {
|
|
|
86
93
|
seeds?: string[]
|
|
87
94
|
/** Identities / roles the scenario acts as. */
|
|
88
95
|
roles?: string[]
|
|
96
|
+
/** Declared tier (critical | standard | extended) — when it runs. */
|
|
97
|
+
tier?: string
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A scenario the tier filter excluded from this run — registered for the record
|
|
102
|
+
* but never executed. Reported `skipped`, carrying a `reason` (which tier it
|
|
103
|
+
* declared vs the selected one) so the dashboard can explain the absence.
|
|
104
|
+
*/
|
|
105
|
+
export interface ScenarioSkip extends ScenarioStart {
|
|
106
|
+
reason?: string
|
|
89
107
|
}
|
|
90
108
|
|
|
91
109
|
export interface ScenarioFinish {
|
|
@@ -101,6 +119,8 @@ export interface ScenarioFinish {
|
|
|
101
119
|
|
|
102
120
|
export interface Reporter {
|
|
103
121
|
startScenario(input: ScenarioStart): Promise<string>
|
|
122
|
+
/** Record a scenario the tier filter skipped (created already-finished as `skipped`). */
|
|
123
|
+
skipScenario(input: ScenarioSkip): Promise<void>
|
|
104
124
|
recordStep(event: StepEvent): Promise<void>
|
|
105
125
|
finishScenario(input: ScenarioFinish): Promise<void>
|
|
106
126
|
flush(): Promise<void>
|
|
@@ -110,6 +130,7 @@ class NoopReporter implements Reporter {
|
|
|
110
130
|
async startScenario(input: ScenarioStart): Promise<string> {
|
|
111
131
|
return `noop-${input.name}-${Date.now()}`
|
|
112
132
|
}
|
|
133
|
+
async skipScenario(_input: ScenarioSkip): Promise<void> {}
|
|
113
134
|
async recordStep(_event: StepEvent): Promise<void> {}
|
|
114
135
|
async finishScenario(_input: ScenarioFinish): Promise<void> {}
|
|
115
136
|
async flush(): Promise<void> {}
|
|
@@ -123,6 +144,8 @@ function handoffPath(pid = process.pid): string {
|
|
|
123
144
|
|
|
124
145
|
export interface RunHandoff {
|
|
125
146
|
endpoint: string
|
|
147
|
+
/** Project slug — the CLI builds /api/v1/<project>/runs/<id>/finish from it. */
|
|
148
|
+
project: string
|
|
126
149
|
apiKey: string
|
|
127
150
|
runId: string
|
|
128
151
|
}
|
|
@@ -142,17 +165,23 @@ class HttpReporter implements Reporter {
|
|
|
142
165
|
}
|
|
143
166
|
|
|
144
167
|
private async startRun(): Promise<string> {
|
|
145
|
-
const response = await this.fetch('POST',
|
|
168
|
+
const response = await this.fetch('POST', `/api/v1/${this.config.projectId}/runs`, {
|
|
146
169
|
branch: this.config.branch,
|
|
147
170
|
commit: this.config.commit,
|
|
148
171
|
source: this.config.source,
|
|
172
|
+
tier: this.config.tier,
|
|
149
173
|
})
|
|
150
174
|
const runId = response['runId'] as string
|
|
151
175
|
// Synchronous write so the CLI can pick this up even if the test
|
|
152
176
|
// process exits abruptly (process.on('exit') runs sync).
|
|
153
177
|
try {
|
|
154
178
|
mkdirSync(HANDOFF_DIR, { recursive: true })
|
|
155
|
-
const handoff: RunHandoff = {
|
|
179
|
+
const handoff: RunHandoff = {
|
|
180
|
+
endpoint: this.config.endpoint,
|
|
181
|
+
project: this.config.projectId,
|
|
182
|
+
apiKey: this.config.apiKey,
|
|
183
|
+
runId,
|
|
184
|
+
}
|
|
156
185
|
writeFileSync(handoffPath(), JSON.stringify(handoff), 'utf-8')
|
|
157
186
|
} catch {
|
|
158
187
|
// best-effort
|
|
@@ -162,17 +191,35 @@ class HttpReporter implements Reporter {
|
|
|
162
191
|
|
|
163
192
|
async startScenario(input: ScenarioStart): Promise<string> {
|
|
164
193
|
const runId = await this.ensureRun()
|
|
165
|
-
const response = await this.fetch('POST', `/api/v1/runs/${runId}/scenarios`, {
|
|
194
|
+
const response = await this.fetch('POST', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios`, {
|
|
166
195
|
name: input.name,
|
|
167
196
|
hash: input.hash,
|
|
168
197
|
testFile: input.testFile,
|
|
169
198
|
feature: input.feature,
|
|
170
199
|
seeds: input.seeds,
|
|
171
200
|
roles: input.roles,
|
|
201
|
+
tier: input.tier,
|
|
172
202
|
})
|
|
173
203
|
return response['scenarioId'] as string
|
|
174
204
|
}
|
|
175
205
|
|
|
206
|
+
async skipScenario(input: ScenarioSkip): Promise<void> {
|
|
207
|
+
const runId = await this.ensureRun()
|
|
208
|
+
// A skipped scenario is created already-finished on the platform — no
|
|
209
|
+
// steps follow, so we don't keep the returned id.
|
|
210
|
+
await this.fetch('POST', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios`, {
|
|
211
|
+
name: input.name,
|
|
212
|
+
hash: input.hash,
|
|
213
|
+
testFile: input.testFile,
|
|
214
|
+
feature: input.feature,
|
|
215
|
+
seeds: input.seeds,
|
|
216
|
+
roles: input.roles,
|
|
217
|
+
tier: input.tier,
|
|
218
|
+
skipped: true,
|
|
219
|
+
reason: input.reason,
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
|
|
176
223
|
recordStep(event: StepEvent): Promise<void> {
|
|
177
224
|
// Track synchronously so flush() awaits the entire pipeline (including
|
|
178
225
|
// encodeScreenshot's fs.readFile and the upload), not just whatever
|
|
@@ -187,7 +234,7 @@ class HttpReporter implements Reporter {
|
|
|
187
234
|
const screenshot = event.screenshotPath
|
|
188
235
|
? await this.encodeScreenshot(event.screenshotPath)
|
|
189
236
|
: undefined
|
|
190
|
-
await this.fetch('POST', `/api/v1/runs/${runId}/scenarios/${event.scenarioId}/steps`, {
|
|
237
|
+
await this.fetch('POST', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios/${event.scenarioId}/steps`, {
|
|
191
238
|
attempt: event.attempt,
|
|
192
239
|
sequence: event.sequence,
|
|
193
240
|
kind: event.kind,
|
|
@@ -206,7 +253,7 @@ class HttpReporter implements Reporter {
|
|
|
206
253
|
const runId = await this.ensureRun()
|
|
207
254
|
// Awaited inline so the scenario status is committed before the
|
|
208
255
|
// bun:test afterAll returns.
|
|
209
|
-
await this.fetch('PATCH', `/api/v1/runs/${runId}/scenarios/${input.scenarioId}`, {
|
|
256
|
+
await this.fetch('PATCH', `/api/v1/${this.config.projectId}/runs/${runId}/scenarios/${input.scenarioId}`, {
|
|
210
257
|
status: input.status,
|
|
211
258
|
durationMs: input.durationMs,
|
|
212
259
|
attempts: input.attempts,
|
|
@@ -326,6 +373,9 @@ export function configureFromEnv(env: NodeJS.ProcessEnv = process.env): Reporter
|
|
|
326
373
|
branch: env['OPICE_BRANCH'] ?? env['GITHUB_REF_NAME'],
|
|
327
374
|
commit: env['OPICE_COMMIT'] ?? env['GITHUB_SHA'],
|
|
328
375
|
source: isCI ? 'ci' : 'local',
|
|
376
|
+
// Record the selected tier only when one was explicitly requested — a run
|
|
377
|
+
// with no OPICE_TIER ran everything and carries no tier filter.
|
|
378
|
+
tier: env['OPICE_TIER'] ? resolveSelectedTier(env) : undefined,
|
|
329
379
|
})
|
|
330
380
|
setReporter(reporter)
|
|
331
381
|
return reporter
|
package/src/scenario.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { closePage, getContext, launchPage } from './context.js'
|
|
|
4
4
|
import { screenshot } from './element.js'
|
|
5
5
|
import { getReporter, type Reporter } from './reporter.js'
|
|
6
6
|
import { loadUserSetup } from './setup.js'
|
|
7
|
+
import { isTierSkipped, normalizeTier, parseSelectedTier, type Tier, TIER_ORDER } from './tier.js'
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* `bun:test` is resolved lazily, at the moment `browserTest` registers a
|
|
@@ -44,6 +45,18 @@ export interface BrowserTestMeta {
|
|
|
44
45
|
hash?: string
|
|
45
46
|
/** Feature / requirement id this scenario covers (e.g. `'F-SML-03a'`). */
|
|
46
47
|
feature?: string
|
|
48
|
+
/**
|
|
49
|
+
* Test tier — *when* this scenario runs (critical < standard < extended).
|
|
50
|
+
* A run selects a tier via `OPICE_TIER` / `opice test --tier`; selection is a
|
|
51
|
+
* threshold (running `standard` runs critical + standard). A scenario above
|
|
52
|
+
* the selected tier is **skipped**: reported as `skipped` (so it still shows
|
|
53
|
+
* on the dashboard) but never opens a browser. Defaults to `standard`.
|
|
54
|
+
*
|
|
55
|
+
* critical — the must-pass core, every push
|
|
56
|
+
* standard — the normal suite (default), PRs / merges
|
|
57
|
+
* extended — slow / edge / expensive, nightly or on demand
|
|
58
|
+
*/
|
|
59
|
+
tier?: Tier
|
|
47
60
|
/**
|
|
48
61
|
* Seeds that must be loaded for this scenario to run — machine-checkable
|
|
49
62
|
* preconditions, not prose. e.g. `['initial-data', 'crm-master-data']`.
|
|
@@ -107,6 +120,40 @@ function captureTestFile(): string | undefined {
|
|
|
107
120
|
return undefined
|
|
108
121
|
}
|
|
109
122
|
|
|
123
|
+
// The tier this run selected (OPICE_TIER), resolved + cached once. An
|
|
124
|
+
// unrecognized value warns once and falls back to running everything.
|
|
125
|
+
let cachedSelectedTier: Tier | undefined
|
|
126
|
+
function getSelectedTier(): Tier {
|
|
127
|
+
if (cachedSelectedTier === undefined) {
|
|
128
|
+
const parsed = parseSelectedTier()
|
|
129
|
+
if (!parsed.recognized) {
|
|
130
|
+
console.warn(
|
|
131
|
+
`[opice] unknown OPICE_TIER="${process.env['OPICE_TIER']}" — running all tiers `
|
|
132
|
+
+ `(use one of: ${TIER_ORDER.join(', ')}).`,
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
cachedSelectedTier = parsed.tier
|
|
136
|
+
}
|
|
137
|
+
return cachedSelectedTier
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Names of scenarios skipped by the tier filter, summarized once at process
|
|
141
|
+
// exit so a tiered run prints "N skipped" instead of a line per scenario.
|
|
142
|
+
const skippedScenarioNames: string[] = []
|
|
143
|
+
let skipSummaryHooked = false
|
|
144
|
+
function noteSkipped(name: string): void {
|
|
145
|
+
skippedScenarioNames.push(name)
|
|
146
|
+
if (skipSummaryHooked) return
|
|
147
|
+
skipSummaryHooked = true
|
|
148
|
+
process.on('exit', () => {
|
|
149
|
+
if (skippedScenarioNames.length === 0) return
|
|
150
|
+
console.warn(
|
|
151
|
+
`[opice] ${skippedScenarioNames.length} scenario(s) skipped — above the selected `
|
|
152
|
+
+ `tier '${getSelectedTier()}' (OPICE_TIER).`,
|
|
153
|
+
)
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
|
|
110
157
|
let currentScenarioId: string | null = null
|
|
111
158
|
let currentScenarioStart: number = 0
|
|
112
159
|
let currentScenarioFailures = 0
|
|
@@ -165,6 +212,14 @@ export function browserTest(meta: BrowserTestMeta, fn: () => void | Promise<void
|
|
|
165
212
|
// fn is the legacy registrar (it registers its own test()/hooks).
|
|
166
213
|
const isBody = fn.constructor.name === 'AsyncFunction'
|
|
167
214
|
|
|
215
|
+
// Tier gate: a scenario above the selected tier is registered but not run —
|
|
216
|
+
// reported `skipped` so the dashboard shows the full inventory.
|
|
217
|
+
const scenarioTier = normalizeTier(meta.tier)
|
|
218
|
+
if (isTierSkipped(scenarioTier, getSelectedTier())) {
|
|
219
|
+
registerSkipped(meta, scenarioTier, testFile, reporter)
|
|
220
|
+
return
|
|
221
|
+
}
|
|
222
|
+
|
|
168
223
|
describe(meta.name, () => {
|
|
169
224
|
beforeAll(async () => {
|
|
170
225
|
currentScenarioStart = Date.now()
|
|
@@ -180,6 +235,7 @@ export function browserTest(meta: BrowserTestMeta, fn: () => void | Promise<void
|
|
|
180
235
|
feature: meta.feature,
|
|
181
236
|
seeds: meta.seeds,
|
|
182
237
|
roles: meta.roles,
|
|
238
|
+
tier: scenarioTier,
|
|
183
239
|
})
|
|
184
240
|
} catch {
|
|
185
241
|
currentScenarioId = null
|
|
@@ -285,6 +341,38 @@ export function browserTest(meta: BrowserTestMeta, fn: () => void | Promise<void
|
|
|
285
341
|
})
|
|
286
342
|
}
|
|
287
343
|
|
|
344
|
+
/**
|
|
345
|
+
* Register a scenario the tier filter excluded. It's reported to the platform as
|
|
346
|
+
* `skipped` (so the dashboard shows it alongside what ran) but never opens a
|
|
347
|
+
* browser. The report runs in a real — instant, browser-free — `test`, not a
|
|
348
|
+
* `test.skip`: bun won't run a describe's hooks if every test in it is skipped,
|
|
349
|
+
* so a skip body is the only place left to POST from. With reporting off (local
|
|
350
|
+
* authoring), the body is a no-op against the NoopReporter.
|
|
351
|
+
*/
|
|
352
|
+
function registerSkipped(meta: BrowserTestMeta, tier: Tier, testFile: string | undefined, reporter: Reporter): void {
|
|
353
|
+
noteSkipped(meta.name)
|
|
354
|
+
const { describe, test } = bunTest()
|
|
355
|
+
const reason = `tier '${tier}' above the selected tier '${getSelectedTier()}'`
|
|
356
|
+
describe(meta.name, () => {
|
|
357
|
+
test('skipped (tier)', async () => {
|
|
358
|
+
try {
|
|
359
|
+
await reporter.skipScenario({
|
|
360
|
+
name: meta.name,
|
|
361
|
+
hash: meta.hash,
|
|
362
|
+
testFile,
|
|
363
|
+
feature: meta.feature,
|
|
364
|
+
seeds: meta.seeds,
|
|
365
|
+
roles: meta.roles,
|
|
366
|
+
tier,
|
|
367
|
+
reason,
|
|
368
|
+
})
|
|
369
|
+
} catch {
|
|
370
|
+
// Best-effort: reporting a skip must never fail the run.
|
|
371
|
+
}
|
|
372
|
+
})
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
|
|
288
376
|
/**
|
|
289
377
|
* Open a fresh isolated browser context + page for `meta` and navigate to its
|
|
290
378
|
* scenario URL. `launchPage()` closes any previous context first, so calling
|
package/src/tier.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test tiers — an ordered hierarchy for *when* a scenario runs.
|
|
3
|
+
*
|
|
4
|
+
* A scenario declares its tier in `browserTest` meta (default `standard`); a run
|
|
5
|
+
* selects a tier via `OPICE_TIER` (the `opice test --tier` flag). Selection is a
|
|
6
|
+
* THRESHOLD: running a tier runs every scenario AT OR BELOW it — the standard
|
|
7
|
+
* `smoke ⊂ regression ⊂ full` model. Scenarios above the selected tier are
|
|
8
|
+
* *skipped*: still registered and reported as `skipped` (so the dashboard shows
|
|
9
|
+
* the full inventory, not just what ran), but they never open a browser.
|
|
10
|
+
*
|
|
11
|
+
* critical — the must-pass core. Run on every push.
|
|
12
|
+
* standard — the normal suite (the default for an untagged scenario). PRs / merges.
|
|
13
|
+
* extended — slow / edge / expensive. Run nightly or on demand.
|
|
14
|
+
*
|
|
15
|
+
* OPICE_TIER=critical → critical only
|
|
16
|
+
* OPICE_TIER=standard → critical + standard
|
|
17
|
+
* OPICE_TIER=extended → everything (also the default when OPICE_TIER is unset)
|
|
18
|
+
*/
|
|
19
|
+
export type Tier = 'critical' | 'standard' | 'extended'
|
|
20
|
+
|
|
21
|
+
/** Tiers low → high. A scenario's index is its level; it runs when level <= selected level. */
|
|
22
|
+
export const TIER_ORDER: readonly Tier[] = ['critical', 'standard', 'extended']
|
|
23
|
+
|
|
24
|
+
/** A scenario with no declared tier sits in the middle `standard` tier. */
|
|
25
|
+
export const DEFAULT_SCENARIO_TIER: Tier = 'standard'
|
|
26
|
+
|
|
27
|
+
/** With no `OPICE_TIER` set, run everything — select the widest tier. */
|
|
28
|
+
export const DEFAULT_SELECTED_TIER: Tier = 'extended'
|
|
29
|
+
|
|
30
|
+
function isTier(value: string | undefined): value is Tier {
|
|
31
|
+
return value === 'critical' || value === 'standard' || value === 'extended'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Normalize a scenario's declared tier, defaulting (and tolerating junk) to `standard`. */
|
|
35
|
+
export function normalizeTier(tier: string | undefined): Tier {
|
|
36
|
+
return isTier(tier) ? tier : DEFAULT_SCENARIO_TIER
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface SelectedTier {
|
|
40
|
+
tier: Tier
|
|
41
|
+
/** false when `OPICE_TIER` held an unrecognized value (the caller may warn). */
|
|
42
|
+
recognized: boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The tier selected for this run, parsed from `OPICE_TIER`. Unset → run
|
|
47
|
+
* everything. `all`/`full` are friendly aliases for the widest tier. An
|
|
48
|
+
* unrecognized value resolves to "run everything" (`recognized: false`) rather
|
|
49
|
+
* than silently dropping tests — better to over-run than to skip on a typo.
|
|
50
|
+
*/
|
|
51
|
+
export function parseSelectedTier(env: NodeJS.ProcessEnv = process.env): SelectedTier {
|
|
52
|
+
const raw = env['OPICE_TIER']?.trim().toLowerCase()
|
|
53
|
+
if (!raw) return { tier: DEFAULT_SELECTED_TIER, recognized: true }
|
|
54
|
+
if (isTier(raw)) return { tier: raw, recognized: true }
|
|
55
|
+
if (raw === 'all' || raw === 'full') return { tier: 'extended', recognized: true }
|
|
56
|
+
return { tier: DEFAULT_SELECTED_TIER, recognized: false }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Convenience: the resolved selected tier, ignoring whether the value was recognized. */
|
|
60
|
+
export function resolveSelectedTier(env: NodeJS.ProcessEnv = process.env): Tier {
|
|
61
|
+
return parseSelectedTier(env).tier
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** A scenario is skipped when its tier sits ABOVE the selected one. */
|
|
65
|
+
export function isTierSkipped(scenarioTier: Tier, selectedTier: Tier): boolean {
|
|
66
|
+
return TIER_ORDER.indexOf(scenarioTier) > TIER_ORDER.indexOf(selectedTier)
|
|
67
|
+
}
|