@vforsh/argus-client 0.2.0 → 0.3.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/README.md +65 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/client/context.d.ts +31 -0
- package/dist/client/context.d.ts.map +1 -0
- package/dist/client/context.js +20 -0
- package/dist/client/context.js.map +1 -0
- package/dist/client/createArgusClient.d.ts +12 -2
- package/dist/client/createArgusClient.d.ts.map +1 -1
- package/dist/client/createArgusClient.js +26 -165
- package/dist/client/createArgusClient.js.map +1 -1
- package/dist/client/methods/capture.d.ts +12 -0
- package/dist/client/methods/capture.d.ts.map +1 -0
- package/dist/client/methods/capture.js +89 -0
- package/dist/client/methods/capture.js.map +1 -0
- package/dist/client/methods/evalMethods.d.ts +9 -0
- package/dist/client/methods/evalMethods.d.ts.map +1 -0
- package/dist/client/methods/evalMethods.js +127 -0
- package/dist/client/methods/evalMethods.js.map +1 -0
- package/dist/client/methods/inspect.d.ts +19 -0
- package/dist/client/methods/inspect.d.ts.map +1 -0
- package/dist/client/methods/inspect.js +110 -0
- package/dist/client/methods/inspect.js.map +1 -0
- package/dist/client/methods/page.d.ts +9 -0
- package/dist/client/methods/page.d.ts.map +1 -0
- package/dist/client/methods/page.js +38 -0
- package/dist/client/methods/page.js.map +1 -0
- package/dist/client/watcherHandle.d.ts +9 -0
- package/dist/client/watcherHandle.d.ts.map +1 -0
- package/dist/client/watcherHandle.js +29 -0
- package/dist/client/watcherHandle.js.map +1 -0
- package/dist/client/watcherRequest.d.ts.map +1 -1
- package/dist/client/watcherRequest.js +7 -0
- package/dist/client/watcherRequest.js.map +1 -1
- package/dist/eval/ArgusEvalError.d.ts +30 -0
- package/dist/eval/ArgusEvalError.d.ts.map +1 -0
- package/dist/eval/ArgusEvalError.js +37 -0
- package/dist/eval/ArgusEvalError.js.map +1 -0
- package/dist/eval/pollEval.d.ts +81 -0
- package/dist/eval/pollEval.d.ts.map +1 -0
- package/dist/eval/pollEval.js +65 -0
- package/dist/eval/pollEval.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +217 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { requestWatcher } from '../watcherRequest.js';
|
|
2
|
+
/** Page interaction methods: click, visibility lock, reload. */
|
|
3
|
+
export const createPageMethods = (ctx) => ({
|
|
4
|
+
domClick: async (watcherId, options) => {
|
|
5
|
+
const hasTarget = Boolean(options?.selector || options?.ref) || options?.x != null || options?.y != null;
|
|
6
|
+
if (!hasTarget) {
|
|
7
|
+
throw new Error('selector, ref, or x,y coordinates are required');
|
|
8
|
+
}
|
|
9
|
+
const { data } = await requestWatcher(ctx, watcherId, {
|
|
10
|
+
path: '/dom/click',
|
|
11
|
+
timeoutMs: ctx.requestTimeoutMs,
|
|
12
|
+
method: 'POST',
|
|
13
|
+
body: options,
|
|
14
|
+
});
|
|
15
|
+
return { matches: data.matches, clicked: data.clicked };
|
|
16
|
+
},
|
|
17
|
+
visibility: async (watcherId, options) => {
|
|
18
|
+
if (options?.action !== 'show' && options?.action !== 'hide') {
|
|
19
|
+
throw new Error("action must be 'show' or 'hide'");
|
|
20
|
+
}
|
|
21
|
+
const { data } = await requestWatcher(ctx, watcherId, {
|
|
22
|
+
path: '/visibility',
|
|
23
|
+
timeoutMs: ctx.requestTimeoutMs,
|
|
24
|
+
method: 'POST',
|
|
25
|
+
body: options,
|
|
26
|
+
});
|
|
27
|
+
return { attached: data.attached, state: data.state };
|
|
28
|
+
},
|
|
29
|
+
reload: async (watcherId, options = {}) => {
|
|
30
|
+
await requestWatcher(ctx, watcherId, {
|
|
31
|
+
path: '/reload',
|
|
32
|
+
timeoutMs: ctx.requestTimeoutMs,
|
|
33
|
+
method: 'POST',
|
|
34
|
+
body: { ignoreCache: options.ignoreCache ?? false },
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../../src/client/methods/page.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAkB,EAAE,EAAE,CAAC,CAAC;IACzD,QAAQ,EAAE,KAAK,EAAE,SAAiB,EAAE,OAAwB,EAA2B,EAAE;QACxF,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC,IAAI,IAAI,CAAA;QACxG,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;QAClE,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,CAAmB,GAAG,EAAE,SAAS,EAAE;YACvE,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,GAAG,CAAC,gBAAgB;YAC/B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,OAAO;SACb,CAAC,CAAA;QAEF,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IACxD,CAAC;IAED,UAAU,EAAE,KAAK,EAAE,SAAiB,EAAE,OAA0B,EAA6B,EAAE;QAC9F,IAAI,OAAO,EAAE,MAAM,KAAK,MAAM,IAAI,OAAO,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;QACnD,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,CAAqB,GAAG,EAAE,SAAS,EAAE;YACzE,IAAI,EAAE,aAAa;YACnB,SAAS,EAAE,GAAG,CAAC,gBAAgB;YAC/B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,OAAO;SACb,CAAC,CAAA;QAEF,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;IACtD,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,SAAiB,EAAE,UAAyB,EAAE,EAAiB,EAAE;QAC/E,MAAM,cAAc,CAAiB,GAAG,EAAE,SAAS,EAAE;YACpD,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,GAAG,CAAC,gBAAgB;YAC/B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK,EAAE;SACnD,CAAC,CAAA;IACH,CAAC;CACD,CAAC,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ArgusClient, WatcherClient } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a {@link WatcherClient}: the same API with `watcherId` pre-bound.
|
|
4
|
+
*
|
|
5
|
+
* `evalValue` is bound by hand rather than through {@link bind} so its generic
|
|
6
|
+
* type parameter survives.
|
|
7
|
+
*/
|
|
8
|
+
export declare const createWatcherClient: (client: ArgusClient, watcherId: string) => WatcherClient;
|
|
9
|
+
//# sourceMappingURL=watcherHandle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcherHandle.d.ts","sourceRoot":"","sources":["../../src/client/watcherHandle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAoB,aAAa,EAAE,MAAM,aAAa,CAAA;AAQ/E;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,WAAW,EAAE,WAAW,MAAM,KAAG,aAmB3E,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Pre-apply `watcherId` as the first argument of a watcher-scoped method. */
|
|
2
|
+
const bind = (method, watcherId) => (...args) => method(watcherId, ...args);
|
|
3
|
+
/**
|
|
4
|
+
* Build a {@link WatcherClient}: the same API with `watcherId` pre-bound.
|
|
5
|
+
*
|
|
6
|
+
* `evalValue` is bound by hand rather than through {@link bind} so its generic
|
|
7
|
+
* type parameter survives.
|
|
8
|
+
*/
|
|
9
|
+
export const createWatcherClient = (client, watcherId) => ({
|
|
10
|
+
logs: bind(client.logs, watcherId),
|
|
11
|
+
logCursor: bind(client.logCursor, watcherId),
|
|
12
|
+
beginLogEpoch: bind(client.beginLogEpoch, watcherId),
|
|
13
|
+
net: bind(client.net, watcherId),
|
|
14
|
+
netRequest: bind(client.netRequest, watcherId),
|
|
15
|
+
netClear: bind(client.netClear, watcherId),
|
|
16
|
+
eval: bind(client.eval, watcherId),
|
|
17
|
+
evalValue: (expression, options) => client.evalValue(watcherId, expression, options),
|
|
18
|
+
evalUntil: bind(client.evalUntil, watcherId),
|
|
19
|
+
domClick: bind(client.domClick, watcherId),
|
|
20
|
+
visibility: bind(client.visibility, watcherId),
|
|
21
|
+
reload: bind(client.reload, watcherId),
|
|
22
|
+
traceStart: bind(client.traceStart, watcherId),
|
|
23
|
+
traceStop: bind(client.traceStop, watcherId),
|
|
24
|
+
screenshot: bind(client.screenshot, watcherId),
|
|
25
|
+
record: bind(client.record, watcherId),
|
|
26
|
+
recordStart: bind(client.recordStart, watcherId),
|
|
27
|
+
recordStop: bind(client.recordStop, watcherId),
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=watcherHandle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcherHandle.js","sourceRoot":"","sources":["../../src/client/watcherHandle.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,MAAM,IAAI,GACT,CAAyB,MAA4C,EAAE,SAAiB,EAAE,EAAE,CAC5F,CAAC,GAAG,IAAO,EAAK,EAAE,CACjB,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CAAA;AAE5B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAmB,EAAE,SAAiB,EAAiB,EAAE,CAAC,CAAC;IAC9F,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5C,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC;IACpD,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC;IAChC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;IAC9C,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC1C,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;IAClC,SAAS,EAAE,CAAc,UAAkB,EAAE,OAA0B,EAAc,EAAE,CAAC,MAAM,CAAC,SAAS,CAAI,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC;IAC3I,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5C,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC1C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;IAC9C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IACtC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;IAC9C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;IAC9C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IACtC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC;IAChD,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;CAC9C,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcherRequest.d.ts","sourceRoot":"","sources":["../../src/client/watcherRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"watcherRequest.d.ts","sourceRoot":"","sources":["../../src/client/watcherRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAIvD,KAAK,eAAe,GAAG;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;CACb,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;CACd,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,CAAC,EAAE,SAAS,eAAe,EAAE,WAAW,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAQ7I,CAAA;AAED,eAAO,MAAM,cAAc,GAAU,CAAC,EACrC,SAAS,eAAe,EACxB,WAAW,MAAM,EACjB,SAAS,qBAAqB,KAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAoB3C,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isHttpResponseError } from '@vforsh/argus-core';
|
|
1
2
|
import { fetchJson } from '../http/fetchJson.js';
|
|
2
3
|
import { readAndPruneRegistry, removeWatcherAndPersist } from '../registry/readAndPruneRegistry.js';
|
|
3
4
|
export const withWatcher = async (context, watcherId, callback) => {
|
|
@@ -18,6 +19,12 @@ export const requestWatcher = async (context, watcherId, options) => withWatcher
|
|
|
18
19
|
return { watcher, data };
|
|
19
20
|
}
|
|
20
21
|
catch (error) {
|
|
22
|
+
// The watcher answered and rejected this request, so it is demonstrably alive.
|
|
23
|
+
// Evicting it here would break every later call in the process over one bad
|
|
24
|
+
// selector or a page that happens to be mid-navigation.
|
|
25
|
+
if (isHttpResponseError(error)) {
|
|
26
|
+
throw new Error(`${watcher.id}: ${error.message}`);
|
|
27
|
+
}
|
|
21
28
|
await removeWatcherAndPersist(watcher.id, context.registryPath);
|
|
22
29
|
throw new Error(formatWatcherTransportError(watcher, error));
|
|
23
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcherRequest.js","sourceRoot":"","sources":["../../src/client/watcherRequest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watcherRequest.js","sourceRoot":"","sources":["../../src/client/watcherRequest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA;AAenG,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAK,OAAwB,EAAE,SAAiB,EAAE,QAAgD,EAAc,EAAE;IACjJ,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;IACzG,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAA;IACnD,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAA;AACzB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAClC,OAAwB,EACxB,SAAiB,EACjB,OAA8B,EACiB,EAAE,CACjD,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACjD,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,SAAS,CAAI,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACtF,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,IAAI,EAAE,OAAO,CAAC,IAAI;SAClB,CAAC,CAAA;QACF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,+EAA+E;QAC/E,4EAA4E;QAC5E,wDAAwD;QACxD,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,CAAC;QAED,MAAM,uBAAuB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;QAC/D,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;IAC7D,CAAC;AACF,CAAC,CAAC,CAAA;AAEH,MAAM,eAAe,GAAG,CAAC,OAA6C,EAAE,IAAY,EAAE,KAAuB,EAAU,EAAE;IACxH,MAAM,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAA;IAC5B,OAAO,UAAU,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AAC5E,CAAC,CAAA;AAED,MAAM,2BAA2B,GAAG,CAAC,OAAkC,EAAE,KAAc,EAAU,EAAE,CAClG,GAAG,OAAO,CAAC,EAAE,8BAA8B,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAA;AAExE,MAAM,kBAAkB,GAAG,CAAC,KAAc,EAAU,EAAE;IACrD,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,eAAe,CAAA;IACvB,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,OAAO,CAAA;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACrB,CAAC,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** The page exception shape carried by `EvalResponse.exception`. */
|
|
2
|
+
type EvalException = {
|
|
3
|
+
text: string;
|
|
4
|
+
details?: unknown;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Thrown when an expression raises inside the page.
|
|
8
|
+
*
|
|
9
|
+
* Only value-returning eval APIs (`evalValue`, `evalUntil`) throw this. Raw
|
|
10
|
+
* `client.eval` keeps reporting page exceptions in its `exception` field so callers
|
|
11
|
+
* can inspect a failure without a try/catch.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ArgusEvalError extends Error {
|
|
14
|
+
/** Structured exception detail from the page, when the transport provided one. */
|
|
15
|
+
readonly details?: unknown;
|
|
16
|
+
/**
|
|
17
|
+
* @param text Page-side exception text, used as the error message.
|
|
18
|
+
* @param details Optional structured exception detail from CDP.
|
|
19
|
+
*/
|
|
20
|
+
constructor(text: string, details?: unknown);
|
|
21
|
+
/**
|
|
22
|
+
* Build an error from a watcher exception payload.
|
|
23
|
+
*
|
|
24
|
+
* CDP reports `text` as a bare `"Uncaught"` for thrown errors and puts the real
|
|
25
|
+
* message plus stack in `details.description`, so prefer that when present.
|
|
26
|
+
*/
|
|
27
|
+
static fromException(exception: EvalException): ArgusEvalError;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=ArgusEvalError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArgusEvalError.d.ts","sourceRoot":"","sources":["../../src/eval/ArgusEvalError.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,KAAK,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAExD;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACxC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAE1B;;;OAGG;gBACS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAM3C;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,GAAG,cAAc;CAG9D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown when an expression raises inside the page.
|
|
3
|
+
*
|
|
4
|
+
* Only value-returning eval APIs (`evalValue`, `evalUntil`) throw this. Raw
|
|
5
|
+
* `client.eval` keeps reporting page exceptions in its `exception` field so callers
|
|
6
|
+
* can inspect a failure without a try/catch.
|
|
7
|
+
*/
|
|
8
|
+
export class ArgusEvalError extends Error {
|
|
9
|
+
/** Structured exception detail from the page, when the transport provided one. */
|
|
10
|
+
details;
|
|
11
|
+
/**
|
|
12
|
+
* @param text Page-side exception text, used as the error message.
|
|
13
|
+
* @param details Optional structured exception detail from CDP.
|
|
14
|
+
*/
|
|
15
|
+
constructor(text, details) {
|
|
16
|
+
super(text);
|
|
17
|
+
this.name = 'ArgusEvalError';
|
|
18
|
+
this.details = details;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build an error from a watcher exception payload.
|
|
22
|
+
*
|
|
23
|
+
* CDP reports `text` as a bare `"Uncaught"` for thrown errors and puts the real
|
|
24
|
+
* message plus stack in `details.description`, so prefer that when present.
|
|
25
|
+
*/
|
|
26
|
+
static fromException(exception) {
|
|
27
|
+
return new ArgusEvalError(readExceptionDescription(exception.details) ?? exception.text, exception.details);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const readExceptionDescription = (details) => {
|
|
31
|
+
if (details == null || typeof details !== 'object' || !('description' in details)) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const { description } = details;
|
|
35
|
+
return typeof description === 'string' && description.trim() ? description : undefined;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=ArgusEvalError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArgusEvalError.js","sourceRoot":"","sources":["../../src/eval/ArgusEvalError.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACxC,kFAAkF;IACzE,OAAO,CAAU;IAE1B;;;OAGG;IACH,YAAY,IAAY,EAAE,OAAiB;QAC1C,KAAK,CAAC,IAAI,CAAC,CAAA;QACX,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACvB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,SAAwB;QAC5C,OAAO,IAAI,cAAc,CAAC,wBAAwB,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC5G,CAAC;CACD;AAED,MAAM,wBAAwB,GAAG,CAAC,OAAgB,EAAsB,EAAE;IACzE,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,aAAa,IAAI,OAAO,CAAC,EAAE,CAAC;QACnF,OAAO,SAAS,CAAA;IACjB,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,OAAoC,CAAA;IAC5D,OAAO,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAA;AACvF,CAAC,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport-agnostic eval polling loop shared by the CLI (`eval --interval`,
|
|
3
|
+
* `eval-until`) and the SDK (`evalUntil`), so loop semantics stay identical.
|
|
4
|
+
*
|
|
5
|
+
* The loop owns only timing and stop conditions. Everything environment-specific —
|
|
6
|
+
* how an eval is performed, retry policy, signal handling, output — is injected by
|
|
7
|
+
* the caller. In particular this module installs no process listeners: cancellation
|
|
8
|
+
* is an `AbortSignal` so it stays safe to use inside a library.
|
|
9
|
+
*/
|
|
10
|
+
/** Per-iteration context handed to stop conditions and result observers. */
|
|
11
|
+
export type EvalPollContext<TResponse> = {
|
|
12
|
+
response: TResponse;
|
|
13
|
+
/** 1-based poll iteration. */
|
|
14
|
+
iteration: number;
|
|
15
|
+
/** 1-based attempt number within the iteration, when the caller retries. */
|
|
16
|
+
attempt: number;
|
|
17
|
+
};
|
|
18
|
+
/** Verdict from a stop condition: matched, not matched, or the condition itself failed. */
|
|
19
|
+
export type EvalPollStopDecision = {
|
|
20
|
+
ok: true;
|
|
21
|
+
matched: boolean;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
error: string;
|
|
25
|
+
};
|
|
26
|
+
/** Outcome of one injected eval attempt. */
|
|
27
|
+
export type EvalPollAttempt<TResponse, TFailure> = {
|
|
28
|
+
ok: true;
|
|
29
|
+
response: TResponse;
|
|
30
|
+
attempt: number;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
failure: TFailure;
|
|
34
|
+
attempt: number;
|
|
35
|
+
};
|
|
36
|
+
/** Inputs for {@link pollEval}. */
|
|
37
|
+
export type EvalPollInput<TResponse, TFailure> = {
|
|
38
|
+
/** Perform one eval. Callers wrap their own retry policy in here. */
|
|
39
|
+
runEval: (iteration: number) => Promise<EvalPollAttempt<TResponse, TFailure>>;
|
|
40
|
+
/** Delay between polls in milliseconds. */
|
|
41
|
+
intervalMs: number;
|
|
42
|
+
/** Stop after this many polls. Unlimited when omitted. */
|
|
43
|
+
count?: number;
|
|
44
|
+
/** Give up after this much wall-clock time. Unlimited when omitted. */
|
|
45
|
+
totalTimeoutMs?: number;
|
|
46
|
+
/** Decide whether to stop. Omitted means "never match" — useful for streaming. */
|
|
47
|
+
shouldStop?: (context: EvalPollContext<TResponse>) => EvalPollStopDecision;
|
|
48
|
+
/** Observe every result, including the matching one. */
|
|
49
|
+
onResult?: (response: TResponse, context: EvalPollContext<TResponse>) => void | Promise<void>;
|
|
50
|
+
/** Cancel the loop. Yields an `interrupted` outcome rather than throwing. */
|
|
51
|
+
signal?: AbortSignal;
|
|
52
|
+
};
|
|
53
|
+
/** Terminal state of a poll loop. */
|
|
54
|
+
export type EvalPollOutcome<TResponse, TFailure> = {
|
|
55
|
+
kind: 'matched';
|
|
56
|
+
response: TResponse;
|
|
57
|
+
iteration: number;
|
|
58
|
+
attempt: number;
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'exhausted';
|
|
61
|
+
iterations: number;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'timeout';
|
|
64
|
+
elapsedMs: number;
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'interrupted';
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'eval-error';
|
|
69
|
+
failure: TFailure;
|
|
70
|
+
} | {
|
|
71
|
+
kind: 'condition-error';
|
|
72
|
+
error: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Poll `runEval` until a stop condition matches, the budget runs out, or the signal aborts.
|
|
76
|
+
*
|
|
77
|
+
* Results are reported to `onResult` before stop conditions are checked, so streaming
|
|
78
|
+
* callers print the matching iteration too.
|
|
79
|
+
*/
|
|
80
|
+
export declare const pollEval: <TResponse, TFailure>(input: EvalPollInput<TResponse, TFailure>) => Promise<EvalPollOutcome<TResponse, TFailure>>;
|
|
81
|
+
//# sourceMappingURL=pollEval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pollEval.d.ts","sourceRoot":"","sources":["../../src/eval/pollEval.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,eAAe,CAAC,SAAS,IAAI;IACxC,QAAQ,EAAE,SAAS,CAAA;IACnB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAA;CACf,CAAA;AAED,2FAA2F;AAC3F,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhG,4CAA4C;AAC5C,MAAM,MAAM,eAAe,CAAC,SAAS,EAAE,QAAQ,IAC5C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,mCAAmC;AACnC,MAAM,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,IAAI;IAChD,qEAAqE;IACrE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAA;IAC7E,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kFAAkF;IAClF,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,oBAAoB,CAAA;IAC1E,wDAAwD;IACxD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7F,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAA;CACpB,CAAA;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,CAAC,SAAS,EAAE,QAAQ,IAC5C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAU,SAAS,EAAE,QAAQ,EAAE,OAAO,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAG,OAAO,CAAC,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAwC3I,CAAA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport-agnostic eval polling loop shared by the CLI (`eval --interval`,
|
|
3
|
+
* `eval-until`) and the SDK (`evalUntil`), so loop semantics stay identical.
|
|
4
|
+
*
|
|
5
|
+
* The loop owns only timing and stop conditions. Everything environment-specific —
|
|
6
|
+
* how an eval is performed, retry policy, signal handling, output — is injected by
|
|
7
|
+
* the caller. In particular this module installs no process listeners: cancellation
|
|
8
|
+
* is an `AbortSignal` so it stays safe to use inside a library.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Poll `runEval` until a stop condition matches, the budget runs out, or the signal aborts.
|
|
12
|
+
*
|
|
13
|
+
* Results are reported to `onResult` before stop conditions are checked, so streaming
|
|
14
|
+
* callers print the matching iteration too.
|
|
15
|
+
*/
|
|
16
|
+
export const pollEval = async (input) => {
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
let iteration = 0;
|
|
19
|
+
while (!input.signal?.aborted) {
|
|
20
|
+
if (input.totalTimeoutMs != null) {
|
|
21
|
+
const elapsedMs = Date.now() - startTime;
|
|
22
|
+
if (elapsedMs >= input.totalTimeoutMs) {
|
|
23
|
+
return { kind: 'timeout', elapsedMs };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
iteration += 1;
|
|
27
|
+
const result = await input.runEval(iteration);
|
|
28
|
+
if (!result.ok) {
|
|
29
|
+
return { kind: 'eval-error', failure: result.failure };
|
|
30
|
+
}
|
|
31
|
+
const context = { response: result.response, iteration, attempt: result.attempt };
|
|
32
|
+
// Streaming callers print the matched iteration too, so emit before checking stop conditions.
|
|
33
|
+
await input.onResult?.(result.response, context);
|
|
34
|
+
const decision = input.shouldStop?.(context);
|
|
35
|
+
if (decision) {
|
|
36
|
+
if (!decision.ok) {
|
|
37
|
+
return { kind: 'condition-error', error: decision.error };
|
|
38
|
+
}
|
|
39
|
+
if (decision.matched) {
|
|
40
|
+
return { kind: 'matched', response: result.response, iteration, attempt: result.attempt };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (input.count != null && iteration >= input.count) {
|
|
44
|
+
return { kind: 'exhausted', iterations: iteration };
|
|
45
|
+
}
|
|
46
|
+
await sleep(input.intervalMs, input.signal);
|
|
47
|
+
}
|
|
48
|
+
return { kind: 'interrupted' };
|
|
49
|
+
};
|
|
50
|
+
/** Resolve after `durationMs`, or immediately once `signal` aborts. */
|
|
51
|
+
const sleep = async (durationMs, signal) => {
|
|
52
|
+
if (signal?.aborted) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
await new Promise((resolve) => {
|
|
56
|
+
const finish = () => {
|
|
57
|
+
clearTimeout(timer);
|
|
58
|
+
signal?.removeEventListener('abort', finish);
|
|
59
|
+
resolve();
|
|
60
|
+
};
|
|
61
|
+
const timer = setTimeout(finish, durationMs);
|
|
62
|
+
signal?.addEventListener('abort', finish, { once: true });
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=pollEval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pollEval.js","sourceRoot":"","sources":["../../src/eval/pollEval.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8CH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAuB,KAAyC,EAAiD,EAAE;IAC/I,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC5B,IAAI,SAAS,GAAG,CAAC,CAAA;IAEjB,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;YACxC,IAAI,SAAS,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAA;YACtC,CAAC;QACF,CAAC;QAED,SAAS,IAAI,CAAC,CAAA;QACd,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YAChB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAA;QACvD,CAAC;QAED,MAAM,OAAO,GAA+B,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAA;QAC7G,8FAA8F;QAC9F,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAEhD,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAA;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAA;YAC1D,CAAC;YACD,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAA;YAC1F,CAAC;QACF,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA;QACpD,CAAC;QAED,MAAM,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;AAC/B,CAAC,CAAA;AAED,uEAAuE;AACvE,MAAM,KAAK,GAAG,KAAK,EAAE,UAAkB,EAAE,MAAoB,EAAiB,EAAE;IAC/E,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACrB,OAAM;IACP,CAAC;IAED,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,GAAS,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAC5C,OAAO,EAAE,CAAA;QACV,CAAC,CAAA;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;AACH,CAAC,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
export type { ArgusClient, ArgusClientOptions, EvalOptions, EvalResult, ListOptions, ListResult, LogsMode, LogsOptions, LogsResult, LogCursorResult, LogEpochResult, NetOptions, NetResult, ScreenshotOptions, ScreenshotResult, TraceStartOptions, TraceStartResult, TraceStopOptions, TraceStopResult, } from './types.js';
|
|
1
|
+
export type { ArgusClient, ArgusClientOptions, DomClickOptions, DomClickResult, EvalOptions, EvalResult, EvalUntilOptions, EvalUntilResult, EvalValueOptions, ListOptions, ListResult, LogsMode, LogsOptions, LogsResult, LogCursorResult, LogEpochResult, NetClearResult, NetOptions, NetResult, RecordCaptureOptions, RecordOptions, RecordStartResult, RecordStopOptions, RecordStopResult, ReloadOptions, ScreenshotOptions, ScreenshotResult, TraceStartOptions, TraceStartResult, TraceStopOptions, TraceStopResult, VisibilityOptions, VisibilityResult, WatcherClient, } from './types.js';
|
|
2
2
|
export { createArgusClient } from './client/createArgusClient.js';
|
|
3
|
+
export { ArgusEvalError } from './eval/ArgusEvalError.js';
|
|
4
|
+
export { pollEval } from './eval/pollEval.js';
|
|
5
|
+
export type { EvalPollAttempt, EvalPollContext, EvalPollInput, EvalPollOutcome, EvalPollStopDecision } from './eval/pollEval.js';
|
|
3
6
|
export type { LogEpoch } from '@vforsh/argus-core';
|
|
4
7
|
export type { NetworkRequestDetail } from '@vforsh/argus-core';
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,UAAU,EACV,SAAS,EACT,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,GACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAChI,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LogEvent, LogEpoch, LogLevel, NetworkRequestDetail, NetworkRequestSummary, ScreenshotClipRegion, StatusResponse, WatcherRecord } from '@vforsh/argus-core';
|
|
1
|
+
import type { ElementRef, LogEvent, LogEpoch, LogLevel, MouseButton, NetworkRequestDetail, NetworkRequestSummary, RecordClipRegion, RecordFormat, ScreenshotClipRegion, StatusResponse, VisibilityLock, WatcherRecord } from '@vforsh/argus-core';
|
|
2
2
|
/** Options for configuring the Argus client. */
|
|
3
3
|
export type ArgusClientOptions = {
|
|
4
4
|
/** Override registry path instead of using `ARGUS_REGISTRY_PATH` / default. */
|
|
@@ -100,6 +100,14 @@ export type EvalOptions = {
|
|
|
100
100
|
timeoutMs?: number;
|
|
101
101
|
/** Return by value when possible. Defaults to true. */
|
|
102
102
|
returnByValue?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Serialize the result inside the page and return that JSON string as `result`,
|
|
105
|
+
* wrapped as `{"v":<value>}`. Defaults to false.
|
|
106
|
+
*
|
|
107
|
+
* Prefer {@link ArgusClient.evalValue}, which sets this and parses the envelope
|
|
108
|
+
* for you. See {@link EvalValueOptions.jsonValue} for why the mode exists.
|
|
109
|
+
*/
|
|
110
|
+
jsonValue?: boolean;
|
|
103
111
|
/** Install the temporary host bridge expected by bundled Argus scenario code. */
|
|
104
112
|
scenario?: boolean;
|
|
105
113
|
};
|
|
@@ -149,6 +157,153 @@ export type ScreenshotResult = {
|
|
|
149
157
|
outFile: string;
|
|
150
158
|
clipped: boolean;
|
|
151
159
|
};
|
|
160
|
+
/** Options for clicking in the connected page. Mirrors CLI `argus click` semantics. */
|
|
161
|
+
export type DomClickOptions = {
|
|
162
|
+
/** CSS selector to match element(s). */
|
|
163
|
+
selector?: string;
|
|
164
|
+
/** Stable element ref to click. Mutually exclusive with `selector`. */
|
|
165
|
+
ref?: ElementRef;
|
|
166
|
+
/** Allow multiple matches. If false and >1 match, the watcher errors. Defaults to false. */
|
|
167
|
+
all?: boolean;
|
|
168
|
+
/** Viewport x-coordinate, or x-offset from element top-left when `selector` is set. */
|
|
169
|
+
x?: number;
|
|
170
|
+
/** Viewport y-coordinate, or y-offset from element top-left when `selector` is set. */
|
|
171
|
+
y?: number;
|
|
172
|
+
/** Mouse button to click. Defaults to 'left'. */
|
|
173
|
+
button?: MouseButton;
|
|
174
|
+
/** Filter elements by trimmed textContent. Plain string = exact match, `/regex/flags` = regex test. */
|
|
175
|
+
text?: string;
|
|
176
|
+
/** Wait up to this many ms for the selector to appear before clicking. */
|
|
177
|
+
wait?: number;
|
|
178
|
+
};
|
|
179
|
+
/** Result of a click, reporting selector matches separately from actual clicks. */
|
|
180
|
+
export type DomClickResult = {
|
|
181
|
+
/** Number of elements matched by the selector. */
|
|
182
|
+
matches: number;
|
|
183
|
+
/** Number of elements actually clicked. */
|
|
184
|
+
clicked: number;
|
|
185
|
+
};
|
|
186
|
+
/** Result of clearing the watcher's buffered network log. */
|
|
187
|
+
export type NetClearResult = {
|
|
188
|
+
/** Number of buffered requests removed. */
|
|
189
|
+
cleared: number;
|
|
190
|
+
};
|
|
191
|
+
/** Options for the page visibility lock. */
|
|
192
|
+
export type VisibilityOptions = {
|
|
193
|
+
/** `show` locks the page shown+focused; `hide` releases the lock. */
|
|
194
|
+
action: 'show' | 'hide';
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Visibility lock result. The desired lock is sticky across detach/reattach:
|
|
198
|
+
* the watcher remembers it and re-applies on the next attach when `attached` is false.
|
|
199
|
+
*/
|
|
200
|
+
export type VisibilityResult = {
|
|
201
|
+
/** Whether the watcher was attached to a CDP target at response time. */
|
|
202
|
+
attached: boolean;
|
|
203
|
+
/** Current desired visibility lock. */
|
|
204
|
+
state: VisibilityLock;
|
|
205
|
+
};
|
|
206
|
+
/** Options for reloading the connected page. */
|
|
207
|
+
export type ReloadOptions = {
|
|
208
|
+
/** Bypass the browser cache. Defaults to false. */
|
|
209
|
+
ignoreCache?: boolean;
|
|
210
|
+
};
|
|
211
|
+
/** Shared options for video recording requests. */
|
|
212
|
+
export type RecordOptions = {
|
|
213
|
+
/** Destination path on the watcher host. Extension may determine `format`. */
|
|
214
|
+
outFile?: string;
|
|
215
|
+
/** Record only the element matched by this CSS selector. Mutually exclusive with `clip`. */
|
|
216
|
+
selector?: string;
|
|
217
|
+
/** Viewport-relative crop rectangle in CSS pixels. Mutually exclusive with `selector`. */
|
|
218
|
+
clip?: RecordClipRegion;
|
|
219
|
+
/** Output frames per second (1-60). Defaults to 30. */
|
|
220
|
+
fps?: number;
|
|
221
|
+
/** Output container. Defaults to mp4 unless inferred from the `outFile` extension. */
|
|
222
|
+
format?: RecordFormat;
|
|
223
|
+
};
|
|
224
|
+
/** Options for a fixed-duration one-shot recording. */
|
|
225
|
+
export type RecordCaptureOptions = RecordOptions & {
|
|
226
|
+
/** Capture duration in milliseconds. Must be greater than 0. */
|
|
227
|
+
durationMs: number;
|
|
228
|
+
};
|
|
229
|
+
/** Metadata returned when a recording starts. */
|
|
230
|
+
export type RecordStartResult = {
|
|
231
|
+
/** Handle for the active recording, accepted by `recordStop`. */
|
|
232
|
+
recordId: string;
|
|
233
|
+
sessionName: string;
|
|
234
|
+
outFile: string;
|
|
235
|
+
format: RecordFormat;
|
|
236
|
+
fps: number;
|
|
237
|
+
/** Whether a `selector` or `clip` crop was applied. */
|
|
238
|
+
clipped: boolean;
|
|
239
|
+
};
|
|
240
|
+
/** Metadata returned when a recording is finalized. */
|
|
241
|
+
export type RecordStopResult = RecordStartResult & {
|
|
242
|
+
/** Number of frames written to `outFile`. */
|
|
243
|
+
frameCount: number;
|
|
244
|
+
/** Wall-clock capture duration in milliseconds. */
|
|
245
|
+
durationMs: number;
|
|
246
|
+
};
|
|
247
|
+
/** Options for stopping an active recording. */
|
|
248
|
+
export type RecordStopOptions = {
|
|
249
|
+
/** Recording to stop. Defaults to the watcher's active recording. */
|
|
250
|
+
recordId?: string;
|
|
251
|
+
/** Move the finalized file to this path before returning. */
|
|
252
|
+
outFile?: string;
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Options for {@link ArgusClient.evalValue}.
|
|
256
|
+
*
|
|
257
|
+
* Omits `returnByValue` (always true) and adds {@link EvalValueOptions.jsonValue}.
|
|
258
|
+
*/
|
|
259
|
+
export type EvalValueOptions = Omit<EvalOptions, 'expression' | 'returnByValue' | 'jsonValue'> & {
|
|
260
|
+
/**
|
|
261
|
+
* Have the page serialize the result, so the JSON string — not a structured object —
|
|
262
|
+
* crosses the transport. Defaults to true.
|
|
263
|
+
*
|
|
264
|
+
* This exists because transports disagree about raw `returnByValue` results: the
|
|
265
|
+
* extension relay (Chrome's `chrome.debugger` serialization) returns object keys
|
|
266
|
+
* sorted alphabetically at every nesting level, while a direct CDP watcher preserves
|
|
267
|
+
* insertion order. Values are identical either way, but structural comparisons of the
|
|
268
|
+
* same page state produce different bytes per transport — which silently breaks
|
|
269
|
+
* snapshot assertions in verification runners. Serializing in the page normalizes both
|
|
270
|
+
* to insertion order, and makes `Date` round-trip as an ISO string (via `toJSON`)
|
|
271
|
+
* instead of `{}`.
|
|
272
|
+
*
|
|
273
|
+
* Evaluation semantics are unaffected: statement lists, top-level `await`, REPL-mode
|
|
274
|
+
* redeclaration, and promise unwrapping behave the same either way.
|
|
275
|
+
*
|
|
276
|
+
* Set to false for the raw transport-native value — one less serialization round-trip
|
|
277
|
+
* for large payloads you never compare structurally, at the cost of transport-dependent
|
|
278
|
+
* key order.
|
|
279
|
+
*/
|
|
280
|
+
jsonValue?: boolean;
|
|
281
|
+
};
|
|
282
|
+
/** Options for {@link ArgusClient.evalUntil}. */
|
|
283
|
+
export type EvalUntilOptions = EvalValueOptions & {
|
|
284
|
+
/** Delay between polls in milliseconds. Defaults to 250. */
|
|
285
|
+
intervalMs?: number;
|
|
286
|
+
/** Give up after this much wall-clock time. Defaults to 30000. */
|
|
287
|
+
totalTimeoutMs?: number;
|
|
288
|
+
/** Give up after this many polls. Unlimited when omitted. */
|
|
289
|
+
count?: number;
|
|
290
|
+
/**
|
|
291
|
+
* Stop condition evaluated against each poll's value.
|
|
292
|
+
* Defaults to a truthiness check on the returned value.
|
|
293
|
+
*/
|
|
294
|
+
predicate?: (value: unknown, iteration: number) => boolean;
|
|
295
|
+
/** Abort the poll loop early. The returned promise rejects when aborted. */
|
|
296
|
+
signal?: AbortSignal;
|
|
297
|
+
};
|
|
298
|
+
/** Result of a successful {@link ArgusClient.evalUntil} poll. */
|
|
299
|
+
export type EvalUntilResult = {
|
|
300
|
+
/** The value that satisfied the predicate. */
|
|
301
|
+
value: unknown;
|
|
302
|
+
/** 1-based poll iteration that matched. */
|
|
303
|
+
iteration: number;
|
|
304
|
+
/** Wall-clock milliseconds spent polling. */
|
|
305
|
+
elapsedMs: number;
|
|
306
|
+
};
|
|
152
307
|
/** Argus client API. */
|
|
153
308
|
export type ArgusClient = {
|
|
154
309
|
/** List registered watcher servers. */
|
|
@@ -163,13 +318,73 @@ export type ArgusClient = {
|
|
|
163
318
|
net: (watcherId: string, options?: NetOptions) => Promise<NetResult>;
|
|
164
319
|
/** Fetch the detailed record for one buffered network request. */
|
|
165
320
|
netRequest: (watcherId: string, request: number | string) => Promise<NetworkRequestDetail>;
|
|
166
|
-
/**
|
|
321
|
+
/** Clear the watcher's buffered network log. */
|
|
322
|
+
netClear: (watcherId: string) => Promise<NetClearResult>;
|
|
323
|
+
/**
|
|
324
|
+
* Evaluate a JS expression in the connected page and return the raw envelope.
|
|
325
|
+
* Page-side exceptions are reported in `exception`, not thrown.
|
|
326
|
+
*/
|
|
167
327
|
eval: (watcherId: string, options: EvalOptions) => Promise<EvalResult>;
|
|
328
|
+
/**
|
|
329
|
+
* Evaluate a JS expression and return its value directly.
|
|
330
|
+
*
|
|
331
|
+
* Unlike {@link ArgusClient.eval}, a page-side exception rejects with an `Error`
|
|
332
|
+
* carrying `exception.text` as its message. Results are normalized across transports
|
|
333
|
+
* by default — see {@link EvalValueOptions.jsonValue}.
|
|
334
|
+
*
|
|
335
|
+
* @throws {Error} When the expression throws in the page.
|
|
336
|
+
*/
|
|
337
|
+
evalValue: <T = unknown>(watcherId: string, expression: string, options?: EvalValueOptions) => Promise<T>;
|
|
338
|
+
/**
|
|
339
|
+
* Poll an expression until it satisfies a predicate (truthy by default).
|
|
340
|
+
*
|
|
341
|
+
* @throws {Error} On page-side exceptions, total-timeout expiry, poll-count
|
|
342
|
+
* exhaustion, or abort via {@link EvalUntilOptions.signal}.
|
|
343
|
+
*/
|
|
344
|
+
evalUntil: (watcherId: string, expression: string, options?: EvalUntilOptions) => Promise<EvalUntilResult>;
|
|
345
|
+
/** Click in the connected page by selector, element ref, or viewport coordinates. */
|
|
346
|
+
domClick: (watcherId: string, options: DomClickOptions) => Promise<DomClickResult>;
|
|
347
|
+
/** Lock the page shown+focused, or release the lock. */
|
|
348
|
+
visibility: (watcherId: string, options: VisibilityOptions) => Promise<VisibilityResult>;
|
|
349
|
+
/** Reload the connected page. Page-scoped even when the active target is an iframe. */
|
|
350
|
+
reload: (watcherId: string, options?: ReloadOptions) => Promise<void>;
|
|
168
351
|
/** Start Chrome tracing and write to disk on the watcher. */
|
|
169
352
|
traceStart: (watcherId: string, options?: TraceStartOptions) => Promise<TraceStartResult>;
|
|
170
353
|
/** Stop an active Chrome trace and finalize the file. */
|
|
171
354
|
traceStop: (watcherId: string, options?: TraceStopOptions) => Promise<TraceStopResult>;
|
|
172
355
|
/** Capture a screenshot and write to disk on the watcher. */
|
|
173
356
|
screenshot: (watcherId: string, options?: ScreenshotOptions) => Promise<ScreenshotResult>;
|
|
357
|
+
/** Capture a fixed-duration silent video and write it to disk on the watcher. */
|
|
358
|
+
record: (watcherId: string, options: RecordCaptureOptions) => Promise<RecordStopResult>;
|
|
359
|
+
/** Begin an open-ended silent video recording. Finalize with `recordStop`. */
|
|
360
|
+
recordStart: (watcherId: string, options?: RecordOptions) => Promise<RecordStartResult>;
|
|
361
|
+
/** Stop the active recording and finalize the file. */
|
|
362
|
+
recordStop: (watcherId: string, options?: RecordStopOptions) => Promise<RecordStopResult>;
|
|
363
|
+
/** Bind every watcher-scoped method to `watcherId`, removing id-threading at call sites. */
|
|
364
|
+
watcher: (watcherId: string) => WatcherClient;
|
|
365
|
+
};
|
|
366
|
+
/**
|
|
367
|
+
* Watcher-scoped subset of {@link ArgusClient}: everything that takes a watcher id first.
|
|
368
|
+
* `evalValue` is excluded because a mapped type erases its generic type parameter;
|
|
369
|
+
* {@link WatcherClient} redeclares it explicitly.
|
|
370
|
+
*/
|
|
371
|
+
type WatcherScopedApi = Omit<ArgusClient, 'list' | 'watcher' | 'evalValue'>;
|
|
372
|
+
/**
|
|
373
|
+
* The same API as {@link ArgusClient} with `watcherId` pre-bound.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* const page = client.watcher('playground')
|
|
377
|
+
* const count = await page.evalValue<number>('document.querySelectorAll("li").length')
|
|
378
|
+
*/
|
|
379
|
+
export type WatcherClient = {
|
|
380
|
+
[K in keyof WatcherScopedApi]: WatcherScopedApi[K] extends (watcherId: string, ...rest: infer A) => infer R ? (...args: A) => R : never;
|
|
381
|
+
} & {
|
|
382
|
+
/**
|
|
383
|
+
* Evaluate a JS expression and return its value directly.
|
|
384
|
+
*
|
|
385
|
+
* @throws {Error} When the expression throws in the page.
|
|
386
|
+
*/
|
|
387
|
+
evalValue: <T = unknown>(expression: string, options?: EvalValueOptions) => Promise<T>;
|
|
174
388
|
};
|
|
389
|
+
export {};
|
|
175
390
|
//# sourceMappingURL=types.d.ts.map
|