@melra/browser-runtime 0.3.0-alpha.10

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.
Files changed (71) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +44 -0
  3. package/dist/browser-connection.d.ts +25 -0
  4. package/dist/browser-connection.d.ts.map +1 -0
  5. package/dist/browser-connection.js +119 -0
  6. package/dist/browser-connection.js.map +1 -0
  7. package/dist/browser-connection.test.d.ts +2 -0
  8. package/dist/browser-connection.test.d.ts.map +1 -0
  9. package/dist/browser-connection.test.js +210 -0
  10. package/dist/browser-connection.test.js.map +1 -0
  11. package/dist/dialogs.test.d.ts +2 -0
  12. package/dist/dialogs.test.d.ts.map +1 -0
  13. package/dist/dialogs.test.js +165 -0
  14. package/dist/dialogs.test.js.map +1 -0
  15. package/dist/frames.test.d.ts +2 -0
  16. package/dist/frames.test.d.ts.map +1 -0
  17. package/dist/frames.test.js +157 -0
  18. package/dist/frames.test.js.map +1 -0
  19. package/dist/history-tabs.test.d.ts +2 -0
  20. package/dist/history-tabs.test.d.ts.map +1 -0
  21. package/dist/history-tabs.test.js +171 -0
  22. package/dist/history-tabs.test.js.map +1 -0
  23. package/dist/index.d.ts +169 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +939 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/input-fidelity.test.d.ts +2 -0
  28. package/dist/input-fidelity.test.d.ts.map +1 -0
  29. package/dist/input-fidelity.test.js +260 -0
  30. package/dist/input-fidelity.test.js.map +1 -0
  31. package/dist/network-policy.d.ts +28 -0
  32. package/dist/network-policy.d.ts.map +1 -0
  33. package/dist/network-policy.js +121 -0
  34. package/dist/network-policy.js.map +1 -0
  35. package/dist/network-policy.test.d.ts +2 -0
  36. package/dist/network-policy.test.d.ts.map +1 -0
  37. package/dist/network-policy.test.js +39 -0
  38. package/dist/network-policy.test.js.map +1 -0
  39. package/dist/pinning-proxy.d.ts +8 -0
  40. package/dist/pinning-proxy.d.ts.map +1 -0
  41. package/dist/pinning-proxy.js +115 -0
  42. package/dist/pinning-proxy.js.map +1 -0
  43. package/dist/pinning-proxy.test.d.ts +2 -0
  44. package/dist/pinning-proxy.test.d.ts.map +1 -0
  45. package/dist/pinning-proxy.test.js +80 -0
  46. package/dist/pinning-proxy.test.js.map +1 -0
  47. package/dist/popups-profile.test.d.ts +2 -0
  48. package/dist/popups-profile.test.d.ts.map +1 -0
  49. package/dist/popups-profile.test.js +170 -0
  50. package/dist/popups-profile.test.js.map +1 -0
  51. package/dist/see-act.test.d.ts +2 -0
  52. package/dist/see-act.test.d.ts.map +1 -0
  53. package/dist/see-act.test.js +152 -0
  54. package/dist/see-act.test.js.map +1 -0
  55. package/dist/selector.d.ts +30 -0
  56. package/dist/selector.d.ts.map +1 -0
  57. package/dist/selector.js +39 -0
  58. package/dist/selector.js.map +1 -0
  59. package/dist/selector.test.d.ts +2 -0
  60. package/dist/selector.test.d.ts.map +1 -0
  61. package/dist/selector.test.js +34 -0
  62. package/dist/selector.test.js.map +1 -0
  63. package/dist/stable-dom.d.ts +21 -0
  64. package/dist/stable-dom.d.ts.map +1 -0
  65. package/dist/stable-dom.js +76 -0
  66. package/dist/stable-dom.js.map +1 -0
  67. package/dist/stable-dom.test.d.ts +2 -0
  68. package/dist/stable-dom.test.d.ts.map +1 -0
  69. package/dist/stable-dom.test.js +22 -0
  70. package/dist/stable-dom.test.js.map +1 -0
  71. package/package.json +33 -0
