@testmuai/playwright-bindings 0.1.1 → 0.1.2-beta.2
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 +3 -3
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/configure.d.ts +5 -1
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +1 -0
- package/dist/configure.js.map +1 -1
- package/dist/helpers/assertion.d.ts.map +1 -1
- package/dist/helpers/assertion.js +9 -10
- package/dist/helpers/assertion.js.map +1 -1
- package/dist/helpers/executeApi.d.ts +12 -1
- package/dist/helpers/executeApi.d.ts.map +1 -1
- package/dist/helpers/executeApi.js +108 -20
- package/dist/helpers/executeApi.js.map +1 -1
- package/dist/helpers/kaneCli.d.ts +10 -1
- package/dist/helpers/kaneCli.d.ts.map +1 -1
- package/dist/helpers/kaneCli.js +122 -3
- package/dist/helpers/kaneCli.js.map +1 -1
- package/dist/helpers/math.d.ts +1 -1
- package/dist/helpers/math.d.ts.map +1 -1
- package/dist/helpers/math.js +6 -6
- package/dist/helpers/math.js.map +1 -1
- package/dist/helpers/network.d.ts +4 -4
- package/dist/helpers/network.d.ts.map +1 -1
- package/dist/helpers/network.js +16 -16
- package/dist/helpers/network.js.map +1 -1
- package/dist/helpers/smartui.d.ts +5 -1
- package/dist/helpers/smartui.d.ts.map +1 -1
- package/dist/helpers/smartui.js +45 -7
- package/dist/helpers/smartui.js.map +1 -1
- package/dist/helpers/vision.d.ts +50 -7
- package/dist/helpers/vision.d.ts.map +1 -1
- package/dist/helpers/vision.js +212 -29
- package/dist/helpers/vision.js.map +1 -1
- package/dist/helpers/wait.d.ts.map +1 -1
- package/dist/helpers/wait.js +1 -2
- package/dist/helpers/wait.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/relayProxy.d.ts +46 -0
- package/dist/relayProxy.d.ts.map +1 -0
- package/dist/relayProxy.js +453 -0
- package/dist/relayProxy.js.map +1 -0
- package/dist/session.d.ts +6 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +122 -12
- package/dist/session.js.map +1 -1
- package/dist/step.d.ts +1 -0
- package/dist/step.d.ts.map +1 -1
- package/dist/step.js +1 -0
- package/dist/step.js.map +1 -1
- package/dist/vars.d.ts +9 -20
- package/dist/vars.d.ts.map +1 -1
- package/dist/vars.js +23 -19
- package/dist/vars.js.map +1 -1
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ npm install @testmuai/playwright-bindings playwright
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import testmu, {
|
|
14
|
+
import testmu, { resolveVar, setVar } from "@testmuai/playwright-bindings";
|
|
15
15
|
import { expect } from "@playwright/test";
|
|
16
16
|
|
|
17
17
|
testmu.configure({
|
|
@@ -23,11 +23,11 @@ testmu.configure({
|
|
|
23
23
|
|
|
24
24
|
testmu.test("Login flow", async (page) => {
|
|
25
25
|
testmu.step("Navigate");
|
|
26
|
-
await page.goto(
|
|
26
|
+
await page.goto(await resolveVar("${BASE_URL}"));
|
|
27
27
|
testmu.done();
|
|
28
28
|
|
|
29
29
|
testmu.step("Fill credentials");
|
|
30
|
-
await page.locator("#email").fill(
|
|
30
|
+
await page.locator("#email").fill(await resolveVar("{{email}}"));
|
|
31
31
|
testmu.done();
|
|
32
32
|
});
|
|
33
33
|
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAGD,eAAO,MAAM,MAAM,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAI9C,CAAC;AACF,wBAAgB,QAAQ,IAAI,IAAI,CAE/B"}
|
package/dist/config.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
const DEFAULT_AI_API_HOST = 'https://kaneai-api.lambdatest.com/v16-server';
|
|
1
2
|
export function readConfig() {
|
|
2
3
|
const runTarget = process.env['TESTMU_RUN_TARGET'] === 'cloud' ? 'cloud' : 'local';
|
|
3
4
|
const ltAuth = Boolean(process.env['LT_USERNAME']) && Boolean(process.env['LT_ACCESS_KEY']);
|
|
4
5
|
const smart = process.env['TESTMU_SMART'] === '1';
|
|
5
|
-
|
|
6
|
+
const aiApiHost = process.env['TESTMU_AI_API_HOST'] || DEFAULT_AI_API_HOST;
|
|
7
|
+
return { runTarget, ltAuth, smart, aiApiHost };
|
|
6
8
|
}
|
|
7
9
|
let _snapshot = readConfig();
|
|
8
10
|
export const config = {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAE3E,MAAM,UAAU,UAAU;IACxB,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,MAAM,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,mBAAmB,CAAC;IAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACjD,CAAC;AAED,IAAI,SAAS,GAAW,UAAU,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,MAAM,GAAiC;IAClD,IAAI,OAAO;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAC;AACF,MAAM,UAAU,QAAQ;IACtB,SAAS,GAAG,UAAU,EAAE,CAAC;AAC3B,CAAC"}
|
package/dist/configure.d.ts
CHANGED
|
@@ -16,7 +16,11 @@ export interface ConfigureOptions {
|
|
|
16
16
|
variables?: Record<string, unknown>;
|
|
17
17
|
testParams?: Record<string, unknown>;
|
|
18
18
|
globalVariables?: GlobalVariable[];
|
|
19
|
-
uploadedFiles?:
|
|
19
|
+
uploadedFiles?: Array<{
|
|
20
|
+
media_url?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
}>;
|
|
23
|
+
environmentId?: number;
|
|
20
24
|
}
|
|
21
25
|
declare const DEFAULTS: Required<ConfigureOptions>;
|
|
22
26
|
type ConfigKey = keyof typeof DEFAULTS;
|
package/dist/configure.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAcxC,CAAC;AAEF,KAAK,SAAS,GAAG,MAAM,OAAO,QAAQ,CAAC;AAKvC,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAGtD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAEhE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAUtD;AAED,wBAAgB,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAErE;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAE9C;AAED,wBAAgB,MAAM,IAAI,IAAI,CAU7B"}
|
package/dist/configure.js
CHANGED
package/dist/configure.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAuBA,MAAM,QAAQ,GAA+B;IAC3C,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,EAAE;IACZ,aAAa,EAAE,EAAE;IACjB,aAAa,EAAE,EAAE;IACjB,gBAAgB,EAAE,KAAK;IACvB,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,EAAE;IACd,eAAe,EAAE,EAAE;IACnB,aAAa,EAAE,EAAE;IACjB,aAAa,EAAE,CAAC;CACjB,CAAC;AAIF,MAAM,IAAI,GAA+B,EAAE,GAAG,QAAQ,EAAE,CAAC;AACzD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAa,CAAC;AAGrC,MAAM,KAAK,GAAoB,EAAE,CAAC;AAElC,MAAM,UAAU,sBAAsB,CAAC,IAAmB;IACxD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAsB;IAC9C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAgB,EAAE,CAAC;QACnD,IAAI,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,kCAAkC,GAAG,aAAa,CAAC,CAAC;YACjE,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,GAAG,CAAsB,GAAM;IAC7C,OAAO,IAAI,CAAC,GAAG,CAAyB,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAc;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAgB,EAAE,CAAC;QACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAG,IAAmC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;aAClE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;YAAG,IAAmC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;;YAC3F,IAAmC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,uFAAuF;IACvF,4FAA4F;AAC9F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assertion.d.ts","sourceRoot":"","sources":["../../src/helpers/assertion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"assertion.d.ts","sourceRoot":"","sources":["../../src/helpers/assertion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvC,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,kBAAkB,EAAE,KAAK,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;CACzB;AAkCD,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,eAAe,CAAC,CA+C1B;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,QAAQ,EAAE,EACrB,iBAAiB,GAAE,KAAK,GAAG,IAAY,GACtC,OAAO,CAAC,OAAO,CAAC,CAWlB"}
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { fetchWithAuth } from '../http.js';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveVar } from '../vars.js';
|
|
3
3
|
import { config } from '../config.js';
|
|
4
4
|
import { log, preview } from '../log.js';
|
|
5
|
-
const AI_HOST = () => process.env['TESTMU_AI_API_HOST'] ?? 'http://localhost:8000';
|
|
6
5
|
/** Resolve a string value through the variable store; non-strings pass through. */
|
|
7
|
-
function resolveSub(sub) {
|
|
6
|
+
async function resolveSub(sub) {
|
|
8
7
|
const rawExpected = sub.expected_value ?? sub.expected ?? '';
|
|
9
8
|
const rawExtracted = sub.extracted_value ?? '';
|
|
10
9
|
const rawDescription = sub.description ?? '';
|
|
11
10
|
return {
|
|
12
|
-
description: typeof rawDescription === 'string' ?
|
|
13
|
-
expected_value: typeof rawExpected === 'string' ?
|
|
14
|
-
extracted_value: typeof rawExtracted === 'string' ?
|
|
11
|
+
description: typeof rawDescription === 'string' ? (await resolveVar(rawDescription)) ?? '' : rawDescription,
|
|
12
|
+
expected_value: typeof rawExpected === 'string' ? (await resolveVar(rawExpected)) ?? '' : rawExpected,
|
|
13
|
+
extracted_value: typeof rawExtracted === 'string' ? (await resolveVar(rawExtracted)) ?? '' : rawExtracted,
|
|
15
14
|
operator: sub.operator ?? 'contains',
|
|
16
15
|
transforms: sub.transforms ?? ['strip'],
|
|
17
16
|
};
|
|
18
17
|
}
|
|
19
18
|
async function callEvaluateApi(claim, compositeOp, subChecks) {
|
|
20
|
-
const resp = await fetchWithAuth(`${
|
|
19
|
+
const resp = await fetchWithAuth(`${config.current.aiApiHost}/api/v1/evaluate`, {
|
|
21
20
|
method: 'POST',
|
|
22
21
|
headers: { 'content-type': 'application/json' },
|
|
23
22
|
body: JSON.stringify({ claim, composite_operator: compositeOp, sub_checks: subChecks }),
|
|
@@ -37,7 +36,7 @@ export async function verifyAssertion(page, claim, tree) {
|
|
|
37
36
|
// Deterministic path: store_keys present, or smart mode is OFF
|
|
38
37
|
if (hasStoreKeys || !config.current.smart) {
|
|
39
38
|
log.helper(`[assertion] deterministic claim=${preview(assertionClaim, 80)}`);
|
|
40
|
-
const resolved = subChecks.map(resolveSub);
|
|
39
|
+
const resolved = await Promise.all(subChecks.map(resolveSub));
|
|
41
40
|
const result = await callEvaluateApi(assertionClaim, compositeOp, resolved);
|
|
42
41
|
log.helper(`[assertion] result status=${result.status ?? 'unknown'}`);
|
|
43
42
|
return result;
|
|
@@ -58,7 +57,7 @@ export async function verifyAssertion(page, claim, tree) {
|
|
|
58
57
|
if (tree.verification !== undefined) {
|
|
59
58
|
body['verification'] = tree.verification;
|
|
60
59
|
}
|
|
61
|
-
const resp = await fetchWithAuth(`${
|
|
60
|
+
const resp = await fetchWithAuth(`${config.current.aiApiHost}/api/v1/assertions/verify`, {
|
|
62
61
|
method: 'POST',
|
|
63
62
|
headers: { 'content-type': 'application/json' },
|
|
64
63
|
body: JSON.stringify(body),
|
|
@@ -72,7 +71,7 @@ export async function verifyAssertion(page, claim, tree) {
|
|
|
72
71
|
return result;
|
|
73
72
|
}
|
|
74
73
|
export async function evaluateBranch(subChecks, compositeOperator = 'and') {
|
|
75
|
-
const resolved = subChecks.map(resolveSub);
|
|
74
|
+
const resolved = await Promise.all(subChecks.map(resolveSub));
|
|
76
75
|
if (resolved.length === 0)
|
|
77
76
|
return false;
|
|
78
77
|
const claim = `Branch condition (${compositeOperator})`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assertion.js","sourceRoot":"","sources":["../../src/helpers/assertion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"assertion.js","sourceRoot":"","sources":["../../src/helpers/assertion.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,18 @@ export interface AuthBasic {
|
|
|
11
11
|
password?: string;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
-
export
|
|
14
|
+
export interface AuthAwsSignature {
|
|
15
|
+
type: 'aws-signature';
|
|
16
|
+
data: {
|
|
17
|
+
region?: string;
|
|
18
|
+
service_name?: string;
|
|
19
|
+
access_key: string;
|
|
20
|
+
secret_key: string;
|
|
21
|
+
session_token?: string;
|
|
22
|
+
add_to?: 'headers' | 'params';
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export type Authorization = AuthBearer | AuthBasic | AuthAwsSignature | string;
|
|
15
26
|
export interface ApiRequest {
|
|
16
27
|
method: string;
|
|
17
28
|
url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeApi.d.ts","sourceRoot":"","sources":["../../src/helpers/executeApi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"executeApi.d.ts","sourceRoot":"","sources":["../../src/helpers/executeApi.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IAAG,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE;AACxE,MAAM,WAAW,SAAS;IAAI,IAAI,EAAE,OAAO,CAAC;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;KAC/B,CAAC;CACH;AACD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAE/E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA6JtE"}
|
|
@@ -1,15 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveVar } from '../vars.js';
|
|
2
|
+
import { config } from '../config.js';
|
|
2
3
|
import { log, preview } from '../log.js';
|
|
3
|
-
function resolve(input) { return
|
|
4
|
+
function resolve(input) { return resolveVar(input); }
|
|
4
5
|
export async function executeApi(req) {
|
|
5
|
-
const url = new URL(resolve(req.url));
|
|
6
|
+
const url = new URL(await resolve(req.url));
|
|
7
|
+
if (url.protocol === 'ws:' || url.protocol === 'wss:') {
|
|
8
|
+
throw new Error('Websockets not supported');
|
|
9
|
+
}
|
|
10
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
11
|
+
throw new Error(`Invalid URL: ${req.url}`);
|
|
12
|
+
}
|
|
6
13
|
if (req.params) {
|
|
7
14
|
for (const [k, val] of Object.entries(req.params))
|
|
8
|
-
url.searchParams.set(k, resolve(val));
|
|
15
|
+
url.searchParams.set(k, await resolve(val));
|
|
9
16
|
}
|
|
10
17
|
const headers = {};
|
|
11
18
|
for (const [k, val] of Object.entries(req.headers ?? {}))
|
|
12
|
-
headers[k] = resolve(val);
|
|
19
|
+
headers[k] = await resolve(val);
|
|
20
|
+
for (const hval of Object.values(headers)) {
|
|
21
|
+
if (hval === 'text/event-stream')
|
|
22
|
+
throw new Error('SSE not supported');
|
|
23
|
+
}
|
|
24
|
+
// Strip multipart/form-data so fetch auto-generates the boundary.
|
|
25
|
+
for (const k of Object.keys(headers)) {
|
|
26
|
+
if (k.toLowerCase() === 'content-type' && headers[k] === 'multipart/form-data') {
|
|
27
|
+
delete headers[k];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!('User-Agent' in headers) && !('user-agent' in headers)) {
|
|
31
|
+
headers['User-Agent'] = 'Mozilla/5.0';
|
|
32
|
+
}
|
|
13
33
|
// Python: auth may be a dict OR a JSON-encoded string.
|
|
14
34
|
let auth;
|
|
15
35
|
if (typeof req.authorization === 'string') {
|
|
@@ -21,31 +41,99 @@ export async function executeApi(req) {
|
|
|
21
41
|
else {
|
|
22
42
|
auth = req.authorization;
|
|
23
43
|
}
|
|
24
|
-
if (auth?.type === 'bearer' && auth.data.token) {
|
|
25
|
-
headers['Authorization'] = `Bearer ${resolve(auth.data.token)}`;
|
|
26
|
-
}
|
|
27
|
-
else if (auth?.type === 'basic' && auth.data.username) {
|
|
28
|
-
const u = resolve(auth.data.username);
|
|
29
|
-
const p = resolve(auth.data.password ?? '');
|
|
30
|
-
headers['Authorization'] = `Basic ${Buffer.from(`${u}:${p}`).toString('base64')}`;
|
|
31
|
-
}
|
|
32
44
|
let body = null;
|
|
33
45
|
if (req.body !== undefined && req.body !== null) {
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
const ct = (headers['Content-Type'] || headers['content-type'] || '').toLowerCase();
|
|
47
|
+
if (typeof req.body === 'string' && ct === 'application/x-www-form-urlencoded') {
|
|
48
|
+
const resolvedBody = await resolve(req.body);
|
|
49
|
+
try {
|
|
50
|
+
body = new URLSearchParams(resolvedBody).toString();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
body = resolvedBody;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (typeof req.body === 'string') {
|
|
57
|
+
body = await resolve(req.body);
|
|
58
|
+
}
|
|
36
59
|
else {
|
|
37
60
|
body = JSON.stringify(req.body);
|
|
38
61
|
if (!headers['content-type'])
|
|
39
62
|
headers['content-type'] = 'application/json';
|
|
40
63
|
}
|
|
41
64
|
}
|
|
65
|
+
if (auth?.type === 'bearer' && auth.data.token) {
|
|
66
|
+
headers['Authorization'] = `Bearer ${await resolve(auth.data.token)}`;
|
|
67
|
+
}
|
|
68
|
+
else if (auth?.type === 'basic' && auth.data.username) {
|
|
69
|
+
const u = await resolve(auth.data.username);
|
|
70
|
+
const p = await resolve(auth.data.password ?? '');
|
|
71
|
+
headers['Authorization'] = `Basic ${Buffer.from(`${u}:${p}`).toString('base64')}`;
|
|
72
|
+
}
|
|
73
|
+
else if (auth?.type === 'aws-signature') {
|
|
74
|
+
// Resolve all auth fields first so {{secrets.X}} / {{global.X}} reach aws4 as real creds.
|
|
75
|
+
try {
|
|
76
|
+
const aws4 = (await import('aws4')).default;
|
|
77
|
+
const region = await resolve(auth.data.region ?? 'us-east-1');
|
|
78
|
+
const service = await resolve(auth.data.service_name ?? '');
|
|
79
|
+
const accessKey = await resolve(auth.data.access_key);
|
|
80
|
+
const secretKey = await resolve(auth.data.secret_key);
|
|
81
|
+
const sessionTok = auth.data.session_token
|
|
82
|
+
? await resolve(auth.data.session_token)
|
|
83
|
+
: undefined;
|
|
84
|
+
const signedBody = typeof body === 'string' ? body : undefined;
|
|
85
|
+
const opts = {
|
|
86
|
+
host: url.host,
|
|
87
|
+
path: url.pathname + url.search,
|
|
88
|
+
method: req.method.toUpperCase(),
|
|
89
|
+
service,
|
|
90
|
+
region,
|
|
91
|
+
body: signedBody,
|
|
92
|
+
headers: { ...headers },
|
|
93
|
+
};
|
|
94
|
+
if (auth.data.add_to === 'params')
|
|
95
|
+
opts.signQuery = true;
|
|
96
|
+
const creds = {
|
|
97
|
+
accessKeyId: accessKey,
|
|
98
|
+
secretAccessKey: secretKey,
|
|
99
|
+
};
|
|
100
|
+
if (sessionTok !== undefined)
|
|
101
|
+
creds.sessionToken = sessionTok;
|
|
102
|
+
const signed = aws4.sign(opts, creds);
|
|
103
|
+
if (auth.data.add_to === 'params' && signed.path) {
|
|
104
|
+
const signedUrl = new URL(`${url.protocol}//${signed.host ?? url.host}${signed.path}`);
|
|
105
|
+
for (const [k, v] of signedUrl.searchParams)
|
|
106
|
+
url.searchParams.set(k, v);
|
|
107
|
+
}
|
|
108
|
+
else if (signed.headers) {
|
|
109
|
+
Object.assign(headers, signed.headers);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
log.helper(`[execute_api] AWS Signature auth failed: ${String(e)}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
42
116
|
log.helper(`[execute_api] ${req.method} ${preview(url.toString(), 80)}`);
|
|
43
117
|
const started = Date.now();
|
|
44
118
|
const ac = new AbortController();
|
|
45
119
|
const timer = setTimeout(() => ac.abort(), req.timeout ?? 30_000);
|
|
120
|
+
// req.verify: PY passes into httpx; Node fetch has no direct equivalent — gap acknowledged.
|
|
121
|
+
let dispatcher;
|
|
122
|
+
if (config.current.runTarget === 'cloud') {
|
|
123
|
+
const { ProxyAgent } = await import('undici');
|
|
124
|
+
dispatcher = new ProxyAgent('http://127.0.0.1:22000');
|
|
125
|
+
}
|
|
126
|
+
const fetchOpts = {
|
|
127
|
+
method: req.method,
|
|
128
|
+
headers,
|
|
129
|
+
body,
|
|
130
|
+
signal: ac.signal,
|
|
131
|
+
};
|
|
132
|
+
if (dispatcher)
|
|
133
|
+
fetchOpts.dispatcher = dispatcher;
|
|
46
134
|
let resp;
|
|
47
135
|
try {
|
|
48
|
-
resp = await fetch(url.toString(),
|
|
136
|
+
resp = await fetch(url.toString(), fetchOpts);
|
|
49
137
|
}
|
|
50
138
|
finally {
|
|
51
139
|
clearTimeout(timer);
|
|
@@ -71,13 +159,13 @@ export async function executeApi(req) {
|
|
|
71
159
|
}
|
|
72
160
|
}
|
|
73
161
|
const text = await resp.text();
|
|
74
|
-
let
|
|
162
|
+
let responseBody = text;
|
|
75
163
|
if (respHeaders['content-type']?.includes('application/json')) {
|
|
76
164
|
try {
|
|
77
|
-
|
|
165
|
+
responseBody = JSON.parse(text);
|
|
78
166
|
}
|
|
79
|
-
catch { }
|
|
167
|
+
catch { /* not valid JSON — keep text */ }
|
|
80
168
|
}
|
|
81
|
-
return { status: resp.status, headers: respHeaders, cookies, response_body:
|
|
169
|
+
return { status: resp.status, headers: respHeaders, cookies, response_body: responseBody, body: text, time: elapsed };
|
|
82
170
|
}
|
|
83
171
|
//# sourceMappingURL=executeApi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeApi.js","sourceRoot":"","sources":["../../src/helpers/executeApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"executeApi.js","sourceRoot":"","sources":["../../src/helpers/executeApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCzC,SAAS,OAAO,CAAC,KAAa,IAAqB,OAAO,UAAU,CAAS,KAAK,CAAC,CAAC,CAAC,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAe;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5C,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1F,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,IAAI,IAAI,KAAK,mBAAmB;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACzE,CAAC;IAED,kEAAkE;IAClE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,cAAc,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,qBAAqB,EAAE,CAAC;YAC/E,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,EAAE,CAAC;QAC7D,OAAO,CAAC,YAAY,CAAC,GAAG,aAAa,CAAC;IACxC,CAAC;IAED,uDAAuD;IACvD,IAAI,IAAgD,CAAC;IACrD,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC1C,IAAI,CAAC;YAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAmC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACxG,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC;IAC3B,CAAC;IAED,IAAI,IAAI,GAAoB,IAAI,CAAC;IACjC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACpF,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,KAAK,mCAAmC,EAAE,CAAC;YAC/E,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,YAAY,CAAC;YACtB,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxC,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;gBAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAC7E,CAAC;IACH,CAAC;IAED,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACxE,CAAC;SAAM,IAAI,IAAI,EAAE,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxD,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACpF,CAAC;SAAM,IAAI,IAAI,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;QAC1C,0FAA0F;QAC1F,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa;gBACxC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;gBACxC,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,UAAU,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAE/D,MAAM,IAAI,GAA4B;gBACpC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM;gBAC/B,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE;gBAChC,OAAO;gBACP,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE;aACxB,CAAC;YACF,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YAEzD,MAAM,KAAK,GAA4E;gBACrF,WAAW,EAAE,SAAS;gBACtB,eAAe,EAAE,SAAS;aAC3B,CAAC;YACF,IAAI,UAAU,KAAK,SAAS;gBAAE,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC;YAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAuE,CAAC;YAE5G,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBACvF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,CAAC,YAAY;oBAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1E,CAAC;iBAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC1B,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,MAAM,CAAC,4CAA4C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;IAElE,4FAA4F;IAC5F,IAAI,UAA+B,CAAC;IACpC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QACzC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,UAAU,GAAG,IAAI,UAAU,CAAC,wBAAwB,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,SAAS,GAA2C;QACxD,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO;QACP,IAAI;QACJ,MAAM,EAAE,EAAE,CAAC,MAAM;KAClB,CAAC;IACF,IAAI,UAAU;QAAE,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC;IAElD,IAAI,IAAc,CAAC;IACnB,IAAI,CAAC;QAAC,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC;IAAC,CAAC;YAC9C,CAAC;QAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IACrC,GAAG,CAAC,MAAM,CAAC,wBAAwB,IAAI,CAAC,MAAM,SAAS,OAAO,IAAI,CAAC,CAAC;IAEpE,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhE,6GAA6G;IAC7G,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,WAAW,GAAI,IAAI,CAAC,OAAwD,CAAC,YAAY,CAAC;IAChG,MAAM,aAAa,GAAa,OAAO,WAAW,KAAK,UAAU;QAC/D,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAChC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9E,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACvC,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,YAAY,GAAY,IAAI,CAAC;IACjC,IAAI,WAAW,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC;YAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACxH,CAAC"}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
export declare function executeKaneCli(objective: string, page: Page): Promise<Page>;
|
|
3
|
+
interface KaneCliResult {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
exitCode: number;
|
|
7
|
+
}
|
|
8
|
+
/** Spawn kane-cli as a subprocess and collect its output with a timeout. */
|
|
9
|
+
export declare function runKaneCli(cmd: string, args: string[], timeoutMs: number): Promise<KaneCliResult>;
|
|
10
|
+
export {};
|
|
2
11
|
//# sourceMappingURL=kaneCli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kaneCli.d.ts","sourceRoot":"","sources":["../../src/helpers/kaneCli.ts"],"names":[],"mappings":"AAAA,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"kaneCli.d.ts","sourceRoot":"","sources":["../../src/helpers/kaneCli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAevC,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFjF;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,4EAA4E;AAC5E,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CA+BxB"}
|
package/dist/helpers/kaneCli.js
CHANGED
|
@@ -1,5 +1,124 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { chromium } from 'playwright';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import { config } from '../config.js';
|
|
4
|
+
import { sessionState } from '../session.js';
|
|
5
|
+
import { _getReporter } from '../step.js';
|
|
6
|
+
import { LTReporter } from '../reporters/lt.js';
|
|
7
|
+
import { TestmuConfigError } from '../errors.js';
|
|
8
|
+
import { log, preview } from '../log.js';
|
|
9
|
+
// Handoff sequence (cloud + smart only) — PY parity: kane_cli.py:22-137.
|
|
10
|
+
// JS uses browser.close() on a connected browser which only detaches the
|
|
11
|
+
// client; the remote browser stays alive via the relay proxy. No need for
|
|
12
|
+
// PY's private `_connection.stop_async()` hack — verified by A1 integration
|
|
13
|
+
// tests I3/I5.
|
|
14
|
+
export async function executeKaneCli(objective, page) {
|
|
15
|
+
if (!config.current.smart) {
|
|
16
|
+
log.helper('[execute_kane_cli] smart is OFF — branch unresolved, skipping');
|
|
17
|
+
return page;
|
|
18
|
+
}
|
|
19
|
+
if (config.current.runTarget !== 'cloud') {
|
|
20
|
+
log.helper('[execute_kane_cli] run_target is not "cloud" — kane-cli needs the relay proxy, skipping (branch unresolved)');
|
|
21
|
+
return page;
|
|
22
|
+
}
|
|
23
|
+
const relayUrl = sessionState.relayUrl;
|
|
24
|
+
if (!relayUrl) {
|
|
25
|
+
throw new TestmuConfigError('execute_kane_cli: relay proxy not initialized; ensure testmu.run() started the cloud session');
|
|
26
|
+
}
|
|
27
|
+
// NB: PY also checks `pw is None` here (kane_cli.py:60-65) because PY needs the
|
|
28
|
+
// async_playwright() handle for chromium.connect later. JS uses the module-level
|
|
29
|
+
// `chromium` import — no handle needed — so the pw gate has no JS analog.
|
|
30
|
+
const currentUrl = page.url();
|
|
31
|
+
const browser = page.context().browser();
|
|
32
|
+
if (!browser) {
|
|
33
|
+
throw new TestmuConfigError('execute_kane_cli: page has no browser (detached?)');
|
|
34
|
+
}
|
|
35
|
+
const username = process.env['LT_USERNAME'] ?? '';
|
|
36
|
+
const accessKey = process.env['LT_ACCESS_KEY'] ?? '';
|
|
37
|
+
const envName = process.env['TESTMUAI_ENV'] ?? 'prod';
|
|
38
|
+
log.helper(`[execute_kane_cli] objective=${preview(objective, 80)}`);
|
|
39
|
+
log.helper('[execute_kane_cli] handing off browser to kane-cli...');
|
|
40
|
+
// Step 1: Disconnect from the remote browser but keep it alive via the relay.
|
|
41
|
+
try {
|
|
42
|
+
await browser.close();
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
log.helper(`[execute_kane_cli] disconnect warning: ${String(e)}`);
|
|
46
|
+
}
|
|
47
|
+
// Step 2: Spawn kane-cli pointing at our relay URL.
|
|
48
|
+
const args = [
|
|
49
|
+
'run', objective,
|
|
50
|
+
'--url', currentUrl,
|
|
51
|
+
'--ws-endpoint', relayUrl,
|
|
52
|
+
'--username', username,
|
|
53
|
+
'--access-key', accessKey,
|
|
54
|
+
'--env', envName,
|
|
55
|
+
'--local',
|
|
56
|
+
'--agent',
|
|
57
|
+
];
|
|
58
|
+
const result = await runKaneCli('kane-cli', args, 600_000);
|
|
59
|
+
if (result.stdout)
|
|
60
|
+
log.helper(`[execute_kane_cli] stdout: ${preview(result.stdout, 2000)}`);
|
|
61
|
+
if (result.stderr)
|
|
62
|
+
log.helper(`[execute_kane_cli] stderr: ${preview(result.stderr, 2000)}`);
|
|
63
|
+
if (result.exitCode !== 0) {
|
|
64
|
+
throw new Error(`kane-cli failed (exit ${result.exitCode}): ${result.stderr}`);
|
|
65
|
+
}
|
|
66
|
+
// Step 3: Reconnect via the relay; proxy replays state.
|
|
67
|
+
log.helper('[execute_kane_cli] reconnecting test to relay...');
|
|
68
|
+
const newBrowser = await chromium.connect(relayUrl, { timeout: 120_000 });
|
|
69
|
+
// Step 4: Resolve a page from the reconnected browser.
|
|
70
|
+
let newPage;
|
|
71
|
+
const ctxs = newBrowser.contexts();
|
|
72
|
+
if (ctxs.length > 0) {
|
|
73
|
+
const ctx = ctxs[0];
|
|
74
|
+
const pages = ctx.pages();
|
|
75
|
+
newPage = pages.length > 0 ? pages[pages.length - 1] : await ctx.newPage();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const ctx = await newBrowser.newContext();
|
|
79
|
+
newPage = await ctx.newPage();
|
|
80
|
+
}
|
|
81
|
+
log.helper(`[execute_kane_cli] reconnected — page URL: ${newPage.url()}`);
|
|
82
|
+
// Step 5: Re-wire LT reporter's page reference.
|
|
83
|
+
const rep = _getReporter();
|
|
84
|
+
if (rep instanceof LTReporter)
|
|
85
|
+
rep._setPage(newPage);
|
|
86
|
+
return newPage;
|
|
87
|
+
}
|
|
88
|
+
/** Spawn kane-cli as a subprocess and collect its output with a timeout. */
|
|
89
|
+
export async function runKaneCli(cmd, args, timeoutMs) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
92
|
+
const stdout = [];
|
|
93
|
+
const stderr = [];
|
|
94
|
+
child.stdout?.on('data', (chunk) => stdout.push(chunk));
|
|
95
|
+
child.stderr?.on('data', (chunk) => stderr.push(chunk));
|
|
96
|
+
let settled = false;
|
|
97
|
+
const timer = setTimeout(() => {
|
|
98
|
+
if (settled)
|
|
99
|
+
return;
|
|
100
|
+
settled = true;
|
|
101
|
+
child.kill('SIGKILL');
|
|
102
|
+
reject(new Error(`kane-cli timed out after ${timeoutMs}ms`));
|
|
103
|
+
}, timeoutMs);
|
|
104
|
+
child.on('error', (err) => {
|
|
105
|
+
if (settled)
|
|
106
|
+
return;
|
|
107
|
+
settled = true;
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
reject(err);
|
|
110
|
+
});
|
|
111
|
+
child.on('close', (exitCode) => {
|
|
112
|
+
if (settled)
|
|
113
|
+
return;
|
|
114
|
+
settled = true;
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
resolve({
|
|
117
|
+
stdout: Buffer.concat(stdout).toString('utf8'),
|
|
118
|
+
stderr: Buffer.concat(stderr).toString('utf8'),
|
|
119
|
+
exitCode: exitCode ?? -1,
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
4
123
|
}
|
|
5
124
|
//# sourceMappingURL=kaneCli.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kaneCli.js","sourceRoot":"","sources":["../../src/helpers/kaneCli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kaneCli.js","sourceRoot":"","sources":["../../src/helpers/kaneCli.ts"],"names":[],"mappings":"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"}
|
package/dist/helpers/math.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export interface MathNode {
|
|
|
2
2
|
operator: string;
|
|
3
3
|
operands: Array<MathNode | number | string>;
|
|
4
4
|
}
|
|
5
|
-
export declare function evaluateMath(node: MathNode): number
|
|
5
|
+
export declare function evaluateMath(node: MathNode): Promise<number>;
|
|
6
6
|
//# sourceMappingURL=math.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/helpers/math.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;CAC7C;AAcD,
|
|
1
|
+
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/helpers/math.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;CAC7C;AAcD,wBAAsB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA+ClE"}
|
package/dist/helpers/math.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveVar } from '../vars.js';
|
|
2
2
|
// Matches Python's _OPERATORS frozenset
|
|
3
3
|
const OPERATORS = new Set([
|
|
4
4
|
'add', 'subtract', 'multiply', 'divide', 'mod', 'pow', 'negate', 'abs',
|
|
5
5
|
// symbolic aliases
|
|
6
6
|
'+', '-', '*', '/',
|
|
7
7
|
]);
|
|
8
|
-
function toNum(val) {
|
|
8
|
+
async function toNum(val) {
|
|
9
9
|
if (typeof val === 'number')
|
|
10
10
|
return val;
|
|
11
11
|
if (typeof val === 'string') {
|
|
12
12
|
// Resolve {{var}} / ${var} placeholders via the variable store
|
|
13
|
-
const resolved =
|
|
13
|
+
const resolved = await resolveVar(val);
|
|
14
14
|
const n = Number(typeof resolved === 'string' ? resolved.trim() : resolved);
|
|
15
15
|
if (Number.isNaN(n))
|
|
16
16
|
throw new Error(`Non-numeric operand encountered: ${JSON.stringify(val)}`);
|
|
@@ -18,15 +18,15 @@ function toNum(val) {
|
|
|
18
18
|
}
|
|
19
19
|
throw new Error(`Unsupported operand type: ${typeof val}`);
|
|
20
20
|
}
|
|
21
|
-
export function evaluateMath(node) {
|
|
21
|
+
export async function evaluateMath(node) {
|
|
22
22
|
const op = node.operator ?? 'add';
|
|
23
23
|
if (!OPERATORS.has(op))
|
|
24
24
|
throw new Error(`Unsupported math operator: ${JSON.stringify(op)}`);
|
|
25
|
-
const resolved = node.operands.map((operand) => {
|
|
25
|
+
const resolved = await Promise.all(node.operands.map(async (operand) => {
|
|
26
26
|
if (typeof operand === 'object' && operand !== null)
|
|
27
27
|
return evaluateMath(operand);
|
|
28
28
|
return toNum(operand);
|
|
29
|
-
});
|
|
29
|
+
}));
|
|
30
30
|
// Validate arity — matches Python's checks
|
|
31
31
|
if ((op === 'subtract' || op === '-' || op === 'divide' || op === '/' || op === 'mod') && resolved.length !== 2) {
|
|
32
32
|
throw new Error(`${op} requires exactly 2 operands, got ${resolved.length}`);
|