playthrough 0.5.1 → 0.6.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/INSTRUCTIONS.md +27 -5
- package/README.md +1 -1
- package/package.json +2 -2
- package/src/{flows-vi0amwSo.js → flows-CbrwgoHB.js} +43 -12
- package/src/playthrough.js +145 -84
- package/src/playwright.config.js +1 -1
- package/src/{reporter-S9fOk0za.js → reporter-DlS7qehW.js} +5 -1
- package/src/reporter.js +1 -1
- package/src/test.js +85 -67
- package/types/cli/src/flows.d.ts +21 -16
- package/types/cli/src/test.d.ts +21 -8
- package/types/page/src/found.d.ts +5 -0
- package/types/review/src/model.d.ts +40 -0
- package/types/review/src/rules.d.ts +4 -0
- package/viewer/assets/index-BbNKJRwK.css +2 -0
- package/viewer/assets/index-DwbSPQMk.js +194 -0
- package/viewer/index.html +2 -2
- package/viewer/assets/index-C4zcB6st.css +0 -2
- package/viewer/assets/index-D_6gdncQ.js +0 -194
package/src/test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as seconds, a as GLIMPSES, c as PERSON, d as RECORDING, f as WROTE, l as PICTURE, n as ASSETS, o as HANDS, p as firstLine, r as DONE_ON, s as HOLD, t as ACTIONS, u as READINGS, v as keepAssets } from "./reporter-
|
|
2
|
-
import { A as
|
|
1
|
+
import { _ as seconds, a as GLIMPSES, c as PERSON, d as RECORDING, f as WROTE, l as PICTURE, n as ASSETS, o as HANDS, p as firstLine, r as DONE_ON, s as HOLD, t as ACTIONS, u as READINGS, v as keepAssets } from "./reporter-DlS7qehW.js";
|
|
2
|
+
import { A as setupIn, E as firstOf, M as repo, O as make, T as changes, b as sameWords, k as personIn, n as FORK_RAN, r as REACHES_OUTSIDE, t as ALONGSIDE } from "./flows-CbrwgoHB.js";
|
|
3
3
|
import { n as readPage, r as unhovered } from "./read-Bg9XVTtn.js";
|
|
4
4
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
@@ -138,7 +138,7 @@ const recorded = test$1.extend({
|
|
|
138
138
|
rest: async ({ page }, use) => use(run ? await watchRest(page) : async () => {}),
|
|
139
139
|
setup: async ({ page, request, baseURL, person, rest: _ }, use, testInfo) => {
|
|
140
140
|
if (run?.only && !run.only.includes(testInfo.title)) testInfo.skip();
|
|
141
|
-
if (run?.
|
|
141
|
+
if (run?.fork && testInfo.title !== run.fork.flow) testInfo.skip();
|
|
142
142
|
const app = await setupOf();
|
|
143
143
|
if (person) personIn(app, person);
|
|
144
144
|
if (run) await readied(page, run);
|
|
@@ -176,7 +176,7 @@ const recorded = test$1.extend({
|
|
|
176
176
|
});
|
|
177
177
|
for (const context of opened) await context.close();
|
|
178
178
|
},
|
|
179
|
-
recorder: [async ({ page, setup, rest, person, handTo
|
|
179
|
+
recorder: [async ({ page, request, baseURL, setup, rest, person, handTo }, use, testInfo) => {
|
|
180
180
|
if (!run) return use();
|
|
181
181
|
testInfo.setTimeout(testInfo.timeout * 3);
|
|
182
182
|
const flow = {
|
|
@@ -191,7 +191,15 @@ const recorded = test$1.extend({
|
|
|
191
191
|
inStep: 0,
|
|
192
192
|
hands: [],
|
|
193
193
|
assets: [],
|
|
194
|
-
doneOn: {}
|
|
194
|
+
doneOn: {},
|
|
195
|
+
given: {
|
|
196
|
+
page,
|
|
197
|
+
context: page.context(),
|
|
198
|
+
request,
|
|
199
|
+
baseURL,
|
|
200
|
+
setup,
|
|
201
|
+
handTo
|
|
202
|
+
}
|
|
195
203
|
};
|
|
196
204
|
await page.exposeFunction("__playthrough", (event) => void (flow.page === page && flow.events.push(event)));
|
|
197
205
|
flow.assets.push(keepAssets(page, run.folder));
|
|
@@ -214,15 +222,20 @@ const recorded = test$1.extend({
|
|
|
214
222
|
}
|
|
215
223
|
const last = flow.page;
|
|
216
224
|
const assets = async () => Object.assign({}, ...await Promise.all(flow.assets.map((kept) => kept())));
|
|
217
|
-
if (run.
|
|
218
|
-
if (!flow.
|
|
225
|
+
if (run.fork) {
|
|
226
|
+
if (!flow.forked) return;
|
|
219
227
|
await last.waitForTimeout(HOLD);
|
|
220
228
|
await last.evaluate(() => window.rrwebRecord.record.addCustomEvent("end", {}));
|
|
221
229
|
await last.waitForTimeout(100);
|
|
222
|
-
|
|
223
|
-
|
|
230
|
+
writeFileSync(join(run.folder, "end.png"), await last.screenshot({
|
|
231
|
+
animations: "disabled",
|
|
232
|
+
caret: "hide"
|
|
233
|
+
}));
|
|
234
|
+
return writeFileSync(join(run.folder, FORK_RAN), JSON.stringify({
|
|
235
|
+
...flow.forked,
|
|
224
236
|
events,
|
|
225
237
|
readings,
|
|
238
|
+
glimpses,
|
|
226
239
|
assets: await assets()
|
|
227
240
|
}));
|
|
228
241
|
}
|
|
@@ -387,12 +400,17 @@ function answers(dialog) {
|
|
|
387
400
|
}
|
|
388
401
|
}
|
|
389
402
|
let collecting;
|
|
403
|
+
let collectingForks = [];
|
|
390
404
|
let around = [];
|
|
391
405
|
let loading = Promise.resolve();
|
|
392
406
|
function flowsIn(file, written) {
|
|
393
407
|
const flows = /* @__PURE__ */ new Map();
|
|
394
408
|
const loaded = loading.then(async () => {
|
|
395
|
-
[collecting, around] = [
|
|
409
|
+
[collecting, around, collectingForks] = [
|
|
410
|
+
flows,
|
|
411
|
+
[{ use: {} }],
|
|
412
|
+
[]
|
|
413
|
+
];
|
|
396
414
|
try {
|
|
397
415
|
await import(`${pathToFileURL(file).href}?${written}`);
|
|
398
416
|
} finally {
|
|
@@ -406,7 +424,7 @@ function flowsIn(file, written) {
|
|
|
406
424
|
const taking = new AsyncLocalStorage();
|
|
407
425
|
const holds = (flow) => !flow.wrote && flow.page.url() === flow.address;
|
|
408
426
|
var Stopped = class extends Error {};
|
|
409
|
-
async function runAlongside(page, { request, baseURL, started, setup: appSetup, borrowed, arrived, person }, body, orders) {
|
|
427
|
+
async function runAlongside(page, { request, baseURL, started, setup: appSetup, borrowed, arrived, person }, body, orders, forks = []) {
|
|
410
428
|
const readied = async (page) => {
|
|
411
429
|
const rest = await watchRest(page);
|
|
412
430
|
await page.clock.setSystemTime(onReviewDay(started));
|
|
@@ -420,6 +438,7 @@ async function runAlongside(page, { request, baseURL, started, setup: appSetup,
|
|
|
420
438
|
};
|
|
421
439
|
const flow = {
|
|
422
440
|
page,
|
|
441
|
+
forks,
|
|
423
442
|
depth: 0,
|
|
424
443
|
rest: async () => {},
|
|
425
444
|
actions: 0,
|
|
@@ -468,14 +487,15 @@ async function runAlongside(page, { request, baseURL, started, setup: appSetup,
|
|
|
468
487
|
person: who,
|
|
469
488
|
setup: made.setup
|
|
470
489
|
});
|
|
471
|
-
|
|
490
|
+
flow.given = {
|
|
472
491
|
page,
|
|
473
492
|
context: page.context(),
|
|
474
493
|
request,
|
|
475
494
|
baseURL,
|
|
476
495
|
setup: made.setup,
|
|
477
496
|
handTo
|
|
478
|
-
}
|
|
497
|
+
};
|
|
498
|
+
await body(flow.given);
|
|
479
499
|
await reached(flow);
|
|
480
500
|
return {
|
|
481
501
|
handed: flow.handed,
|
|
@@ -505,7 +525,7 @@ async function reached(flow, step, actions) {
|
|
|
505
525
|
if (stopped) throw new Stopped();
|
|
506
526
|
const where = against(flow.passed, step, actions, to);
|
|
507
527
|
if (where === "on") return;
|
|
508
|
-
if (where === "here" && to.rests) await handOver(flow, to
|
|
528
|
+
if (where === "here" && to.rests) await handOver(flow, to);
|
|
509
529
|
if (where === "past" || to.rests) {
|
|
510
530
|
if (step) throw new Stopped();
|
|
511
531
|
return;
|
|
@@ -547,9 +567,13 @@ async function kept(page, rest) {
|
|
|
547
567
|
clock: kept.clock - Date.now()
|
|
548
568
|
};
|
|
549
569
|
}
|
|
550
|
-
async function handOver(flow, did) {
|
|
551
|
-
const
|
|
552
|
-
if (
|
|
570
|
+
async function handOver(flow, { notes, did }) {
|
|
571
|
+
const fork = notes && flow.forks.find((fork) => fork.notes.some((note) => notes.includes(note)));
|
|
572
|
+
if (fork) {
|
|
573
|
+
flow.forking = true;
|
|
574
|
+
await fork.body(flow.given);
|
|
575
|
+
} else if (did?.length) {
|
|
576
|
+
const { page, rest } = flow;
|
|
553
577
|
await taking.exit(async () => {
|
|
554
578
|
for (const one of did) {
|
|
555
579
|
if (!await doAgain(page, one).then(() => true, () => false)) break;
|
|
@@ -559,6 +583,7 @@ async function handOver(flow, did) {
|
|
|
559
583
|
flow.handed = await kept(page, rest);
|
|
560
584
|
return;
|
|
561
585
|
}
|
|
586
|
+
const { page, rest, from, again } = flow;
|
|
562
587
|
flow.handed = from && again.length && holds(flow) ? {
|
|
563
588
|
...from,
|
|
564
589
|
again
|
|
@@ -576,6 +601,7 @@ const pathTo = (target) => target.evaluate((element) => {
|
|
|
576
601
|
const playwrightStep = test$1.step;
|
|
577
602
|
const step = Object.assign(async (title, body, options) => {
|
|
578
603
|
const taken = taking.getStore();
|
|
604
|
+
if (taken?.forking) return body(void 0);
|
|
579
605
|
if (taken) {
|
|
580
606
|
const own = !taken.depth;
|
|
581
607
|
if (own) Object.assign(taken, {
|
|
@@ -602,6 +628,10 @@ const step = Object.assign(async (title, body, options) => {
|
|
|
602
628
|
step: title,
|
|
603
629
|
inStep: 0
|
|
604
630
|
});
|
|
631
|
+
flow.forked?.steps.push({
|
|
632
|
+
title,
|
|
633
|
+
at: seconds(Date.now() - (flow.events[0]?.timestamp ?? Date.now()))
|
|
634
|
+
});
|
|
605
635
|
flow.depth++;
|
|
606
636
|
let done;
|
|
607
637
|
try {
|
|
@@ -625,7 +655,7 @@ const step = Object.assign(async (title, body, options) => {
|
|
|
625
655
|
caret: "hide"
|
|
626
656
|
}));
|
|
627
657
|
});
|
|
628
|
-
if (run?.
|
|
658
|
+
if (run?.fork?.step === title && run.fork.actions === void 0 && !flow.forked) await forkOn(flow, run.fork);
|
|
629
659
|
return done;
|
|
630
660
|
}, options);
|
|
631
661
|
}, playwrightStep);
|
|
@@ -642,8 +672,10 @@ const outsideIn = (details) => {
|
|
|
642
672
|
};
|
|
643
673
|
const keeping = Object.assign((title, ...rest) => {
|
|
644
674
|
const scopes = [...around];
|
|
675
|
+
const forks = collectingForks;
|
|
645
676
|
collecting?.set(title, {
|
|
646
677
|
body: rest.at(-1),
|
|
678
|
+
forks,
|
|
647
679
|
outside: (rest.length > 1 ? outsideIn(rest[0]) : void 0) ?? scopes.findLast((scope) => scope.outside)?.outside,
|
|
648
680
|
get use() {
|
|
649
681
|
return Object.assign({}, ...scopes.map((scope) => scope.use));
|
|
@@ -665,7 +697,17 @@ const keeping = Object.assign((title, ...rest) => {
|
|
|
665
697
|
},
|
|
666
698
|
extend: () => keeping
|
|
667
699
|
});
|
|
668
|
-
const
|
|
700
|
+
const forks = [];
|
|
701
|
+
const fork = (name, { notes }, body) => void forks.push({
|
|
702
|
+
name,
|
|
703
|
+
notes: notes.map(String),
|
|
704
|
+
body
|
|
705
|
+
});
|
|
706
|
+
const test = globalThis[ALONGSIDE] ? Object.assign(keeping, { fork: (name, { notes }, body) => void collectingForks.push({
|
|
707
|
+
name,
|
|
708
|
+
notes: notes.map(String),
|
|
709
|
+
body
|
|
710
|
+
}) }) : Object.assign(withSteps(recorded), { fork });
|
|
669
711
|
const actions = [
|
|
670
712
|
"click",
|
|
671
713
|
"dblclick",
|
|
@@ -740,7 +782,7 @@ function pace(page) {
|
|
|
740
782
|
}
|
|
741
783
|
async function acted(does, target, act, given) {
|
|
742
784
|
const taken = taking.getStore();
|
|
743
|
-
const keeping = taken?.depth ? taken : void 0;
|
|
785
|
+
const keeping = taken?.depth || taken?.forking ? taken : void 0;
|
|
744
786
|
let on, address;
|
|
745
787
|
if (keeping) {
|
|
746
788
|
if (!holds(keeping)) Object.assign(keeping, {
|
|
@@ -758,10 +800,10 @@ async function acted(does, target, act, given) {
|
|
|
758
800
|
await dialog;
|
|
759
801
|
});
|
|
760
802
|
underway?.actions.push(Date.now());
|
|
761
|
-
const
|
|
762
|
-
if (
|
|
803
|
+
const fork = run?.fork;
|
|
804
|
+
if (fork && underway?.depth && !underway.forked && fork.step === underway.step && fork.actions === ++underway.inStep) {
|
|
763
805
|
await underway.page.waitForTimeout(650);
|
|
764
|
-
await
|
|
806
|
+
await forkOn(underway, fork);
|
|
765
807
|
}
|
|
766
808
|
if (keeping) {
|
|
767
809
|
await keeping.page.waitForTimeout(SAVING);
|
|
@@ -776,7 +818,7 @@ async function acted(does, target, act, given) {
|
|
|
776
818
|
again: []
|
|
777
819
|
});
|
|
778
820
|
}
|
|
779
|
-
if (keeping) await reached(keeping, keeping.step, ++keeping.actions);
|
|
821
|
+
if (keeping && !keeping.forking) await reached(keeping, keeping.step, ++keeping.actions);
|
|
780
822
|
return result;
|
|
781
823
|
}
|
|
782
824
|
async function follow(flow, target) {
|
|
@@ -794,56 +836,32 @@ const doneOn = (target) => target.ariaSnapshot({ timeout: 1e3 }).then((snapshot)
|
|
|
794
836
|
} : void 0;
|
|
795
837
|
}, () => void 0);
|
|
796
838
|
function alike(one, other) {
|
|
797
|
-
|
|
798
|
-
const words = (name) => name.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
799
|
-
const [few, many] = [words(one.name), words(other.name)].sort((a, b) => a.length - b.length);
|
|
800
|
-
return !few.length || few.filter((word) => many.includes(word)).length * 2 >= few.length;
|
|
839
|
+
return one.role === other.role && sameWords(one.name, other.name);
|
|
801
840
|
}
|
|
802
|
-
async function
|
|
841
|
+
async function forkOn(flow, run) {
|
|
803
842
|
await flow.rest();
|
|
804
843
|
const since = () => seconds(Date.now() - (flow.events[0]?.timestamp ?? Date.now()));
|
|
805
|
-
const
|
|
844
|
+
const written = forks.find((fork) => fork.notes.some((note) => run.notes.includes(note)));
|
|
845
|
+
const ran = flow.forked = {
|
|
806
846
|
from: since(),
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
};
|
|
810
|
-
const look = async () => {
|
|
811
|
-
for (const [i, { after, css }] of walk.look.entries()) {
|
|
812
|
-
if (after !== walked.done.length) continue;
|
|
813
|
-
walked.found[i] = css ? await flow.page.evaluate((css) => {
|
|
814
|
-
const on = document.querySelector(css);
|
|
815
|
-
const node = on ? window.rrwebRecord.record.mirror.getId(on) : -1;
|
|
816
|
-
return node > 0 ? node : null;
|
|
817
|
-
}, css).catch(() => null) : null;
|
|
818
|
-
writeFileSync(join(run.folder, `look-${i}.png`), await flow.page.screenshot({
|
|
819
|
-
animations: "disabled",
|
|
820
|
-
caret: "hide"
|
|
821
|
-
}));
|
|
822
|
-
}
|
|
847
|
+
steps: [],
|
|
848
|
+
...written && { fork: written.name }
|
|
823
849
|
};
|
|
824
|
-
|
|
825
|
-
|
|
850
|
+
if (written) {
|
|
851
|
+
const depth = flow.depth;
|
|
852
|
+
flow.depth = 0;
|
|
826
853
|
try {
|
|
827
|
-
await
|
|
828
|
-
} catch {
|
|
829
|
-
|
|
830
|
-
|
|
854
|
+
await written.body(flow.given);
|
|
855
|
+
} catch (error) {
|
|
856
|
+
ran.failed = {
|
|
857
|
+
...ran.steps.length && { at: ran.steps.at(-1).title },
|
|
858
|
+
why: firstLine(String(error?.message ?? error))
|
|
859
|
+
};
|
|
860
|
+
} finally {
|
|
861
|
+
flow.depth = depth;
|
|
831
862
|
}
|
|
832
|
-
await flow.rest();
|
|
833
|
-
walked.done.push(since());
|
|
834
|
-
await unhovered(flow.page, async () => {
|
|
835
|
-
const { screen, things, items } = await readPage(flow.page);
|
|
836
|
-
flow.readings.push({
|
|
837
|
-
step: "In the app",
|
|
838
|
-
at: since(),
|
|
839
|
-
screen,
|
|
840
|
-
things,
|
|
841
|
-
items
|
|
842
|
-
});
|
|
843
|
-
});
|
|
844
|
-
await look();
|
|
845
863
|
}
|
|
846
|
-
test$1.info().skip(true, "
|
|
864
|
+
test$1.info().skip(true, "Ran as far as the note's fork");
|
|
847
865
|
}
|
|
848
866
|
async function doAgain(page, { does, on, with: given }) {
|
|
849
867
|
const target = page.locator(on).first();
|
|
@@ -862,7 +880,7 @@ async function doAgain(page, { does, on, with: given }) {
|
|
|
862
880
|
}
|
|
863
881
|
async function glimpse() {
|
|
864
882
|
const flow = underway;
|
|
865
|
-
if (!pointer || !flow || run?.
|
|
883
|
+
if (!pointer || !flow || run?.fork && !flow.forked) return;
|
|
866
884
|
const at = seconds(Date.now() - (flow.events[0]?.timestamp ?? Date.now()));
|
|
867
885
|
const read = await readPage(flow.page).catch(() => void 0);
|
|
868
886
|
if (read) flow.glimpses.push({
|
package/types/cli/src/flows.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Glimpse, Reading } from "../../page/src/index.js";
|
|
1
2
|
import { type Did, type Flow } from "../../review/src/index.js";
|
|
2
3
|
import { type Failed, type Written } from "./reporter.js";
|
|
3
4
|
import { type App, type Repo } from "./repo.js";
|
|
@@ -14,7 +15,7 @@ export type Run = {
|
|
|
14
15
|
before: boolean;
|
|
15
16
|
taken: string[];
|
|
16
17
|
started: string;
|
|
17
|
-
|
|
18
|
+
fork?: ForkRun;
|
|
18
19
|
doneInRound?: Record<string, DoneOn>;
|
|
19
20
|
};
|
|
20
21
|
export type On = {
|
|
@@ -22,29 +23,32 @@ export type On = {
|
|
|
22
23
|
name: string;
|
|
23
24
|
};
|
|
24
25
|
export type DoneOn = Record<string, (On | null)[]>;
|
|
25
|
-
export type
|
|
26
|
+
export type ForkRun = {
|
|
26
27
|
flow: string;
|
|
27
28
|
step: string;
|
|
28
29
|
actions?: number;
|
|
29
|
-
|
|
30
|
-
look: {
|
|
31
|
-
after: number;
|
|
32
|
-
css?: string;
|
|
33
|
-
}[];
|
|
30
|
+
notes: string[];
|
|
34
31
|
};
|
|
35
|
-
export type
|
|
32
|
+
export type ForkRan = {
|
|
36
33
|
from: number;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
fork?: string;
|
|
35
|
+
steps: {
|
|
36
|
+
title: string;
|
|
37
|
+
at: number;
|
|
38
|
+
}[];
|
|
39
|
+
failed?: {
|
|
40
|
+
at?: string;
|
|
41
|
+
why: string;
|
|
42
|
+
};
|
|
40
43
|
};
|
|
41
|
-
export declare const
|
|
44
|
+
export declare const FORK_RAN = "fork.json";
|
|
42
45
|
export type To = {
|
|
43
46
|
flow: string;
|
|
44
47
|
step?: string;
|
|
45
48
|
actions?: number;
|
|
46
49
|
rests?: boolean;
|
|
47
50
|
did?: Did[];
|
|
51
|
+
notes?: string[];
|
|
48
52
|
};
|
|
49
53
|
export type Handed = {
|
|
50
54
|
url: string;
|
|
@@ -110,17 +114,18 @@ export type Ran = {
|
|
|
110
114
|
failed: Failed[];
|
|
111
115
|
written: Record<string, Written>;
|
|
112
116
|
};
|
|
113
|
-
export type
|
|
117
|
+
export type ForkRecorded = ForkRan & {
|
|
114
118
|
events: {
|
|
115
119
|
timestamp: number;
|
|
116
120
|
}[];
|
|
117
|
-
readings:
|
|
121
|
+
readings: Reading[];
|
|
122
|
+
glimpses: Glimpse[];
|
|
118
123
|
assets: Record<string, string>;
|
|
119
124
|
files: {
|
|
120
125
|
name: string;
|
|
121
126
|
bytes: Buffer;
|
|
122
127
|
}[];
|
|
123
|
-
|
|
128
|
+
picture?: Buffer;
|
|
124
129
|
};
|
|
125
|
-
export declare function
|
|
130
|
+
export declare function runFork(repo: Repo, id: string, fork: ForkRun): Promise<ForkRecorded | undefined>;
|
|
126
131
|
export declare const failedAt: ({ flow, at, why }: Failed) => string;
|
package/types/cli/src/test.d.ts
CHANGED
|
@@ -8,6 +8,13 @@ export declare const tablet: Screen;
|
|
|
8
8
|
export declare const expect: import("@playwright/test").Expect<{}>;
|
|
9
9
|
export declare const onReviewDay: (started: string, now?: number) => Date;
|
|
10
10
|
export type HandTo = (person: string, screen?: Screen) => Promise<Page>;
|
|
11
|
+
declare const recorded: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & {
|
|
12
|
+
person: string | undefined;
|
|
13
|
+
rest: () => Promise<void>;
|
|
14
|
+
setup: Record<string, any>;
|
|
15
|
+
handTo: HandTo;
|
|
16
|
+
recorder: void;
|
|
17
|
+
}, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
|
|
11
18
|
export declare function pageFor(browser: Browser, baseURL: string, screen: Screen, use?: BrowserContextOptions): Promise<{
|
|
12
19
|
context: BrowserContext;
|
|
13
20
|
page: Page;
|
|
@@ -31,6 +38,7 @@ export type Kept = {
|
|
|
31
38
|
use: BrowserContextOptions & {
|
|
32
39
|
person?: string;
|
|
33
40
|
};
|
|
41
|
+
forks: Forked[];
|
|
34
42
|
};
|
|
35
43
|
export declare function flowsIn(file: string, written: number): Promise<Map<string, Kept>>;
|
|
36
44
|
export type Arrived = (step: string | undefined, actions: number | undefined, worked: number) => void;
|
|
@@ -42,15 +50,20 @@ export declare function runAlongside(page: Page, { request, baseURL, started, se
|
|
|
42
50
|
borrowed: string;
|
|
43
51
|
arrived?: Arrived;
|
|
44
52
|
person?: string;
|
|
45
|
-
}, body: Body, orders: Orders): Promise<{
|
|
53
|
+
}, body: Body, orders: Orders, forks?: Forked[]): Promise<{
|
|
46
54
|
handed?: Handed;
|
|
47
55
|
stopped?: Pick<Failed, "at" | "why">;
|
|
48
56
|
made?: Made;
|
|
49
57
|
}>;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
type Forked = {
|
|
59
|
+
name: string;
|
|
60
|
+
notes: string[];
|
|
61
|
+
body: Body;
|
|
62
|
+
};
|
|
63
|
+
declare const fork: (name: string, { notes }: {
|
|
64
|
+
notes: string[];
|
|
65
|
+
}, body: Body) => undefined;
|
|
66
|
+
export declare const test: typeof recorded & {
|
|
67
|
+
fork: typeof fork;
|
|
68
|
+
};
|
|
69
|
+
export {};
|
|
@@ -13,3 +13,8 @@ export declare const HOLDING: RegExp;
|
|
|
13
13
|
export declare const nearTo: (read: Glimpse[], at: number, point: Point) => Thing | undefined;
|
|
14
14
|
export declare function shownAt(readings: Reading[], element: Element, at: number): Shown | undefined;
|
|
15
15
|
export declare const elementOf: (thing: Thing, name: string) => Element;
|
|
16
|
+
export declare function sameWords(one: string, other: string): boolean;
|
|
17
|
+
export declare function firstShown(element: Element, seen: Glimpse[]): {
|
|
18
|
+
at: number;
|
|
19
|
+
element: Element;
|
|
20
|
+
} | undefined;
|
|
@@ -61,6 +61,10 @@ export declare const Place: z.ZodObject<{
|
|
|
61
61
|
}, z.core.$strict>>;
|
|
62
62
|
recording: z.ZodString;
|
|
63
63
|
length: z.ZodNumber;
|
|
64
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
65
|
+
title: z.ZodString;
|
|
66
|
+
at: z.ZodNumber;
|
|
67
|
+
}, z.core.$strict>>>;
|
|
64
68
|
}, z.core.$strict>>;
|
|
65
69
|
}, z.core.$strict>;
|
|
66
70
|
export declare const Step: z.ZodObject<{
|
|
@@ -128,6 +132,10 @@ export declare const Change: z.ZodObject<{
|
|
|
128
132
|
}, z.core.$strict>>;
|
|
129
133
|
recording: z.ZodString;
|
|
130
134
|
length: z.ZodNumber;
|
|
135
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
136
|
+
title: z.ZodString;
|
|
137
|
+
at: z.ZodNumber;
|
|
138
|
+
}, z.core.$strict>>>;
|
|
131
139
|
}, z.core.$strict>>;
|
|
132
140
|
}, z.core.$strict>>;
|
|
133
141
|
pictureOnly: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -179,6 +187,10 @@ export declare const Comparison: z.ZodObject<{
|
|
|
179
187
|
}, z.core.$strict>>;
|
|
180
188
|
recording: z.ZodString;
|
|
181
189
|
length: z.ZodNumber;
|
|
190
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
191
|
+
title: z.ZodString;
|
|
192
|
+
at: z.ZodNumber;
|
|
193
|
+
}, z.core.$strict>>>;
|
|
182
194
|
}, z.core.$strict>>;
|
|
183
195
|
}, z.core.$strict>>;
|
|
184
196
|
pictureOnly: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -233,6 +245,10 @@ export declare const Reply: z.ZodObject<{
|
|
|
233
245
|
}, z.core.$strict>>;
|
|
234
246
|
recording: z.ZodString;
|
|
235
247
|
length: z.ZodNumber;
|
|
248
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
249
|
+
title: z.ZodString;
|
|
250
|
+
at: z.ZodNumber;
|
|
251
|
+
}, z.core.$strict>>>;
|
|
236
252
|
}, z.core.$strict>>;
|
|
237
253
|
}, z.core.$strict>>;
|
|
238
254
|
watch: z.ZodOptional<z.ZodString>;
|
|
@@ -278,6 +294,10 @@ export declare const Note: z.ZodObject<{
|
|
|
278
294
|
}, z.core.$strict>>;
|
|
279
295
|
recording: z.ZodString;
|
|
280
296
|
length: z.ZodNumber;
|
|
297
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
298
|
+
title: z.ZodString;
|
|
299
|
+
at: z.ZodNumber;
|
|
300
|
+
}, z.core.$strict>>>;
|
|
281
301
|
}, z.core.$strict>>;
|
|
282
302
|
}, z.core.$strict>>;
|
|
283
303
|
words: z.ZodString;
|
|
@@ -342,6 +362,10 @@ export declare const Round: z.ZodObject<{
|
|
|
342
362
|
}, z.core.$strict>>;
|
|
343
363
|
recording: z.ZodString;
|
|
344
364
|
length: z.ZodNumber;
|
|
365
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
366
|
+
title: z.ZodString;
|
|
367
|
+
at: z.ZodNumber;
|
|
368
|
+
}, z.core.$strict>>>;
|
|
345
369
|
}, z.core.$strict>>;
|
|
346
370
|
}, z.core.$strict>>;
|
|
347
371
|
watch: z.ZodOptional<z.ZodString>;
|
|
@@ -411,6 +435,10 @@ export declare const Send: z.ZodObject<{
|
|
|
411
435
|
}, z.core.$strict>>;
|
|
412
436
|
recording: z.ZodString;
|
|
413
437
|
length: z.ZodNumber;
|
|
438
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
439
|
+
title: z.ZodString;
|
|
440
|
+
at: z.ZodNumber;
|
|
441
|
+
}, z.core.$strict>>>;
|
|
414
442
|
}, z.core.$strict>>;
|
|
415
443
|
}, z.core.$strict>>;
|
|
416
444
|
words: z.ZodString;
|
|
@@ -500,6 +528,10 @@ export declare const Review: z.ZodObject<{
|
|
|
500
528
|
}, z.core.$strict>>;
|
|
501
529
|
recording: z.ZodString;
|
|
502
530
|
length: z.ZodNumber;
|
|
531
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
532
|
+
title: z.ZodString;
|
|
533
|
+
at: z.ZodNumber;
|
|
534
|
+
}, z.core.$strict>>>;
|
|
503
535
|
}, z.core.$strict>>;
|
|
504
536
|
}, z.core.$strict>>;
|
|
505
537
|
watch: z.ZodOptional<z.ZodString>;
|
|
@@ -562,6 +594,10 @@ export declare const Review: z.ZodObject<{
|
|
|
562
594
|
}, z.core.$strict>>;
|
|
563
595
|
recording: z.ZodString;
|
|
564
596
|
length: z.ZodNumber;
|
|
597
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
598
|
+
title: z.ZodString;
|
|
599
|
+
at: z.ZodNumber;
|
|
600
|
+
}, z.core.$strict>>>;
|
|
565
601
|
}, z.core.$strict>>;
|
|
566
602
|
}, z.core.$strict>>;
|
|
567
603
|
pictureOnly: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -613,6 +649,10 @@ export declare const Review: z.ZodObject<{
|
|
|
613
649
|
}, z.core.$strict>>;
|
|
614
650
|
recording: z.ZodString;
|
|
615
651
|
length: z.ZodNumber;
|
|
652
|
+
steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
653
|
+
title: z.ZodString;
|
|
654
|
+
at: z.ZodNumber;
|
|
655
|
+
}, z.core.$strict>>>;
|
|
616
656
|
}, z.core.$strict>>;
|
|
617
657
|
}, z.core.$strict>>;
|
|
618
658
|
words: z.ZodString;
|