waygraph 0.15.31 → 0.15.32
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/auto-session/session.js +2 -1
- package/dist/pilot-overlay/action-ring.d.ts +16 -0
- package/dist/pilot-overlay/action-ring.js +67 -0
- package/dist/pilot-overlay.d.ts +1 -0
- package/dist/pilot-overlay.js +1 -0
- package/dist/ui/components/ring.js +5 -0
- package/examples/saucedemo/.waygraph-auto/2c79c73a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2c94a05b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/37b56184.log +0 -0
- package/examples/saucedemo/.waygraph-auto/476cff76.log +0 -0
- package/examples/saucedemo/.waygraph-auto/535e8922.json +8 -0
- package/examples/saucedemo/.waygraph-auto/535e8922.log +0 -0
- package/examples/saucedemo/.waygraph-auto/73a41843.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8598b4c0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bf8693e7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f86224c6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fe83305d.log +0 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Split out of the former 1,078-line auto-session.ts (see src/ARCHITECTURE.md). Behavior unchanged.
|
|
2
2
|
import { CONSOLE_LOG_MAX_ENTRIES, FULL_MODE_DEFAULT_DEPTH, FULL_MODE_MAX_NODES, FULL_MODE_MAX_TEXT_LENGTH, TRACE_MAX_STEPS, buildSessionSnapshot, parsePick, stubFilePath, stubPhaseHasContent, walkFullDom } from "./helpers.js";
|
|
3
|
-
import { installPersistentPilotOverlay, showPilotActivity, showPilotFixtures, showPilotVision, updatePilotOverlay } from "../pilot-overlay.js";
|
|
3
|
+
import { instrumentPilotActions, installPersistentPilotOverlay, showPilotActivity, showPilotFixtures, showPilotVision, updatePilotOverlay } from "../pilot-overlay.js";
|
|
4
4
|
import { buildExploreContext, buildExploreMenu } from "../auto-explore.js";
|
|
5
5
|
import { MemPage } from "../mem-page.js";
|
|
6
6
|
import { Engine } from "../engine.js";
|
|
@@ -92,6 +92,7 @@ export class AutoSession {
|
|
|
92
92
|
const context = await browser.newContext(contextOpts);
|
|
93
93
|
await installPersistentPilotOverlay(context);
|
|
94
94
|
const page = await context.newPage();
|
|
95
|
+
instrumentPilotActions(page, headless ? 0 : 450);
|
|
95
96
|
if (startUrl) {
|
|
96
97
|
await page.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(() => { });
|
|
97
98
|
await page.waitForLoadState("load").catch(() => { });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Page } from "@playwright/test";
|
|
2
|
+
type Box = {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
};
|
|
8
|
+
/** Paint the gray "auto" ring (Playwright is about to act here) at a viewport rectangle. */
|
|
9
|
+
export declare function showPilotRect(page: Page, box: Box, label: string, tone?: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Every Playwright instruction a Block runs against this session's page gets a gray (auto) ring + robot
|
|
12
|
+
* label first, so a human watching a pilot window sees WHAT is being driven. `dwellMs` holds the ring
|
|
13
|
+
* long enough to read before the action fires (0 for headless).
|
|
14
|
+
*/
|
|
15
|
+
export declare function instrumentPilotActions(page: Page, dwellMs: number): void;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ensureInstalled } from "./shell.js";
|
|
2
|
+
/** Paint the gray "auto" ring (Playwright is about to act here) at a viewport rectangle. */
|
|
3
|
+
export async function showPilotRect(page, box, label, tone = "auto") {
|
|
4
|
+
await ensureInstalled(page);
|
|
5
|
+
await page
|
|
6
|
+
.evaluate(({ box, label, tone }) => {
|
|
7
|
+
const ring = __wgById("wg-ring");
|
|
8
|
+
const tag = __wgById("wg-ring-label");
|
|
9
|
+
if (!ring || !tag)
|
|
10
|
+
return;
|
|
11
|
+
const w = window;
|
|
12
|
+
if (w.__wgVisionHideTimer)
|
|
13
|
+
clearTimeout(w.__wgVisionHideTimer);
|
|
14
|
+
ring.dataset.tone = tone;
|
|
15
|
+
ring.dataset.size = "md";
|
|
16
|
+
tag.dataset.tone = tone;
|
|
17
|
+
tag.dataset.size = "md";
|
|
18
|
+
tag.dataset.weight = "normal";
|
|
19
|
+
ring.style.left = `${box.x - 3}px`;
|
|
20
|
+
ring.style.top = `${box.y - 3}px`;
|
|
21
|
+
ring.style.width = `${box.width + 6}px`;
|
|
22
|
+
ring.style.height = `${box.height + 6}px`;
|
|
23
|
+
tag.textContent = label;
|
|
24
|
+
tag.style.left = `${Math.max(0, box.x)}px`;
|
|
25
|
+
tag.style.top = `${Math.max(0, box.y - 24)}px`;
|
|
26
|
+
ring.style.opacity = "1";
|
|
27
|
+
tag.style.opacity = "1";
|
|
28
|
+
w.__wgVisionHideTimer = setTimeout(() => {
|
|
29
|
+
ring.style.opacity = "0";
|
|
30
|
+
tag.style.opacity = "0";
|
|
31
|
+
}, 4_000);
|
|
32
|
+
}, { box, label, tone })
|
|
33
|
+
.catch(() => { });
|
|
34
|
+
}
|
|
35
|
+
const LOCATOR_ACTIONS = ["click", "dblclick", "hover", "tap", "fill", "check", "uncheck", "selectOption", "press", "pressSequentially", "setInputFiles"];
|
|
36
|
+
const patched = new WeakSet();
|
|
37
|
+
/**
|
|
38
|
+
* Every Playwright instruction a Block runs against this session's page gets a gray (auto) ring + robot
|
|
39
|
+
* label first, so a human watching a pilot window sees WHAT is being driven. `dwellMs` holds the ring
|
|
40
|
+
* long enough to read before the action fires (0 for headless).
|
|
41
|
+
*/
|
|
42
|
+
export function instrumentPilotActions(page, dwellMs) {
|
|
43
|
+
const proto = Object.getPrototypeOf(page.locator("html"));
|
|
44
|
+
if (patched.has(proto))
|
|
45
|
+
return;
|
|
46
|
+
patched.add(proto);
|
|
47
|
+
for (const action of LOCATOR_ACTIONS) {
|
|
48
|
+
const original = proto[action];
|
|
49
|
+
if (typeof original !== "function")
|
|
50
|
+
continue;
|
|
51
|
+
proto[action] = async function (...args) {
|
|
52
|
+
try {
|
|
53
|
+
const box = await this.first().boundingBox({ timeout: 1_500 });
|
|
54
|
+
if (box) {
|
|
55
|
+
const desc = String(this).replace(/^locator\(['"]?|['"]?\)$/g, "").slice(0, 60);
|
|
56
|
+
await showPilotRect(this.page(), box, `${action} ${desc}`);
|
|
57
|
+
if (dwellMs > 0)
|
|
58
|
+
await this.page().waitForTimeout(dwellMs);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
/* decoration only - never block the real action */
|
|
63
|
+
}
|
|
64
|
+
return original.apply(this, args);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
package/dist/pilot-overlay.d.ts
CHANGED
package/dist/pilot-overlay.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { TONES } from "../tokens.js";
|
|
2
|
+
/** Prefix icon for gray (auto) labels. */
|
|
3
|
+
const ROBOT = 'content:"\\1F916\\00a0";';
|
|
2
4
|
const toneNames = Object.keys(TONES);
|
|
3
5
|
/** Tone rules for `sel[data-tone=x]{...}` from the token table. */
|
|
4
6
|
function toneRules(sel, decl, only) {
|
|
@@ -17,6 +19,8 @@ export function ringCss() {
|
|
|
17
19
|
`max-width:min(360px,70vw);white-space:normal;padding:6px 10px;border-radius:7px;background:${p.labelBg};color:${p.labelFg};` +
|
|
18
20
|
"font:600 12px/1.35 system-ui,sans-serif;transition:opacity .3s ease;}" +
|
|
19
21
|
toneRules("#wg-ring-label", (t) => `background:${t.labelBg};color:${t.labelFg};`) +
|
|
22
|
+
// Gray = a real Playwright-driven instruction: mark it with a robot.
|
|
23
|
+
`#wg-ring-label[data-tone=auto]::before{${ROBOT}}` +
|
|
20
24
|
"#wg-ring[data-size=sm]{border-width:1.5px;border-radius:8px;}" +
|
|
21
25
|
"#wg-ring[data-size=lg]{border-width:4px;border-radius:12px;}" +
|
|
22
26
|
"#wg-ring-label[data-size=sm]{font-size:10px;line-height:1.25;padding:4px 7px;border-radius:5px;}" +
|
|
@@ -36,6 +40,7 @@ export function pilotFxRingCss() {
|
|
|
36
40
|
"max-width:min(360px,80vw);box-shadow:0 2px 8px rgba(0,0,0,.25);white-space:nowrap;" +
|
|
37
41
|
"overflow:hidden;text-overflow:ellipsis;transition:opacity .12s ease;}" +
|
|
38
42
|
toneRules(".wg-pilot-fx-label", (t) => `background:${t.labelBg};color:${t.labelFg};`) +
|
|
43
|
+
`.wg-pilot-fx-label[data-tone=auto]::before{${ROBOT}}` +
|
|
39
44
|
".wg-pilot-fx-ring[data-size=sm]{border-width:1.5px;border-radius:8px;}" +
|
|
40
45
|
".wg-pilot-fx-ring[data-size=lg]{border-width:4px;border-radius:12px;}" +
|
|
41
46
|
".wg-pilot-fx-label[data-size=sm]{font-size:10px;padding:4px 7px;}" +
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|