@nextclaw/x-harness 0.1.1 → 0.2.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/LICENSE +231 -6
- package/README.md +15 -1
- package/SOURCE.md +9 -0
- package/cli/main.js +232 -200
- package/dist/api.d.ts +56 -2
- package/dist/api.js +130 -79
- package/dist/boundary.js +1 -0
- package/dist/browser-common.d.ts +11 -0
- package/dist/browser-common.js +34 -18
- package/dist/browser-dom-capabilities.d.ts +7 -2
- package/dist/browser-dom-capabilities.js +123 -102
- package/dist/browser-dom-dependencies.js +1 -0
- package/dist/browser-dom-editing.d.ts +20 -2
- package/dist/browser-dom-editing.js +148 -116
- package/dist/browser-dom-navigation.d.ts +11 -2
- package/dist/browser-dom-navigation.js +66 -50
- package/dist/browser-dom-submission.d.ts +6 -1
- package/dist/browser-dom-submission.js +37 -18
- package/dist/browser-dom.d.ts +13 -1
- package/dist/browser-dom.js +113 -66
- package/dist/browser-native.d.ts +14 -1
- package/dist/browser-native.js +161 -128
- package/dist/creator-native.d.ts +3 -0
- package/dist/creator-native.js +113 -0
- package/dist/diagnostics.d.ts +11 -0
- package/dist/diagnostics.js +10 -0
- package/dist/growth-batch.d.ts +6 -3
- package/dist/growth-batch.js +157 -135
- package/dist/growth-dependencies.js +1 -0
- package/dist/growth-execution.d.ts +8 -2
- package/dist/growth-execution.js +68 -37
- package/dist/growth-parallel.d.ts +6 -2
- package/dist/growth-parallel.js +78 -47
- package/dist/growth-plan.d.ts +8 -3
- package/dist/growth-plan.js +45 -23
- package/dist/growth-policy.d.ts +11 -2
- package/dist/growth-policy.js +80 -53
- package/dist/growth-publishing.d.ts +7 -2
- package/dist/growth-publishing.js +72 -46
- package/dist/growth-reading.d.ts +6 -2
- package/dist/growth-reading.js +47 -25
- package/dist/growth-recovery.d.ts +7 -4
- package/dist/growth-recovery.js +177 -148
- package/dist/growth-state.d.ts +10 -2
- package/dist/growth-state.js +67 -30
- package/dist/growth-tasks.d.ts +19 -16
- package/dist/growth-tasks.js +153 -90
- package/dist/growth.d.ts +25 -1
- package/dist/growth.js +207 -124
- package/dist/platform-capabilities.d.ts +6 -2
- package/dist/platform-capabilities.js +18 -8
- package/dist/platform-collections.d.ts +10 -3
- package/dist/platform-collections.js +62 -35
- package/dist/platform-dependencies.js +1 -0
- package/dist/platform-diagnostics.d.ts +7 -2
- package/dist/platform-diagnostics.js +31 -19
- package/dist/platform-observation.d.ts +10 -2
- package/dist/platform-observation.js +44 -23
- package/dist/platform-targets.d.ts +10 -3
- package/dist/platform-targets.js +39 -14
- package/dist/platform-writing.d.ts +10 -2
- package/dist/platform-writing.js +63 -32
- package/dist/platform.d.ts +22 -1
- package/dist/platform.js +120 -52
- package/dist/readers-ax-host.d.ts +11 -1
- package/dist/readers-ax-host.js +108 -99
- package/dist/readers-ax-program.js +5 -0
- package/dist/readers-ax-tree.js +1 -0
- package/dist/readers-cli.js +79 -0
- package/dist/readers.js +9 -0
- package/dist/round-state.js +18 -1
- package/dist/store.d.ts +22 -4
- package/dist/store.js +173 -151
- package/dist/types.js +1 -0
- package/generated/observation.mjs +1 -1
- package/package.json +23 -9
- package/skill/SKILL.md +2 -2
- package/skill/references/reads.md +1 -1
- package/skill/references/recovery.md +4 -4
- package/skill/references/setup.md +1 -1
package/dist/api.js
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import { createGrowthHarness } from "./growth.js";
|
|
2
2
|
import { readResult, decisions, diagnostic, stableReason } from "./results.js";
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
export class BusinessHarness {
|
|
4
|
+
#store;
|
|
5
|
+
#core;
|
|
6
|
+
#readCache;
|
|
7
|
+
constructor(dependencies) {
|
|
8
|
+
this.verifyFollow = this.verifyFollow.bind(this);
|
|
9
|
+
this.followBatch = this.followBatch.bind(this);
|
|
10
|
+
this.verifyPublishedPost = this.verifyPublishedPost.bind(this);
|
|
11
|
+
this.verifySubmission = this.verifySubmission.bind(this);
|
|
12
|
+
this.followOne = this.followOne.bind(this);
|
|
13
|
+
this.replyToPost = this.replyToPost.bind(this);
|
|
14
|
+
this.publishPost = this.publishPost.bind(this);
|
|
15
|
+
this.runGrowthRound = this.runGrowthRound.bind(this);
|
|
16
|
+
this.inspectRound = this.inspectRound.bind(this);
|
|
17
|
+
this.inspectAccount = this.inspectAccount.bind(this);
|
|
18
|
+
this.readFeedback = this.readFeedback.bind(this);
|
|
19
|
+
this.readPerson = this.readPerson.bind(this);
|
|
20
|
+
this.readPost = this.readPost.bind(this);
|
|
21
|
+
this.searchSources = this.searchSources.bind(this);
|
|
22
|
+
this.readBookmarks = this.readBookmarks.bind(this);
|
|
23
|
+
this.readCreator = this.readCreator.bind(this);
|
|
24
|
+
const { store } = dependencies;
|
|
25
|
+
this.#store = store;
|
|
26
|
+
this.#core = createGrowthHarness(dependencies);
|
|
27
|
+
this.#readCache = new Map();
|
|
28
|
+
}
|
|
29
|
+
async invoke(operation, args) {
|
|
9
30
|
try {
|
|
10
|
-
const raw = await core[operation](args);
|
|
31
|
+
const raw = await this.#core[operation](args);
|
|
11
32
|
// Legacy core decisions can contain a human error without a diagnostic proof.
|
|
12
33
|
// Expose a bounded recovery route; consumers never need implementation source.
|
|
13
34
|
const errors = [
|
|
@@ -18,7 +39,7 @@ export function createBusinessHarness(dependencies) {
|
|
|
18
39
|
]),
|
|
19
40
|
].filter((reason) => typeof reason === "string" && stableReason(reason) !== reason);
|
|
20
41
|
if (errors.length) {
|
|
21
|
-
const evidenceRef = await store.recordProof({
|
|
42
|
+
const evidenceRef = await this.#store.recordProof({
|
|
22
43
|
operation,
|
|
23
44
|
error: errors[0],
|
|
24
45
|
...(errors.length > 1 ? { errors } : {}),
|
|
@@ -50,7 +71,10 @@ export function createBusinessHarness(dependencies) {
|
|
|
50
71
|
const message = error instanceof Error ? error.message : String(error);
|
|
51
72
|
let evidenceRef;
|
|
52
73
|
try {
|
|
53
|
-
evidenceRef = await store.recordProof({
|
|
74
|
+
evidenceRef = await this.#store.recordProof({
|
|
75
|
+
operation,
|
|
76
|
+
error: message,
|
|
77
|
+
});
|
|
54
78
|
}
|
|
55
79
|
catch {
|
|
56
80
|
/* Evidence failure is explicit below. */
|
|
@@ -78,7 +102,7 @@ export function createBusinessHarness(dependencies) {
|
|
|
78
102
|
};
|
|
79
103
|
}
|
|
80
104
|
}
|
|
81
|
-
async
|
|
105
|
+
async read(operation, args = {}, mode = "receipt") {
|
|
82
106
|
if (!["receipt", "decision", "delta"].includes(mode))
|
|
83
107
|
return {
|
|
84
108
|
status: "needsDecision",
|
|
@@ -86,7 +110,7 @@ export function createBusinessHarness(dependencies) {
|
|
|
86
110
|
reason: "read-mode-invalid",
|
|
87
111
|
};
|
|
88
112
|
// Always collect fresh evidence once. Projection, not a second browser call, chooses output.
|
|
89
|
-
const raw = await invoke(operation, { ...args, mode: "decision" });
|
|
113
|
+
const raw = await this.invoke(operation, { ...args, mode: "decision" });
|
|
90
114
|
const output = readResult(operation, raw, mode);
|
|
91
115
|
if (mode === "receipt")
|
|
92
116
|
return output;
|
|
@@ -101,11 +125,11 @@ export function createBusinessHarness(dependencies) {
|
|
|
101
125
|
continue;
|
|
102
126
|
}
|
|
103
127
|
const key = JSON.stringify([operation, id]), value = JSON.stringify(entry);
|
|
104
|
-
if (readCache.get(key) === value)
|
|
128
|
+
if (this.#readCache.get(key) === value)
|
|
105
129
|
unchangedIds.push(id);
|
|
106
130
|
else
|
|
107
131
|
changed.push(entry);
|
|
108
|
-
readCache.set(key, value);
|
|
132
|
+
this.#readCache.set(key, value);
|
|
109
133
|
}
|
|
110
134
|
// Creator metadata changes independently from the post collection.
|
|
111
135
|
if (operation === "readCreator") {
|
|
@@ -114,9 +138,9 @@ export function createBusinessHarness(dependencies) {
|
|
|
114
138
|
continue;
|
|
115
139
|
const key = JSON.stringify([operation, name, args.handle]);
|
|
116
140
|
const value = JSON.stringify(output[name], (k, v) => k === "observedAt" ? undefined : v);
|
|
117
|
-
if (mode === "delta" && readCache.get(key) === value)
|
|
141
|
+
if (mode === "delta" && this.#readCache.get(key) === value)
|
|
118
142
|
delete output[name];
|
|
119
|
-
readCache.set(key, value);
|
|
143
|
+
this.#readCache.set(key, value);
|
|
120
144
|
}
|
|
121
145
|
}
|
|
122
146
|
// A decision has delivered complete evidence and seeds the next delta.
|
|
@@ -133,8 +157,8 @@ export function createBusinessHarness(dependencies) {
|
|
|
133
157
|
output.unchangedIds = unchangedIds;
|
|
134
158
|
return output;
|
|
135
159
|
}
|
|
136
|
-
async
|
|
137
|
-
const raw = await invoke(operation, args);
|
|
160
|
+
async compactRound(operation, args) {
|
|
161
|
+
const raw = await this.invoke(operation, args);
|
|
138
162
|
const out = {
|
|
139
163
|
status: raw.status,
|
|
140
164
|
taskId: args.taskId,
|
|
@@ -181,11 +205,11 @@ export function createBusinessHarness(dependencies) {
|
|
|
181
205
|
};
|
|
182
206
|
return out;
|
|
183
207
|
}
|
|
184
|
-
async
|
|
185
|
-
const raw = await invoke(operation, args);
|
|
208
|
+
async single(operation, args, selector) {
|
|
209
|
+
const raw = await this.invoke(operation, args);
|
|
186
210
|
let snapshot;
|
|
187
211
|
try {
|
|
188
|
-
snapshot = await store.load();
|
|
212
|
+
snapshot = await this.#store.load();
|
|
189
213
|
}
|
|
190
214
|
catch {
|
|
191
215
|
return {
|
|
@@ -246,63 +270,90 @@ export function createBusinessHarness(dependencies) {
|
|
|
246
270
|
out.diagnostic = d;
|
|
247
271
|
return out;
|
|
248
272
|
}
|
|
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
|
-
|
|
273
|
+
readCreator(args) {
|
|
274
|
+
return this.read("readCreator", args, args.mode);
|
|
275
|
+
}
|
|
276
|
+
readBookmarks(args) {
|
|
277
|
+
return this.read("readBookmarks", args, args.mode);
|
|
278
|
+
}
|
|
279
|
+
searchSources(args) {
|
|
280
|
+
return this.read("searchSources", args, args.mode);
|
|
281
|
+
}
|
|
282
|
+
readPost({ target, mode, }) {
|
|
283
|
+
return this.read("readPost", target, mode);
|
|
284
|
+
}
|
|
285
|
+
readPerson({ target, mode, }) {
|
|
286
|
+
return this.read("readPerson", target, mode);
|
|
287
|
+
}
|
|
288
|
+
readFeedback(args) {
|
|
289
|
+
return this.read("readFeedback", args, args.mode);
|
|
290
|
+
}
|
|
291
|
+
inspectAccount(args = {}) {
|
|
292
|
+
return this.read("inspectAccount", args, args.mode);
|
|
293
|
+
}
|
|
294
|
+
inspectRound(args) {
|
|
295
|
+
return this.compactRound("inspectRound", args);
|
|
296
|
+
}
|
|
297
|
+
runGrowthRound(args) {
|
|
298
|
+
return this.compactRound("runGrowthRound", args);
|
|
299
|
+
}
|
|
300
|
+
publishPost(args) {
|
|
301
|
+
return this.single("publishPost", args, (a) => a.kind === "original" && a.draftPath === args.draftPath);
|
|
302
|
+
}
|
|
303
|
+
replyToPost(args) {
|
|
304
|
+
return this.single("replyToPost", args, (a) => a.kind === "reply" && a.postId === args.postId && a.text === args.text);
|
|
305
|
+
}
|
|
306
|
+
followOne(args) {
|
|
307
|
+
return this.single("followOne", args, (a) => a.kind === "follow" &&
|
|
308
|
+
a.handle?.toLowerCase() === args.handle.toLowerCase());
|
|
309
|
+
}
|
|
310
|
+
verifySubmission(args) {
|
|
311
|
+
return this.single("verifySubmission", args, (a) => a.id === args.actionId);
|
|
312
|
+
}
|
|
313
|
+
verifyPublishedPost(args) {
|
|
314
|
+
return this.single("verifyPublishedPost", args, (a) => a.kind === "original" && a.draftPath === args.draftPath);
|
|
315
|
+
}
|
|
316
|
+
async followBatch(args) {
|
|
317
|
+
const raw = await this.invoke("followBatch", args);
|
|
318
|
+
const output = {
|
|
319
|
+
status: raw.status ?? (raw.mayEnd ? "verified" : "needsDecision"),
|
|
320
|
+
taskId: args.taskId,
|
|
321
|
+
planned: raw.planned ?? args.handles.length,
|
|
322
|
+
attempted: raw.attempted ?? 0,
|
|
323
|
+
verified: raw.verifiedThisCall ?? 0,
|
|
324
|
+
unknown: raw.unknownInBatch ?? 0,
|
|
325
|
+
remaining: raw.remaining ?? args.handles.length,
|
|
326
|
+
mayEnd: raw.mayEnd === true,
|
|
327
|
+
};
|
|
328
|
+
if (raw.batchId)
|
|
329
|
+
output.batchId = raw.batchId;
|
|
330
|
+
if (raw.evidenceRef)
|
|
331
|
+
output.evidenceRef = raw.evidenceRef;
|
|
332
|
+
const d = diagnostic(raw.diagnostic);
|
|
333
|
+
if (d)
|
|
334
|
+
output.diagnostic = d;
|
|
335
|
+
const issues = decisions(raw.decision);
|
|
336
|
+
if (raw.reason)
|
|
337
|
+
issues.push({ reason: raw.reason, status: "needsDecision" });
|
|
338
|
+
if (raw.missing)
|
|
339
|
+
issues.push({ missing: raw.missing });
|
|
340
|
+
if (issues.length)
|
|
341
|
+
output.decision = issues;
|
|
342
|
+
return output;
|
|
343
|
+
}
|
|
344
|
+
async verifyFollow(args) {
|
|
345
|
+
const raw = await this.invoke("verifyFollow", {
|
|
346
|
+
...args,
|
|
347
|
+
mode: args.mode ?? "receipt",
|
|
348
|
+
});
|
|
349
|
+
const out = readResult("verifyFollow", raw, "receipt");
|
|
350
|
+
out.handle = args.handle;
|
|
351
|
+
out.verified = raw.verified === true;
|
|
352
|
+
if (args.mode === "decision" && raw.observation)
|
|
353
|
+
out.person = readResult("readPerson", raw.observation, "decision").person;
|
|
354
|
+
return out;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
export function createBusinessHarness(...args) {
|
|
358
|
+
return new BusinessHarness(...args);
|
|
308
359
|
}
|
package/dist/boundary.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/browser-common.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export declare const plain: (label: any) => any;
|
|
2
2
|
export declare const valueOf: (label: any) => any;
|
|
3
3
|
export declare const missingMethods: (object: any, names: any) => any;
|
|
4
|
+
/** One instance owns one browser session and its concurrency boundary. */
|
|
5
|
+
export declare class SerializedBrowser {
|
|
6
|
+
#private;
|
|
7
|
+
collectCreator?: (args: unknown) => Promise<any>;
|
|
8
|
+
constructor(port: any);
|
|
9
|
+
private run;
|
|
10
|
+
observe(query: any): Promise<any>;
|
|
11
|
+
act(command: any): Promise<any>;
|
|
12
|
+
screenshot(): Promise<any>;
|
|
13
|
+
private collect;
|
|
14
|
+
}
|
|
4
15
|
export declare function serialized(port: any): any;
|
package/dist/browser-common.js
CHANGED
|
@@ -1,29 +1,45 @@
|
|
|
1
1
|
export const plain = (label) => label.replace(/^(?:按钮|link|文本输入区域|文本输入区|文本区域|文本栏) /, "");
|
|
2
2
|
export const valueOf = (label) => label.match(/, Value: ([\s\S]*)$/)?.[1] ?? null;
|
|
3
3
|
export const missingMethods = (object, names) => names.filter((name) => typeof object?.[name] !== "function");
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/** One instance owns one browser session and its concurrency boundary. */
|
|
5
|
+
export class SerializedBrowser {
|
|
6
|
+
#busy = false;
|
|
7
|
+
#port;
|
|
8
|
+
collectCreator;
|
|
9
|
+
constructor(port) {
|
|
10
|
+
this.#port = port;
|
|
11
|
+
Object.assign(this, port);
|
|
12
|
+
this.observe = SerializedBrowser.prototype.observe.bind(this);
|
|
13
|
+
this.act = SerializedBrowser.prototype.act.bind(this);
|
|
14
|
+
this.screenshot = SerializedBrowser.prototype.screenshot.bind(this);
|
|
15
|
+
if (port.collectCreator)
|
|
16
|
+
this.collectCreator = this.collect.bind(this);
|
|
17
|
+
}
|
|
18
|
+
async run(fn) {
|
|
19
|
+
if (this.#busy)
|
|
8
20
|
throw new Error("浏览器harness操作进行中,禁止并发");
|
|
9
|
-
busy = true;
|
|
21
|
+
this.#busy = true;
|
|
10
22
|
try {
|
|
11
23
|
return await fn();
|
|
12
24
|
}
|
|
13
25
|
finally {
|
|
14
|
-
busy = false;
|
|
26
|
+
this.#busy = false;
|
|
15
27
|
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
}
|
|
29
|
+
observe(query) {
|
|
30
|
+
return this.run(() => this.#port.observe(query));
|
|
31
|
+
}
|
|
32
|
+
act(command) {
|
|
33
|
+
return this.run(() => this.#port.act(command));
|
|
34
|
+
}
|
|
35
|
+
screenshot() {
|
|
36
|
+
return this.run(() => this.#port.screenshot());
|
|
37
|
+
}
|
|
38
|
+
collect(args) {
|
|
39
|
+
return this.run(() => this.#port.collectCreator(args));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function serialized(port) {
|
|
43
|
+
return new SerializedBrowser(port);
|
|
28
44
|
}
|
|
29
45
|
// AX indices never cross this port. Only semantic commands reach the platform layer.
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { DOMDependencies } from "./browser-dom-dependencies.js";
|
|
2
|
-
export declare
|
|
2
|
+
export declare class DOMCapabilities {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(dependencies: Pick<DOMDependencies, "tab" | "nativeSubmit">);
|
|
3
5
|
capabilities(operation: any): any;
|
|
4
|
-
|
|
6
|
+
private creatorCapabilities;
|
|
7
|
+
private collectionCapabilities;
|
|
8
|
+
}
|
|
9
|
+
export declare function createDOMCapabilities(...args: ConstructorParameters<typeof DOMCapabilities>): DOMCapabilities;
|
|
@@ -1,110 +1,131 @@
|
|
|
1
1
|
import { missingMethods } from "./browser-common.js";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
export class DOMCapabilities {
|
|
3
|
+
#tab;
|
|
4
|
+
#nativeSubmit;
|
|
5
|
+
constructor(dependencies) {
|
|
6
|
+
this.capabilities = this.capabilities.bind(this);
|
|
7
|
+
const { tab, nativeSubmit } = dependencies;
|
|
8
|
+
this.#tab = tab;
|
|
9
|
+
this.#nativeSubmit = nativeSubmit;
|
|
10
|
+
}
|
|
11
|
+
capabilities(operation) {
|
|
12
|
+
const base = missingMethods(this.#tab?.playwright, ["evaluate"]);
|
|
13
|
+
if (operation === "readCreator") {
|
|
14
|
+
return this.creatorCapabilities(base, operation);
|
|
15
|
+
}
|
|
16
|
+
if (["readBookmarks", "searchSources", "readFeedback"].includes(operation)) {
|
|
17
|
+
return this.collectionCapabilities(base, operation);
|
|
18
|
+
}
|
|
19
|
+
if (operation !== "read")
|
|
20
|
+
base.push(...missingMethods(this.#tab?.playwright, ["getByRole"]), ...missingMethods(this.#tab, ["goto"]));
|
|
21
|
+
if (operation !== "read" &&
|
|
22
|
+
typeof this.#tab?.playwright?.getByRole === "function") {
|
|
23
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("button"), [
|
|
24
|
+
"count",
|
|
25
|
+
"click",
|
|
26
|
+
]));
|
|
27
|
+
if (operation !== "submitFollow")
|
|
28
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("textbox"), [
|
|
29
|
+
"count",
|
|
30
|
+
"fill",
|
|
31
|
+
]));
|
|
32
|
+
if (["submitPost", "submitReply"].includes(operation)) {
|
|
33
|
+
base.push(...missingMethods(this.#tab.playwright, [
|
|
34
|
+
"locator",
|
|
35
|
+
"waitForLoadState",
|
|
36
|
+
]));
|
|
37
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("button"), [
|
|
38
|
+
"and",
|
|
39
|
+
"waitFor",
|
|
14
40
|
]));
|
|
15
|
-
base.push(...missingMethods(tab.playwright, ["locator"]));
|
|
16
|
-
if (typeof tab.playwright?.locator === "function") {
|
|
17
|
-
const article = tab.playwright.locator("article");
|
|
18
|
-
base.push(...missingMethods(article, ["first", "getByRole"]));
|
|
19
|
-
if (typeof article.first === "function")
|
|
20
|
-
base.push(...missingMethods(article.first(), ["waitFor"]));
|
|
21
|
-
if (typeof article.getByRole === "function")
|
|
22
|
-
base.push(...missingMethods(article.getByRole("button", { name: "显示更多", exact: true }), ["all"]));
|
|
23
|
-
}
|
|
24
|
-
return base;
|
|
25
|
-
}
|
|
26
|
-
if (["readBookmarks", "searchSources", "readFeedback"].includes(operation)) {
|
|
27
|
-
base.push(...missingMethods(tab, ["goto"]));
|
|
28
|
-
base.push(...missingMethods(tab?.playwright, ["getByRole", "waitForURL"]));
|
|
29
|
-
if (typeof tab?.playwright?.getByRole === "function")
|
|
30
|
-
base.push(...missingMethods(tab.playwright.getByRole("article"), [
|
|
31
|
-
"first",
|
|
32
|
-
"waitFor",
|
|
33
|
-
]));
|
|
34
|
-
if (operation !== "readFeedback") {
|
|
35
|
-
base.push(...missingMethods(tab?.playwright, [
|
|
36
|
-
"getByRole",
|
|
37
|
-
"getByText",
|
|
38
|
-
"locator",
|
|
39
|
-
"waitForURL",
|
|
40
|
-
]));
|
|
41
|
-
if (typeof tab?.playwright?.getByRole === "function")
|
|
42
|
-
base.push(...missingMethods(tab.playwright.getByRole("main"), [
|
|
43
|
-
"count",
|
|
44
|
-
"click",
|
|
45
|
-
"first",
|
|
46
|
-
"waitFor",
|
|
47
|
-
]));
|
|
48
|
-
if (typeof tab?.playwright?.locator === "function")
|
|
49
|
-
base.push(...missingMethods(tab.playwright.locator("a"), [
|
|
50
|
-
"count",
|
|
51
|
-
"filter",
|
|
52
|
-
"press",
|
|
53
|
-
]));
|
|
54
|
-
if (typeof tab?.playwright?.getByText === "function")
|
|
55
|
-
base.push(...missingMethods(tab.playwright.getByText(""), ["waitFor"]));
|
|
56
|
-
}
|
|
57
|
-
return base;
|
|
58
41
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
42
|
+
}
|
|
43
|
+
if (operation === "refreshPerson" || operation === "refreshPosts") {
|
|
44
|
+
base.push(...missingMethods(this.#tab, ["reload"]));
|
|
45
|
+
base.push(...missingMethods(this.#tab?.playwright, ["waitForLoadState"]));
|
|
46
|
+
if (typeof this.#tab?.playwright?.getByRole === "function")
|
|
47
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("button"), [
|
|
48
|
+
"waitFor",
|
|
49
|
+
]));
|
|
50
|
+
}
|
|
51
|
+
if (operation === "openOwnPostMenu") {
|
|
52
|
+
base.push(...missingMethods(this.#tab?.playwright, ["locator"]));
|
|
53
|
+
if (typeof this.#tab?.playwright?.getByRole === "function")
|
|
54
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("article"), [
|
|
55
|
+
"filter",
|
|
56
|
+
"getByRole",
|
|
57
|
+
]));
|
|
58
|
+
}
|
|
59
|
+
if (operation === "submitEditedPost") {
|
|
60
|
+
base.push(...missingMethods(this.#tab?.playwright, ["waitForLoadState"]));
|
|
61
|
+
if (typeof this.#tab?.playwright?.getByRole === "function")
|
|
62
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("button"), [
|
|
63
|
+
"press",
|
|
64
|
+
]));
|
|
65
|
+
}
|
|
66
|
+
if (operation === "attachAssets")
|
|
67
|
+
base.push(...missingMethods(this.#tab?.playwright, [
|
|
68
|
+
"waitForEvent",
|
|
69
|
+
"getByLabel",
|
|
70
|
+
"getByPlaceholder",
|
|
71
|
+
]));
|
|
72
|
+
if (this.#nativeSubmit && ["submitPost", "submitReply"].includes(operation))
|
|
73
|
+
base.push(...missingMethods(this.#tab, ["getAXState", "click"]));
|
|
74
|
+
return base;
|
|
75
|
+
}
|
|
76
|
+
creatorCapabilities(base, operation) {
|
|
77
|
+
base.push(...missingMethods(this.#tab, [
|
|
78
|
+
"url",
|
|
79
|
+
"goto",
|
|
80
|
+
"reload",
|
|
81
|
+
"getAXState",
|
|
82
|
+
"scroll",
|
|
83
|
+
]));
|
|
84
|
+
base.push(...missingMethods(this.#tab.playwright, ["locator"]));
|
|
85
|
+
if (typeof this.#tab.playwright?.locator === "function") {
|
|
86
|
+
const article = this.#tab.playwright.locator("article");
|
|
87
|
+
base.push(...missingMethods(article, ["first", "getByRole"]));
|
|
88
|
+
if (typeof article.first === "function")
|
|
89
|
+
base.push(...missingMethods(article.first(), ["waitFor"]));
|
|
90
|
+
if (typeof article.getByRole === "function")
|
|
91
|
+
base.push(...missingMethods(article.getByRole("button", { name: "显示更多", exact: true }), ["all"]));
|
|
92
|
+
}
|
|
93
|
+
return base;
|
|
94
|
+
}
|
|
95
|
+
collectionCapabilities(base, operation) {
|
|
96
|
+
base.push(...missingMethods(this.#tab, ["goto"]));
|
|
97
|
+
base.push(...missingMethods(this.#tab?.playwright, ["getByRole", "waitForURL"]));
|
|
98
|
+
if (typeof this.#tab?.playwright?.getByRole === "function")
|
|
99
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("article"), [
|
|
100
|
+
"first",
|
|
101
|
+
"waitFor",
|
|
102
|
+
]));
|
|
103
|
+
if (operation !== "readFeedback") {
|
|
104
|
+
base.push(...missingMethods(this.#tab?.playwright, [
|
|
105
|
+
"getByRole",
|
|
106
|
+
"getByText",
|
|
107
|
+
"locator",
|
|
108
|
+
"waitForURL",
|
|
109
|
+
]));
|
|
110
|
+
if (typeof this.#tab?.playwright?.getByRole === "function")
|
|
111
|
+
base.push(...missingMethods(this.#tab.playwright.getByRole("main"), [
|
|
64
112
|
"count",
|
|
65
113
|
"click",
|
|
114
|
+
"first",
|
|
115
|
+
"waitFor",
|
|
66
116
|
]));
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (["submitPost", "submitReply"].includes(operation)) {
|
|
73
|
-
base.push(...missingMethods(tab.playwright, ["locator", "waitForLoadState"]));
|
|
74
|
-
base.push(...missingMethods(tab.playwright.getByRole("button"), [
|
|
75
|
-
"and",
|
|
76
|
-
"waitFor",
|
|
77
|
-
]));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (operation === "refreshPerson" || operation === "refreshPosts") {
|
|
81
|
-
base.push(...missingMethods(tab, ["reload"]));
|
|
82
|
-
base.push(...missingMethods(tab?.playwright, ["waitForLoadState"]));
|
|
83
|
-
if (typeof tab?.playwright?.getByRole === "function")
|
|
84
|
-
base.push(...missingMethods(tab.playwright.getByRole("button"), ["waitFor"]));
|
|
85
|
-
}
|
|
86
|
-
if (operation === "openOwnPostMenu") {
|
|
87
|
-
base.push(...missingMethods(tab?.playwright, ["locator"]));
|
|
88
|
-
if (typeof tab?.playwright?.getByRole === "function")
|
|
89
|
-
base.push(...missingMethods(tab.playwright.getByRole("article"), [
|
|
90
|
-
"filter",
|
|
91
|
-
"getByRole",
|
|
92
|
-
]));
|
|
93
|
-
}
|
|
94
|
-
if (operation === "submitEditedPost") {
|
|
95
|
-
base.push(...missingMethods(tab?.playwright, ["waitForLoadState"]));
|
|
96
|
-
if (typeof tab?.playwright?.getByRole === "function")
|
|
97
|
-
base.push(...missingMethods(tab.playwright.getByRole("button"), ["press"]));
|
|
98
|
-
}
|
|
99
|
-
if (operation === "attachAssets")
|
|
100
|
-
base.push(...missingMethods(tab?.playwright, [
|
|
101
|
-
"waitForEvent",
|
|
102
|
-
"getByLabel",
|
|
103
|
-
"getByPlaceholder",
|
|
117
|
+
if (typeof this.#tab?.playwright?.locator === "function")
|
|
118
|
+
base.push(...missingMethods(this.#tab.playwright.locator("a"), [
|
|
119
|
+
"count",
|
|
120
|
+
"filter",
|
|
121
|
+
"press",
|
|
104
122
|
]));
|
|
105
|
-
if (
|
|
106
|
-
base.push(...missingMethods(tab
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
123
|
+
if (typeof this.#tab?.playwright?.getByText === "function")
|
|
124
|
+
base.push(...missingMethods(this.#tab.playwright.getByText(""), ["waitFor"]));
|
|
125
|
+
}
|
|
126
|
+
return base;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export function createDOMCapabilities(...args) {
|
|
130
|
+
return new DOMCapabilities(...args);
|
|
110
131
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DOMDependencies } from "./browser-dom-dependencies.js";
|
|
2
|
-
export declare
|
|
2
|
+
export declare class DOMEditing {
|
|
3
|
+
#private;
|
|
3
4
|
dismissMenu: (command: any) => Promise<{
|
|
4
5
|
completed: boolean;
|
|
5
6
|
loc?: undefined;
|
|
@@ -145,4 +146,21 @@ export declare function createDOMEditing(dependencies: Pick<DOMDependencies, "se
|
|
|
145
146
|
loc: any;
|
|
146
147
|
submittedEditor: any;
|
|
147
148
|
}>;
|
|
148
|
-
|
|
149
|
+
constructor(dependencies: Pick<DOMDependencies, "session" | "unique" | "locator" | "tab" | "observe">);
|
|
150
|
+
private handleDismissMenu;
|
|
151
|
+
private handleOpenControl;
|
|
152
|
+
private handleOpenOwnPostMenu;
|
|
153
|
+
private handleSubmitEditedPost;
|
|
154
|
+
private handleExpandPost;
|
|
155
|
+
private handleNextPosts;
|
|
156
|
+
private handleClearPreparedText;
|
|
157
|
+
private handleClosePreparedReply;
|
|
158
|
+
private handleClosePreparedMedia;
|
|
159
|
+
private handleRemovePreparedMedia;
|
|
160
|
+
private handleAttachAssets;
|
|
161
|
+
private handleFollow;
|
|
162
|
+
private handleOpenReply;
|
|
163
|
+
private handleFillComposer;
|
|
164
|
+
private handleSubmitPost;
|
|
165
|
+
}
|
|
166
|
+
export declare function createDOMEditing(...args: ConstructorParameters<typeof DOMEditing>): DOMEditing;
|