@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 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';
@@ -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;AAEvG,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"}
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"}
@@ -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/runs/<id>/finish so the dashboard sees the run as completed.
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,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;CACvB;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;CAChB;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,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;AAWD,eAAO,MAAM,WAAW,QAAwC,CAAA;AAMhE,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACb;AAsKD,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,CA8B/E"}
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/runs/<id>/finish so the dashboard sees the run as completed.
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', '/api/v1/runs', {
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 = { endpoint: this.config.endpoint, apiKey: this.config.apiKey, runId };
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;
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
@@ -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']`.
@@ -1 +1 @@
1
- {"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../src/scenario.ts"],"names":[],"mappings":"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"}
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
@@ -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
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opice/harness",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Runtime primitives for opice — AI-driven E2E browser tests on top of Playwright",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
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/runs/<id>/finish so the dashboard sees the run as completed.
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', '/api/v1/runs', {
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 = { endpoint: this.config.endpoint, apiKey: this.config.apiKey, runId }
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
+ }