@@ -0,0 +1,169 @@
1
+ import type { BrowserOperation } from "@melra/protocol";
2
+ import { type NetworkPolicy } from "./network-policy.js";
3
+ export interface BrowserRuntimeOptions extends NetworkPolicy {
4
+ artifactDirectory: string;
5
+ workspaceRoot: string;
6
+ executablePath?: string;
7
+ headless?: boolean;
8
+ cdpEndpoint?: string;
9
+ cdpContextIndex?: number;
10
+ recordHarPath?: string;
11
+ /**
12
+ * HTTP archive every request is answered from, instead of the network.
13
+ *
14
+ * A request the archive does not hold is aborted rather than fetched: a
15
+ * replay that quietly reaches the live web is not a replay, and the whole
16
+ * point is that the same task run twice sees the same bytes. Nothing leaves
17
+ * the machine while this is set, so the destination checks below never come
18
+ * up — a recording made against an allowed host stays replayable after the
19
+ * host is removed from the allowlist, because the host is no longer involved.
20
+ */
21
+ replayHarPath?: string;
22
+ /**
23
+ * Directory holding cookies, storage, and profile state between runs.
24
+ *
25
+ * Absent means a fresh throwaway profile per run, which is the safe default
26
+ * and also why a logged-in site had to be logged into again on every task.
27
+ */
28
+ userDataDir?: string;
29
+ /**
30
+ * What to do with a window the page opens itself.
31
+ *
32
+ * `"block"` closes it and reports it, which is the honest default for an
33
+ * unattended agent: a popup that steals focus is a page deciding what the
34
+ * caller looks at next. `"allow"` keeps it as an addressable tab.
35
+ */
36
+ popups?: "allow" | "block";
37
+ }
38
+ /**
39
+ * Name any human-verification widget embedded in the page.
40
+ *
41
+ * Returns nothing when the page is clear, so a normal snapshot is unchanged.
42
+ */
43
+ export declare function captchaReport(frameUrls: string[]): Record<string, unknown>;
44
+ export declare class BrowserRuntime {
45
+ private readonly options;
46
+ private browser;
47
+ private context;
48
+ private activePage;
49
+ private connection;
50
+ private proxy;
51
+ private routeHandler;
52
+ /**
53
+ * Dialogs raised by the action currently running, cleared by `execute`.
54
+ *
55
+ * One buffer on the runtime rather than one per page because the handler is
56
+ * registered on the context, and because operations execute one at a time —
57
+ * a task owns its runtime for the length of one action.
58
+ */
59
+ private dialogs;
60
+ /**
61
+ * Windows the page opened during the action currently running, same lifetime
62
+ * as `dialogs` and reported the same way.
63
+ */
64
+ private popups;
65
+ /** Pending closes of blocked popups, awaited before the action reports. */
66
+ private closing;
67
+ /** True only while `tab_new` is opening the tab the caller asked for. */
68
+ private openingTab;
69
+ constructor(options: BrowserRuntimeOptions);
70
+ private uploadPaths;
71
+ private ensureContext;
72
+ /**
73
+ * Opens a page MELRA asked for, not one the site opened by itself.
74
+ *
75
+ * The popup handler cannot tell the two apart — both arrive as a `page`
76
+ * event — so this flag is the difference, and it is held across exactly the
77
+ * await that emits the event.
78
+ */
79
+ private openPage;
80
+ private page;
81
+ /**
82
+ * The tab list, with the index each entry can be addressed by.
83
+ *
84
+ * Returned by every tab action rather than only by `tabs`, because opening,
85
+ * switching, and closing all renumber the list — a caller that had to issue a
86
+ * separate `tabs` call after each one would be acting on a stale index.
87
+ */
88
+ private describeTabs;
89
+ /**
90
+ * The frames a target may live in, main frame first.
91
+ *
92
+ * Consent banners, cookie walls, payment fields, and captcha widgets are
93
+ * almost always in an iframe, and `page.locator` only ever searched the main
94
+ * document — so the element an agent could plainly see in a screenshot was
95
+ * unaddressable, and the run died on an action timeout. Searching every frame
96
+ * with the main one first keeps precise callers unaffected and makes the
97
+ * embedded case work without a new field to pass.
98
+ *
99
+ * Ad and analytics pages can attach dozens of frames, so the list is bounded.
100
+ */
101
+ private frames;
102
+ /**
103
+ * Every way the caller gave us to find the element, in the order we trust
104
+ * them. Split out from `locator` because waiting and acting need the same
105
+ * list but disagree about what to do when nothing matches yet.
106
+ */
107
+ private candidates;
108
+ /**
109
+ * Resolve a target to a locator that actually matches something.
110
+ *
111
+ * Text matching used to be `exact: true` only, which fails on the whitespace,
112
+ * casing, and nested-markup differences that real pages are full of — a button
113
+ * rendered as `<button> Sign in </button>` never matched `"Sign in"`. Exact is
114
+ * still tried first so a precise caller keeps precise behaviour; the substring
115
+ * form is only consulted when exact found nothing.
116
+ *
117
+ * A target that matches nothing is reported as such instead of being handed to
118
+ * Playwright to fail as an opaque action timeout thirty seconds later.
119
+ */
120
+ private locator;
121
+ /**
122
+ * Wait for a target to reach a state, re-resolving it on every poll.
123
+ *
124
+ * Playwright's own `waitFor` is bound to one frame decided up front, which is
125
+ * exactly wrong here: the consent iframe or captcha widget being waited for
126
+ * usually does not exist yet when the wait starts. Re-reading `page.frames()`
127
+ * each round costs a poll interval of latency and covers the frame that
128
+ * appears halfway through.
129
+ *
130
+ * `visible` and `attached` are satisfied by any one candidate; `hidden` and
131
+ * `detached` must hold for all of them. Fanning out across frames makes that
132
+ * distinction load-bearing — most frames never contain the target, so "some
133
+ * candidate is absent" is true from the first poll and would report a banner
134
+ * as dismissed while it is still on screen.
135
+ */
136
+ private waitForTarget;
137
+ /**
138
+ * Type by pressing keys rather than by assigning the value.
139
+ *
140
+ * `.fill()` sets the field and fires a single `input` event. Anything that
141
+ * listens for keystrokes never sees the text: React inputs with key handlers,
142
+ * autocomplete dropdowns, comboboxes that filter as you type, and fields that
143
+ * enable a submit button only after a `keyup`. The old server used
144
+ * `page.type`, and losing that is most of why typing "stopped working".
145
+ * `.fill("")` is still how the field gets cleared, because it empties one
146
+ * reliably no matter what is in it.
147
+ */
148
+ private typeInto;
149
+ private snapshot;
150
+ /**
151
+ * Read one element rather than the whole page.
152
+ *
153
+ * The old server had `extract_text` and `extract_html`; both were dropped, so
154
+ * a caller wanting one table out of a large document had to take the entire
155
+ * page text and cut it up itself. `inspect` already accepts a target, so
156
+ * scoping it needs no new action.
157
+ */
158
+ private extract;
159
+ private settledSnapshot;
160
+ execute(operation: BrowserOperation): Promise<Record<string, unknown>>;
161
+ private run;
162
+ close(): Promise<void>;
163
+ }
164
+ export * from "./network-policy.js";
165
+ export * from "./pinning-proxy.js";
166
+ export * from "./selector.js";
167
+ export * from "./stable-dom.js";
168
+ export * from "./browser-connection.js";
169
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,iBAAiB,CAAC;AAKvE,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5B;AA6CD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiB1E;AAgGD,qBAAa,cAAc;IAyBb,OAAO,CAAC,QAAQ,CAAC,OAAO;IAxBpC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,YAAY,CAAgD;IACpE;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,CAAiC;IAChD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAiC;IAC/C,2EAA2E;IAC3E,OAAO,CAAC,OAAO,CAA0B;IACzC,yEAAyE;IACzE,OAAO,CAAC,UAAU,CAAS;gBAEE,OAAO,EAAE,qBAAqB;YAE7C,WAAW;YA8BX,aAAa;IA0J3B;;;;;;OAMG;YACW,QAAQ;YASR,IAAI;IASlB;;;;;;OAMG;YACW,YAAY;IAa1B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM;IAId;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAwBlB;;;;;;;;;;;OAWG;YACW,OAAO;IAarB;;;;;;;;;;;;;;OAcG;YACW,aAAa;IAsC3B;;;;;;;;;;OAUG;YACW,QAAQ;YAeR,QAAQ;IAwCtB;;;;;;;OAOG;YACW,OAAO;YAqBP,eAAe;IAcvB,OAAO,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAuB9D,GAAG;IAsTX,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CA0B7B;AAED,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC"}