middlewright 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,91 @@
1
1
  import type { Plugin, OverrideableMethod } from "../plugin-system.ts";
2
+ export type VideoModeSpan = {
3
+ start: number;
4
+ end: number;
5
+ };
6
+ export type VideoModeOutputs = {
7
+ player?: string;
8
+ raw?: string;
9
+ rendered?: string;
10
+ };
11
+ export type VideoModeOutputPaths = {
12
+ metadata: string;
13
+ player: string;
14
+ raw: string;
15
+ rendered: string;
16
+ reportPlayer: string;
17
+ };
18
+ export type VideoModeSourceRange = {
19
+ start?: number;
20
+ end?: number;
21
+ };
22
+ export type VideoModeRect = {
23
+ x: number;
24
+ y: number;
25
+ width: number;
26
+ height: number;
27
+ };
28
+ export type VideoModeViewport = {
29
+ width: number;
30
+ height: number;
31
+ };
32
+ export type VideoModeHighlight = VideoModeSpan & {
33
+ actionEnd?: number;
34
+ color: string;
35
+ image?: string;
36
+ method?: OverrideableMethod;
37
+ rect: VideoModeRect;
38
+ thickness: number;
39
+ viewport: VideoModeViewport;
40
+ };
41
+ export type VideoModeMetadata = {
42
+ schemaVersion: 1;
43
+ timebase: "ms";
44
+ deadAir: VideoModeSpan[];
45
+ highlights: VideoModeHighlight[];
46
+ outputs: VideoModeOutputs;
47
+ sourceRange: VideoModeSourceRange;
48
+ };
49
+ export type VideoModeControls = {
50
+ /**
51
+ * Run invisible video bookkeeping and write the elapsed span as dead air.
52
+ */
53
+ deadAir<T>(action: () => Promise<T>): Promise<T>;
54
+ /** Milliseconds since video-mode started recording metadata for this test. */
55
+ getVideoTimestamp(): number;
56
+ /** Parsed video-mode metadata JSON after the test, or the current in-memory snapshot during the test. */
57
+ metadata(): Promise<VideoModeMetadata>;
58
+ /** Absolute artifact paths for the current test's video-mode outputs. */
59
+ outputPaths(): VideoModeOutputPaths;
60
+ /** Render the video from this source timestamp, in ms. Defaults to the current video timestamp. */
61
+ setStartTime(ms?: number): void;
62
+ /** Render the video until this source timestamp, in ms. Defaults to the current video timestamp. */
63
+ setEndTime(ms?: number): void;
64
+ };
65
+ export type VideoModePageExtension = {
66
+ videoMode: VideoModeControls;
67
+ };
68
+ export type VideoModePlugin = Plugin<VideoModePageExtension> & VideoModeControls;
69
+ export type VideoModeOutlineHighlightStyle = `${number}px solid ${string}`;
70
+ export type VideoModeHighlightOptions = boolean | {
71
+ /** Highlight duration in the rendered video (ms). Default: 1000 */
72
+ duration?: number;
73
+ mode: "pointer";
74
+ } | {
75
+ /** Highlight duration in the rendered video (ms). Default: 1000 */
76
+ duration?: number;
77
+ mode: "outline";
78
+ /** Outline style for the rendered video. Default: '3px solid gold' */
79
+ style?: VideoModeOutlineHighlightStyle;
80
+ };
2
81
  export type VideoModeOptions = {
3
- /** Pause duration before action (ms). Default: 1000 */
4
- pauseBefore?: number;
5
- /** Pause duration after test (ms). Default: 3000 */
6
- pauseAfterTest?: number;
7
- /** Highlight style. Default: '3px solid gold' */
8
- highlightStyle?: string;
82
+ /**
83
+ * Render action annotations. `true` uses pointer mode with default options.
84
+ * Default: true
85
+ */
86
+ highlight?: VideoModeHighlightOptions;
87
+ /** Final hold duration in the rendered video (ms). Default: 3000 */
88
+ finalHold?: number;
9
89
  /** Methods to skip highlighting. Default: ['waitFor'] */
10
90
  skipMethods?: OverrideableMethod[];
11
91
  /**
@@ -14,9 +94,29 @@ export type VideoModeOptions = {
14
94
  * flows that shouldn't be slowed down. Default: []
15
95
  */
16
96
  skipStackFrames?: string[];
97
+ /**
98
+ * Maximum rendered duration for each dead-air span. Longer spans are sped up
99
+ * so they fit within this duration.
100
+ */
101
+ deadAirThreshold?: number;
102
+ /**
103
+ * Where the rendered video starts, trimming the blank "startup" lead-in
104
+ * (about:blank, the loading shell, the pre-hydration app frame) so it opens on
105
+ * real content instead of a white screen. An explicit `setStartTime()` always
106
+ * wins over this.
107
+ *
108
+ * - `"auto"` (default): pick a sensible strategy — currently the blank
109
+ * detector below. Chosen so consumers get lead-in trimming just by upgrading.
110
+ * - `"detect-blank"`: find where the leading blank frames end in the recorded
111
+ * pixels (the first frame that differs from the opening frame) and start
112
+ * there, when that lead-in is long enough to be worth trimming.
113
+ * - `["selector", css]`: start the moment `css` first becomes visible (waited
114
+ * for live, once); falls back to blank detection if it never appears.
115
+ * - `"never"`: don't trim. Use this for a video whose exact frames you assert
116
+ * on, since trimming shifts the timeline.
117
+ */
118
+ trimStart?: VideoModeTrimStart;
17
119
  };
18
- /**
19
- * Highlights elements before actions and pauses for video recording.
20
- * Also pauses after tests complete for better video endings.
21
- */
22
- export declare const videoMode: (options?: VideoModeOptions) => Plugin;
120
+ export type VideoModeTrimStart = "auto" | "detect-blank" | "never" | ["selector", string];
121
+ /** Records video-mode facts and renders annotations into the recorded video. */
122
+ export declare const videoMode: (options?: VideoModeOptions) => VideoModePlugin;