objs-core 2.3.0 → 2.4.1
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/README.md +572 -618
- package/objs-extension/README.md +32 -0
- package/objs-extension/background.js +110 -0
- package/objs-extension/bridge.js +193 -0
- package/objs-extension/icons/icon128.png +0 -0
- package/objs-extension/lib/objs-inject.js +5308 -0
- package/objs-extension/manifest.json +18 -0
- package/objs-extension/sidepanel.css +455 -0
- package/objs-extension/sidepanel.html +56 -0
- package/objs-extension/sidepanel.js +908 -0
- package/objs.built.js +475 -120
- package/objs.built.min.js +63 -54
- package/objs.d.ts +584 -525
- package/objs.global.js +5308 -0
- package/objs.global.min.js +98 -0
- package/objs.js +593 -134
- package/package.json +73 -70
package/objs.d.ts
CHANGED
|
@@ -1,525 +1,584 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Objs-core v2.
|
|
3
|
-
* @license Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// ─── Core instance types ──────────────────────────────────────────────────
|
|
7
|
-
|
|
8
|
-
/** State definition object for o.init(). `render` is the reserved creation state. */
|
|
9
|
-
export interface StateObject {
|
|
10
|
-
tag?: string;
|
|
11
|
-
tagName?: string;
|
|
12
|
-
/** Component name — used for o.autotag data-* attribute (camelCase → kebab-case) */
|
|
13
|
-
name?: string;
|
|
14
|
-
class?: string;
|
|
15
|
-
/** React-style alias for `class` */
|
|
16
|
-
className?: string;
|
|
17
|
-
id?: string;
|
|
18
|
-
html?: string;
|
|
19
|
-
innerHTML?: string;
|
|
20
|
-
style?: string | Record<string, string>;
|
|
21
|
-
dataset?: Record<string, string>;
|
|
22
|
-
events?: Record<string, EventListener>;
|
|
23
|
-
[attr: string]: unknown;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Parameter object passed to every state function.
|
|
27
|
-
*
|
|
28
|
-
* State functions receive ONE merged object: { ...passedProps, self, o, i, parent, data }.
|
|
29
|
-
* - Properties from the calling argument are spread into the context.
|
|
30
|
-
* - `data` holds the raw first argument (useful for primitives: `comp.setState(5)` → `data = 5`).
|
|
31
|
-
* - `parent` is the ObjsInstance that this component was `appendInside()` into (if any).
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* // Passing an object — destructure its keys:
|
|
35
|
-
* sync: ({ self, values, errors }) => { ... } // comp.sync(store)
|
|
36
|
-
* // Passing a primitive — use `data`:
|
|
37
|
-
* setCount: ({ self, data }) => { self.html(data); } // comp.setCount(5)
|
|
38
|
-
*/
|
|
39
|
-
export interface StateParams {
|
|
40
|
-
self: ObjsInstance;
|
|
41
|
-
o: typeof o;
|
|
42
|
-
i: number;
|
|
43
|
-
/** The ObjsInstance this component was appendInside() into, or null */
|
|
44
|
-
parent: ObjsInstance | null;
|
|
45
|
-
/** The raw first argument passed when the state method was called */
|
|
46
|
-
data: unknown;
|
|
47
|
-
[key: string]: unknown;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** State function signature */
|
|
51
|
-
export type StateFunction = (params: StateParams) => void | unknown;
|
|
52
|
-
|
|
53
|
-
/** States map passed to o.init() */
|
|
54
|
-
export type StatesMap = {
|
|
55
|
-
render?: StateObject | StateFunction | string;
|
|
56
|
-
[stateName: string]: StateObject | StateFunction | string | undefined;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/** Test case tuple: [title, testFn | true | false | string] */
|
|
60
|
-
export type TestCase = [string, ((info: TestInfo) => boolean | string | undefined) | boolean | string | undefined];
|
|
61
|
-
|
|
62
|
-
export interface TestInfo {
|
|
63
|
-
n: number;
|
|
64
|
-
i: number;
|
|
65
|
-
title: string;
|
|
66
|
-
tShowOk: boolean;
|
|
67
|
-
tStyled: boolean;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** Object returned by o.addTest() */
|
|
71
|
-
export interface TestHandle {
|
|
72
|
-
testId: number;
|
|
73
|
-
run(): void;
|
|
74
|
-
autorun(): void;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Object returned by o.newLoader() */
|
|
78
|
-
export interface ObjsLoader<T = unknown> {
|
|
79
|
-
reload(promise: Promise<T>): void;
|
|
80
|
-
isObjsLoader: true;
|
|
81
|
-
listeners: Array<[ObjsInstance, string, string?]>;
|
|
82
|
-
isFinished(): boolean;
|
|
83
|
-
getStore(): T | null;
|
|
84
|
-
connect(listener: ObjsInstance, state?: string, fail?: string): void;
|
|
85
|
-
disconnect(listener: ObjsInstance): void;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Element measurement result from o.measure() */
|
|
89
|
-
export interface MeasureResult {
|
|
90
|
-
width: number;
|
|
91
|
-
height: number;
|
|
92
|
-
top: number;
|
|
93
|
-
left: number;
|
|
94
|
-
visible: boolean;
|
|
95
|
-
opacity: string;
|
|
96
|
-
zIndex: string;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Recorded action entry */
|
|
100
|
-
export interface RecordedAction {
|
|
101
|
-
type: string;
|
|
102
|
-
target: string;
|
|
103
|
-
time: number;
|
|
104
|
-
scrollY?: number;
|
|
105
|
-
value?: string;
|
|
106
|
-
checked?: boolean;
|
|
107
|
-
key?: string;
|
|
108
|
-
code?: string;
|
|
109
|
-
targetType?: string;
|
|
110
|
-
/** When target matches multiple elements, selector for the repeated list item container */
|
|
111
|
-
listSelector?: string;
|
|
112
|
-
/** Index within listSelector matches for replay by index */
|
|
113
|
-
targetIndex?: number;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export type Assertion = {
|
|
117
|
-
actionIdx: number;
|
|
118
|
-
type: 'visible' | 'class' | 'style' | 'hidden' | 'disabled' | 'aria-expanded' | 'aria-checked';
|
|
119
|
-
selector: string;
|
|
120
|
-
text?: string;
|
|
121
|
-
className?: string;
|
|
122
|
-
style?: string;
|
|
123
|
-
hidden?: boolean;
|
|
124
|
-
disabled?: boolean;
|
|
125
|
-
ariaExpanded?: string | null;
|
|
126
|
-
ariaChecked?: string | null;
|
|
127
|
-
/** When selector matches multiple, selector for the list item container */
|
|
128
|
-
listSelector?: string;
|
|
129
|
-
/** Index within listSelector matches */
|
|
130
|
-
index?: number;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
/** WebSocket connection and message capture */
|
|
134
|
-
export interface WebSocketEvent {
|
|
135
|
-
url: string;
|
|
136
|
-
protocol?: string;
|
|
137
|
-
open: boolean;
|
|
138
|
-
messages: Array<{ dir: 'in' | 'out'; data: string }>;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
export interface
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
*/
|
|
159
|
-
export interface
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
function
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
function
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
function
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
function
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
function
|
|
337
|
-
function
|
|
338
|
-
|
|
339
|
-
//
|
|
340
|
-
function
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
function
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
function
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
function
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
function
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
state
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
function
|
|
503
|
-
|
|
504
|
-
function
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Objs-core v2.4.1 TypeScript definitions
|
|
3
|
+
* @license Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ─── Core instance types ──────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
/** State definition object for o.init(). `render` is the reserved creation state. */
|
|
9
|
+
export interface StateObject {
|
|
10
|
+
tag?: string;
|
|
11
|
+
tagName?: string;
|
|
12
|
+
/** Component name — used for o.autotag data-* attribute (camelCase → kebab-case) */
|
|
13
|
+
name?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
/** React-style alias for `class` */
|
|
16
|
+
className?: string;
|
|
17
|
+
id?: string;
|
|
18
|
+
html?: string;
|
|
19
|
+
innerHTML?: string;
|
|
20
|
+
style?: string | Record<string, string>;
|
|
21
|
+
dataset?: Record<string, string>;
|
|
22
|
+
events?: Record<string, EventListener>;
|
|
23
|
+
[attr: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Parameter object passed to every state function.
|
|
27
|
+
*
|
|
28
|
+
* State functions receive ONE merged object: { ...passedProps, self, o, i, parent, data }.
|
|
29
|
+
* - Properties from the calling argument are spread into the context.
|
|
30
|
+
* - `data` holds the raw first argument (useful for primitives: `comp.setState(5)` → `data = 5`).
|
|
31
|
+
* - `parent` is the ObjsInstance that this component was `appendInside()` into (if any).
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Passing an object — destructure its keys:
|
|
35
|
+
* sync: ({ self, values, errors }) => { ... } // comp.sync(store)
|
|
36
|
+
* // Passing a primitive — use `data`:
|
|
37
|
+
* setCount: ({ self, data }) => { self.html(data); } // comp.setCount(5)
|
|
38
|
+
*/
|
|
39
|
+
export interface StateParams {
|
|
40
|
+
self: ObjsInstance;
|
|
41
|
+
o: typeof o;
|
|
42
|
+
i: number;
|
|
43
|
+
/** The ObjsInstance this component was appendInside() into, or null */
|
|
44
|
+
parent: ObjsInstance | null;
|
|
45
|
+
/** The raw first argument passed when the state method was called */
|
|
46
|
+
data: unknown;
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** State function signature */
|
|
51
|
+
export type StateFunction = (params: StateParams) => void | unknown;
|
|
52
|
+
|
|
53
|
+
/** States map passed to o.init() */
|
|
54
|
+
export type StatesMap = {
|
|
55
|
+
render?: StateObject | StateFunction | string;
|
|
56
|
+
[stateName: string]: StateObject | StateFunction | string | undefined;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Test case tuple: [title, testFn | true | false | string] */
|
|
60
|
+
export type TestCase = [string, ((info: TestInfo) => boolean | string | undefined) | boolean | string | undefined];
|
|
61
|
+
|
|
62
|
+
export interface TestInfo {
|
|
63
|
+
n: number;
|
|
64
|
+
i: number;
|
|
65
|
+
title: string;
|
|
66
|
+
tShowOk: boolean;
|
|
67
|
+
tStyled: boolean;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Object returned by o.addTest() */
|
|
71
|
+
export interface TestHandle {
|
|
72
|
+
testId: number;
|
|
73
|
+
run(): void;
|
|
74
|
+
autorun(): void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Object returned by o.newLoader() */
|
|
78
|
+
export interface ObjsLoader<T = unknown> {
|
|
79
|
+
reload(promise: Promise<T>): void;
|
|
80
|
+
isObjsLoader: true;
|
|
81
|
+
listeners: Array<[ObjsInstance, string, string?]>;
|
|
82
|
+
isFinished(): boolean;
|
|
83
|
+
getStore(): T | null;
|
|
84
|
+
connect(listener: ObjsInstance, state?: string, fail?: string): void;
|
|
85
|
+
disconnect(listener: ObjsInstance): void;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Element measurement result from o.measure() */
|
|
89
|
+
export interface MeasureResult {
|
|
90
|
+
width: number;
|
|
91
|
+
height: number;
|
|
92
|
+
top: number;
|
|
93
|
+
left: number;
|
|
94
|
+
visible: boolean;
|
|
95
|
+
opacity: string;
|
|
96
|
+
zIndex: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Recorded action entry */
|
|
100
|
+
export interface RecordedAction {
|
|
101
|
+
type: string;
|
|
102
|
+
target: string;
|
|
103
|
+
time: number;
|
|
104
|
+
scrollY?: number;
|
|
105
|
+
value?: string;
|
|
106
|
+
checked?: boolean;
|
|
107
|
+
key?: string;
|
|
108
|
+
code?: string;
|
|
109
|
+
targetType?: string;
|
|
110
|
+
/** When target matches multiple elements, selector for the repeated list item container */
|
|
111
|
+
listSelector?: string;
|
|
112
|
+
/** Index within listSelector matches for replay by index */
|
|
113
|
+
targetIndex?: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export type Assertion = {
|
|
117
|
+
actionIdx: number;
|
|
118
|
+
type: 'visible' | 'class' | 'style' | 'hidden' | 'disabled' | 'aria-expanded' | 'aria-checked';
|
|
119
|
+
selector: string;
|
|
120
|
+
text?: string;
|
|
121
|
+
className?: string;
|
|
122
|
+
style?: string;
|
|
123
|
+
hidden?: boolean;
|
|
124
|
+
disabled?: boolean;
|
|
125
|
+
ariaExpanded?: string | null;
|
|
126
|
+
ariaChecked?: string | null;
|
|
127
|
+
/** When selector matches multiple, selector for the list item container */
|
|
128
|
+
listSelector?: string;
|
|
129
|
+
/** Index within listSelector matches */
|
|
130
|
+
index?: number;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/** WebSocket connection and message capture */
|
|
134
|
+
export interface WebSocketEvent {
|
|
135
|
+
url: string;
|
|
136
|
+
protocol?: string;
|
|
137
|
+
open: boolean;
|
|
138
|
+
messages: Array<{ dir: 'in' | 'out'; data: string }>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Optional strict replay defaults saved with the recording (from startRecording options) */
|
|
142
|
+
export interface RecordingStrictCapture {
|
|
143
|
+
assertions?: boolean;
|
|
144
|
+
network?: boolean;
|
|
145
|
+
websocket?: boolean;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Entry when a node was removed during recording (for lenient assertion skip or strict absence checks) */
|
|
149
|
+
export interface RecordingRemovedEntry {
|
|
150
|
+
actionIdx: number;
|
|
151
|
+
type: 'removed';
|
|
152
|
+
selector: string;
|
|
153
|
+
text?: string;
|
|
154
|
+
listSelector?: string;
|
|
155
|
+
index?: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Full recording object */
|
|
159
|
+
export interface Recording {
|
|
160
|
+
actions: RecordedAction[];
|
|
161
|
+
mocks: Record<string, { url: string; method: string; request: unknown; response: unknown; status: number }>;
|
|
162
|
+
initialData: Record<string, unknown>;
|
|
163
|
+
stepDelays?: Record<string, number>;
|
|
164
|
+
assertions: Assertion[];
|
|
165
|
+
observeRoot: string | null;
|
|
166
|
+
websocketEvents?: WebSocketEvent[];
|
|
167
|
+
removedElements?: RecordingRemovedEntry[];
|
|
168
|
+
strictCapture?: RecordingStrictCapture;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Reactive store returned by o.createStore().
|
|
173
|
+
* Components subscribe via store.subscribe(component, stateName).
|
|
174
|
+
* When store.notify() is called, each subscribed component's state method
|
|
175
|
+
* receives the full store object, whose properties are merged into the
|
|
176
|
+
* state context: { ...storeProps, self, o, i, parent, data }.
|
|
177
|
+
*/
|
|
178
|
+
export interface ObjsStore<T extends object = Record<string, unknown>> {
|
|
179
|
+
_listeners: Array<(store: this) => void>;
|
|
180
|
+
/** Subscribe an Objs component state to this store.
|
|
181
|
+
* On every notify(), component[stateName](store) is called. */
|
|
182
|
+
subscribe(component: ObjsInstance, stateName: string): this;
|
|
183
|
+
/** Notify all subscribers — passes `this` store as the argument. */
|
|
184
|
+
notify(): void;
|
|
185
|
+
/** Restore store data from initial defaults; does not replace subscribe, notify, _listeners. */
|
|
186
|
+
reset(): void;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ─── ObjsInstance (chainable result of o() / o.init()) ────────────────────
|
|
190
|
+
|
|
191
|
+
export interface ObjsInstance {
|
|
192
|
+
// Properties
|
|
193
|
+
els: Element[];
|
|
194
|
+
el: Element | undefined;
|
|
195
|
+
last: Element | undefined;
|
|
196
|
+
length: number;
|
|
197
|
+
initID: number | undefined;
|
|
198
|
+
ie: Record<string, Array<[EventListener, unknown?, unknown?]>>;
|
|
199
|
+
delegated: Record<string, EventListener[]>;
|
|
200
|
+
store: Record<string, unknown>;
|
|
201
|
+
states: string[];
|
|
202
|
+
isDebug: boolean;
|
|
203
|
+
currentState: string;
|
|
204
|
+
savedStates: Record<string, unknown>;
|
|
205
|
+
isRoot: boolean;
|
|
206
|
+
/** The ObjsInstance this component was appendInside() into, or null */
|
|
207
|
+
_parent: ObjsInstance | null;
|
|
208
|
+
/**
|
|
209
|
+
* Named sub-elements collected from `ref="name"` attributes in the rendered HTML.
|
|
210
|
+
* Populated automatically on first render; `ref` attributes are removed from the DOM.
|
|
211
|
+
* @example
|
|
212
|
+
* // In render: html: `<div ref="body"></div>`
|
|
213
|
+
* // After render: component.refs.body → ObjsInstance wrapping that div
|
|
214
|
+
*/
|
|
215
|
+
refs: Record<string, ObjsInstance>;
|
|
216
|
+
|
|
217
|
+
// Selection
|
|
218
|
+
reset(query: QueryArg): ObjsInstance;
|
|
219
|
+
/** Select by index or by event: select(e) selects the element in this instance that contains e.target. */
|
|
220
|
+
select(i?: number | Event): ObjsInstance;
|
|
221
|
+
all(): ObjsInstance;
|
|
222
|
+
find(query: string): ObjsInstance;
|
|
223
|
+
first(query?: string): ObjsInstance;
|
|
224
|
+
add(el: QueryArg): ObjsInstance;
|
|
225
|
+
skip(i?: number): ObjsInstance;
|
|
226
|
+
remove(i?: number): ObjsInstance;
|
|
227
|
+
|
|
228
|
+
// State
|
|
229
|
+
init(states: StatesMap | StateFunction | string): ObjsInstance;
|
|
230
|
+
initState(state: StateObject, props?: Record<string, unknown>): ObjsInstance;
|
|
231
|
+
sample(state?: string): StatesMap;
|
|
232
|
+
saveState(stateId?: string, root?: boolean): ObjsInstance;
|
|
233
|
+
revertState(stateId?: string): ObjsInstance;
|
|
234
|
+
loseState(stateId: string): ObjsInstance;
|
|
235
|
+
|
|
236
|
+
// DOM manipulation
|
|
237
|
+
html(html?: string): string | ObjsInstance;
|
|
238
|
+
toString(): string;
|
|
239
|
+
[Symbol.toPrimitive](hint: string): string | number;
|
|
240
|
+
innerHTML(html?: string): string[] | ObjsInstance;
|
|
241
|
+
innerText(text: string): ObjsInstance;
|
|
242
|
+
textContent(content: string): ObjsInstance;
|
|
243
|
+
val(value?: string): string | ObjsInstance;
|
|
244
|
+
attr(attr: string, value?: string | null): string | string[] | ObjsInstance;
|
|
245
|
+
attrs(): Record<string, string> | Array<Record<string, string>>;
|
|
246
|
+
dataset(values?: Record<string, string>): Record<string, string> | Array<Record<string, string>> | ObjsInstance;
|
|
247
|
+
style(value?: string | null): ObjsInstance;
|
|
248
|
+
css(styles: Record<string, string> | null): ObjsInstance;
|
|
249
|
+
cssMerge(styles: Record<string, string | null | undefined> | null): ObjsInstance;
|
|
250
|
+
setClass(value: string): ObjsInstance;
|
|
251
|
+
addClass(...cls: string[]): ObjsInstance;
|
|
252
|
+
removeClass(...cls: string[]): ObjsInstance;
|
|
253
|
+
toggleClass(cls: string, rule?: boolean): ObjsInstance;
|
|
254
|
+
haveClass(cls: string): boolean;
|
|
255
|
+
|
|
256
|
+
// Events
|
|
257
|
+
on(events: string, handler: EventListener, options?: EventListenerOptions): ObjsInstance;
|
|
258
|
+
off(events: string, handler: EventListener, options?: EventListenerOptions): ObjsInstance;
|
|
259
|
+
offAll(event?: string): ObjsInstance;
|
|
260
|
+
onAll(event?: string): ObjsInstance;
|
|
261
|
+
onDelegate(events: string, selector: string, handler: EventListener): ObjsInstance;
|
|
262
|
+
offDelegate(event?: string): ObjsInstance;
|
|
263
|
+
onParent(events: string, selectorOrEl: string | Element, handler: EventListener): ObjsInstance;
|
|
264
|
+
offParent(events: string, query: string): ObjsInstance;
|
|
265
|
+
|
|
266
|
+
// DOM insertion
|
|
267
|
+
appendInside(el: QueryArg): ObjsInstance;
|
|
268
|
+
appendBefore(el: QueryArg): ObjsInstance;
|
|
269
|
+
appendAfter(el: QueryArg): ObjsInstance;
|
|
270
|
+
|
|
271
|
+
// Misc
|
|
272
|
+
forEach(fn: (ctx: { o: typeof o; self: ObjsInstance; i: number; el: Element }) => void): ObjsInstance;
|
|
273
|
+
connect(loader: ObjsLoader, state?: string, fail?: string): ObjsInstance;
|
|
274
|
+
getSSR(initId?: number): ObjsInstance;
|
|
275
|
+
saveAs(key: string): ObjsInstance;
|
|
276
|
+
unmount(): boolean;
|
|
277
|
+
take(query: QueryArg): ObjsInstance;
|
|
278
|
+
|
|
279
|
+
// React
|
|
280
|
+
prepareFor(createElement: Function, component?: Function): unknown;
|
|
281
|
+
|
|
282
|
+
// Debug (behind __DEV__ in build)
|
|
283
|
+
debug?: () => ObjsInstance;
|
|
284
|
+
|
|
285
|
+
// Dynamic state methods added by init()
|
|
286
|
+
render?: (props?: Record<string, unknown> | Array<Record<string, unknown>>) => ObjsInstance;
|
|
287
|
+
[stateName: string]: unknown;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
type QueryArg = string | Element | Element[] | ObjsInstance | number;
|
|
291
|
+
|
|
292
|
+
// ─── o() function and static API ─────────────────────────────────────────
|
|
293
|
+
|
|
294
|
+
declare function o(query?: QueryArg): ObjsInstance;
|
|
295
|
+
|
|
296
|
+
declare namespace o {
|
|
297
|
+
// Core
|
|
298
|
+
const inits: ObjsInstance[];
|
|
299
|
+
const getSaved: Record<string, ObjsInstance>;
|
|
300
|
+
const errors: Error[];
|
|
301
|
+
let debug: boolean;
|
|
302
|
+
let showErrors: boolean;
|
|
303
|
+
function logErrors(): void;
|
|
304
|
+
function onError(error: Error, name?: string): void;
|
|
305
|
+
function reactRender(...args: unknown[]): unknown;
|
|
306
|
+
|
|
307
|
+
// Autotag
|
|
308
|
+
let autotag: string | undefined;
|
|
309
|
+
|
|
310
|
+
function reactQA(componentName: string): Record<string, string>;
|
|
311
|
+
|
|
312
|
+
// Element selection
|
|
313
|
+
function first(query: string): ObjsInstance;
|
|
314
|
+
function take(query: QueryArg): ObjsInstance;
|
|
315
|
+
|
|
316
|
+
// State
|
|
317
|
+
function init(states: StatesMap | StateFunction | string): ObjsInstance;
|
|
318
|
+
function initState(state: StateObject, props?: Record<string, unknown>): ObjsInstance;
|
|
319
|
+
function getStates(): (string[] | undefined)[];
|
|
320
|
+
function getStores(): (Record<string, unknown> | undefined)[];
|
|
321
|
+
function getListeners(): (Record<string, unknown> | undefined)[];
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Create a reactive store — plain object with built-in subscribe / notify.
|
|
325
|
+
* Components subscribed via store.subscribe(comp, 'state') receive the store
|
|
326
|
+
* as their merged state context: { ...storeProps, self, o, i, parent, data }.
|
|
327
|
+
* @example
|
|
328
|
+
* const store = o.createStore({ count: 0, inc() { this.count++; this.notify(); } });
|
|
329
|
+
* store.subscribe(badge, 'sync'); // badge.sync(store) on every notify
|
|
330
|
+
*/
|
|
331
|
+
function createStore<T extends object>(defaults: T): T & ObjsStore<T>;
|
|
332
|
+
|
|
333
|
+
// AJAX
|
|
334
|
+
function ajax(url: string, props?: Record<string, unknown>): Promise<Response>;
|
|
335
|
+
function get(url: string, props?: Record<string, unknown>): Promise<Response>;
|
|
336
|
+
function post(url: string, props?: Record<string, unknown>): Promise<Response>;
|
|
337
|
+
function getParams(key?: string): Record<string, string> | string;
|
|
338
|
+
|
|
339
|
+
// Loader
|
|
340
|
+
function newLoader<T = unknown>(promise?: Promise<T>): ObjsLoader<T>;
|
|
341
|
+
|
|
342
|
+
// Include
|
|
343
|
+
let incCache: boolean;
|
|
344
|
+
let incCacheExp: number;
|
|
345
|
+
let incTimeout: number;
|
|
346
|
+
let incSource: string;
|
|
347
|
+
let incForce: boolean;
|
|
348
|
+
let incAsync: boolean;
|
|
349
|
+
let incCors: boolean;
|
|
350
|
+
let incFns: Record<string, number>;
|
|
351
|
+
function inc(sources: Record<string, string>, callBack?: (setId: number) => void, callBad?: (setId: number) => void): number;
|
|
352
|
+
function incCheck(set?: number, fnId?: number, loaded?: number): boolean;
|
|
353
|
+
function incCacheClear(all?: boolean): boolean;
|
|
354
|
+
|
|
355
|
+
// Routing
|
|
356
|
+
function route(path: string | boolean | ((path: string) => boolean), task?: Function | object): boolean | object;
|
|
357
|
+
function router(routes: Record<string, Function | object>): boolean;
|
|
358
|
+
|
|
359
|
+
// Cookies
|
|
360
|
+
function setCookie(title: string, value?: string | number | boolean, params?: Record<string, unknown>): void;
|
|
361
|
+
function getCookie(title: string): string | undefined;
|
|
362
|
+
function deleteCookie(title: string): void;
|
|
363
|
+
function clearCookies(): void;
|
|
364
|
+
/** Clear cookies, localStorage, and test-related sessionStorage. Call after Cookies/LS/SS tests. */
|
|
365
|
+
function clearAfterTests(): void;
|
|
366
|
+
|
|
367
|
+
// Storage
|
|
368
|
+
function clearLocalStorage(all?: boolean): void;
|
|
369
|
+
function clearSessionStorage(onlyTests?: boolean): void;
|
|
370
|
+
function clearTestsStorage(): void;
|
|
371
|
+
|
|
372
|
+
// Utilities
|
|
373
|
+
function camelToKebab(str: string): string;
|
|
374
|
+
function kebabToCamel(str: string): string;
|
|
375
|
+
function verify(pairs: Array<[unknown, string | string[]]>, safe?: boolean): boolean | Error;
|
|
376
|
+
function safeVerify(pairs: Array<[unknown, string | string[]]>): boolean;
|
|
377
|
+
const C: (obj: object, key: string) => boolean;
|
|
378
|
+
const F: false;
|
|
379
|
+
const U: undefined;
|
|
380
|
+
|
|
381
|
+
// Store adapters (always present, prod + dev)
|
|
382
|
+
function connectRedux<S = unknown>(
|
|
383
|
+
store: { getState(): S; subscribe(listener: () => void): () => void },
|
|
384
|
+
selector: (state: S) => unknown,
|
|
385
|
+
component: ObjsInstance,
|
|
386
|
+
state?: string
|
|
387
|
+
): () => void;
|
|
388
|
+
|
|
389
|
+
function connectMobX<T = unknown>(
|
|
390
|
+
mobx: { autorun(fn: () => void): () => void },
|
|
391
|
+
observable: T,
|
|
392
|
+
accessor: (obs: T) => unknown,
|
|
393
|
+
component: ObjsInstance,
|
|
394
|
+
state?: string
|
|
395
|
+
): () => void;
|
|
396
|
+
|
|
397
|
+
let ObjsContext: unknown;
|
|
398
|
+
|
|
399
|
+
function withReactContext<C = unknown>(
|
|
400
|
+
React: { useContext(ctx: unknown): C; useEffect(fn: () => void, deps: unknown[]): void },
|
|
401
|
+
Context: unknown,
|
|
402
|
+
selector: (value: C) => unknown,
|
|
403
|
+
component: ObjsInstance,
|
|
404
|
+
state?: string
|
|
405
|
+
): () => null;
|
|
406
|
+
|
|
407
|
+
// SSR
|
|
408
|
+
const DocumentMVP: {
|
|
409
|
+
createElement(tag: string): unknown;
|
|
410
|
+
addEventListener(): void;
|
|
411
|
+
parseElement(elem: unknown, outer?: boolean): string;
|
|
412
|
+
};
|
|
413
|
+
let D: Document | typeof DocumentMVP;
|
|
414
|
+
|
|
415
|
+
const recorder: {
|
|
416
|
+
active: boolean;
|
|
417
|
+
actions: RecordedAction[];
|
|
418
|
+
mocks: Recording['mocks'];
|
|
419
|
+
initialData: Record<string, unknown>;
|
|
420
|
+
assertions: Assertion[];
|
|
421
|
+
observeRoot: string | null;
|
|
422
|
+
strictCapture: RecordingStrictCapture | null;
|
|
423
|
+
_observer: MutationObserver | null;
|
|
424
|
+
};
|
|
425
|
+
/** Options object form for o.startRecording (observe/events/timeouts + optional strict capture flags on the recording) */
|
|
426
|
+
interface StartRecordingOptions {
|
|
427
|
+
observe?: string;
|
|
428
|
+
events?: string[];
|
|
429
|
+
timeouts?: Record<string, number>;
|
|
430
|
+
strictCaptureAssertions?: boolean;
|
|
431
|
+
strictCaptureNetwork?: boolean;
|
|
432
|
+
strictCaptureWebSocket?: boolean;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Start recording user interactions.
|
|
436
|
+
* Available in all builds — QA testers can record on staging/production.
|
|
437
|
+
*/
|
|
438
|
+
function startRecording(options: StartRecordingOptions): void;
|
|
439
|
+
/**
|
|
440
|
+
* @param observe CSS selector to scope the MutationObserver (reduces assertion noise)
|
|
441
|
+
* @param events Events to record (default: click, mouseover, scroll, input, change)
|
|
442
|
+
* @param timeouts Debounce delays per event type in ms
|
|
443
|
+
*/
|
|
444
|
+
function startRecording(observe?: string, events?: string[], timeouts?: Record<string, number>): void;
|
|
445
|
+
function stopRecording(): Recording;
|
|
446
|
+
function clearRecording(id?: number): void;
|
|
447
|
+
function exportTest(
|
|
448
|
+
recording: Recording,
|
|
449
|
+
options?: { delay?: number; extensionExport?: boolean },
|
|
450
|
+
): string;
|
|
451
|
+
/** Optional filters and strict modes for o.runRecordingAssertions */
|
|
452
|
+
interface RunRecordingAssertionsOpts {
|
|
453
|
+
assertions?: Assertion[];
|
|
454
|
+
removedElements?: Recording['removedElements'];
|
|
455
|
+
strictAssertions?: boolean;
|
|
456
|
+
/** When omitted, defaults to strictAssertions */
|
|
457
|
+
strictRemoved?: boolean;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Run recording assertions against the current DOM.
|
|
461
|
+
* @param recording Recording with assertions
|
|
462
|
+
* @param root Root element or selector (default: document)
|
|
463
|
+
* @param actionIdx When provided, run only assertions for this action index
|
|
464
|
+
* @param opts Optional assertion subset, removedElements, and strict DOM/removed flags
|
|
465
|
+
*/
|
|
466
|
+
function runRecordingAssertions(
|
|
467
|
+
recording: Recording,
|
|
468
|
+
root?: Element | string,
|
|
469
|
+
actionIdx?: number,
|
|
470
|
+
opts?: RunRecordingAssertionsOpts
|
|
471
|
+
): { passed: number; total: number; failures: Array<{ selector: string; message: string }> };
|
|
472
|
+
function exportPlaywrightTest(
|
|
473
|
+
recording: Recording,
|
|
474
|
+
options?: { testName?: string; baseUrl?: string }
|
|
475
|
+
): string;
|
|
476
|
+
|
|
477
|
+
// Test framework
|
|
478
|
+
function sleep(ms: number): Promise<void>;
|
|
479
|
+
let tLog: string[];
|
|
480
|
+
let tRes: boolean[];
|
|
481
|
+
let tStatus: Array<Array<boolean | undefined>>;
|
|
482
|
+
let tFns: Array<((testN: number) => void) | undefined>;
|
|
483
|
+
let tShowOk: boolean;
|
|
484
|
+
let tStyled: boolean;
|
|
485
|
+
let tTime: number;
|
|
486
|
+
let tests: Array<{ title: string; tests: TestCase[]; hooks: { before?: Function; after?: Function } }>;
|
|
487
|
+
let tAutolog: boolean;
|
|
488
|
+
let tBeforeEach: ((info: TestInfo) => void) | undefined;
|
|
489
|
+
let tAfterEach: ((info: TestInfo, result: unknown) => void) | undefined;
|
|
490
|
+
|
|
491
|
+
/** Options for o.test when sync or confirmOnFailure is needed */
|
|
492
|
+
interface TestOptions {
|
|
493
|
+
sync?: boolean;
|
|
494
|
+
confirmOnFailure?: boolean;
|
|
495
|
+
confirmOnFailureTimeout?: number;
|
|
496
|
+
}
|
|
497
|
+
function test(
|
|
498
|
+
title: string,
|
|
499
|
+
...cases: Array<TestCase | TestOptions | (() => void)>
|
|
500
|
+
): number;
|
|
501
|
+
function addTest(title: string, ...cases: Array<TestCase | { before?: Function; after?: Function }>): TestHandle;
|
|
502
|
+
function runTest(testId?: number, autoRun?: boolean, savePrev?: boolean): void;
|
|
503
|
+
function testUpdate(info: TestInfo, result?: boolean | string, suffix?: string): void;
|
|
504
|
+
function updateLogs(): string[];
|
|
505
|
+
|
|
506
|
+
// Measurements
|
|
507
|
+
function measure(el: Element): MeasureResult;
|
|
508
|
+
function assertVisible(el: Element): boolean;
|
|
509
|
+
/** Expected size/padding/margin for design system or UI verification. All values in px. */
|
|
510
|
+
function assertSize(
|
|
511
|
+
el: Element,
|
|
512
|
+
expected?: {
|
|
513
|
+
w?: number;
|
|
514
|
+
h?: number;
|
|
515
|
+
padding?: number;
|
|
516
|
+
paddingTop?: number;
|
|
517
|
+
paddingRight?: number;
|
|
518
|
+
paddingBottom?: number;
|
|
519
|
+
paddingLeft?: number;
|
|
520
|
+
margin?: number;
|
|
521
|
+
marginTop?: number;
|
|
522
|
+
marginRight?: number;
|
|
523
|
+
marginBottom?: number;
|
|
524
|
+
marginLeft?: number;
|
|
525
|
+
}
|
|
526
|
+
): boolean | string;
|
|
527
|
+
|
|
528
|
+
// Dev-only replay + overlay (depend on o.test framework)
|
|
529
|
+
/** Manual check inserted after an action or at end of playback */
|
|
530
|
+
interface ManualCheck {
|
|
531
|
+
afterAction: number | 'end';
|
|
532
|
+
label: string;
|
|
533
|
+
items: string[];
|
|
534
|
+
}
|
|
535
|
+
/** Options for o.playRecording when runAssertions is used */
|
|
536
|
+
interface PlayRecordingOptions {
|
|
537
|
+
runAssertions?: boolean;
|
|
538
|
+
root?: string;
|
|
539
|
+
actionDelay?: number;
|
|
540
|
+
manualChecks?: ManualCheck[];
|
|
541
|
+
mockOverrides?: Recording['mocks'];
|
|
542
|
+
skipWebSocketMock?: boolean;
|
|
543
|
+
skipNetworkMocks?: boolean;
|
|
544
|
+
recordingAssertionDebug?: boolean;
|
|
545
|
+
/** When true, enables strictAssertions, strictNetwork, and strictWebSocket (and strictRemoved follows strictAssertions). Per-flag opts still override when set. */
|
|
546
|
+
strictPlay?: boolean;
|
|
547
|
+
/** Exact list index, visible text equality (normalized), style/className equality, no list rescan */
|
|
548
|
+
strictAssertions?: boolean;
|
|
549
|
+
/** Require request body to match mock.request when replaying a mocked fetch/XHR */
|
|
550
|
+
strictNetwork?: boolean;
|
|
551
|
+
/** Require outbound WebSocket frames to match recorded order and payload */
|
|
552
|
+
strictWebSocket?: boolean;
|
|
553
|
+
/** When true, removed-element assertions verify absence instead of auto-pass */
|
|
554
|
+
strictRemoved?: boolean;
|
|
555
|
+
onComplete?: (assertionResult?: { passed: number; total: number; failures: Array<{ selector: string; message: string }> }) => void;
|
|
556
|
+
}
|
|
557
|
+
function playRecording(
|
|
558
|
+
recording: Recording,
|
|
559
|
+
opts?: Recording['mocks'] | PlayRecordingOptions
|
|
560
|
+
): number | { testId: number };
|
|
561
|
+
function testOverlay(): void;
|
|
562
|
+
/** Common draggable overlay; used by testConfirm, testOverlay, confirmOnFailure */
|
|
563
|
+
function overlay(opts: {
|
|
564
|
+
innerHTML: string;
|
|
565
|
+
onClose?: (result?: { ok?: boolean; errors?: string[]; continue?: boolean }) => void;
|
|
566
|
+
timeout?: number;
|
|
567
|
+
excludeDragSelector?: string;
|
|
568
|
+
removeExisting?: boolean;
|
|
569
|
+
className?: string;
|
|
570
|
+
id?: string;
|
|
571
|
+
}): ObjsInstance;
|
|
572
|
+
/**
|
|
573
|
+
* Pause an Objs browser test; shows a draggable bar with "Test title: Paused", optional checklist (labels + checkboxes), and Continue.
|
|
574
|
+
* Dev-only. Returns ok: true if all items checked; ok: false with errors = list of unchecked item texts.
|
|
575
|
+
*/
|
|
576
|
+
function testConfirm(
|
|
577
|
+
label: string,
|
|
578
|
+
items?: string[],
|
|
579
|
+
opts?: { confirm?: string; timeout?: number }
|
|
580
|
+
): Promise<{ ok: boolean; errors?: string[] }>;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
export { o };
|
|
584
|
+
export default o;
|