@validate.qa/runner 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +48 -25
- package/dist/cli.mjs +48 -25
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1264,7 +1264,8 @@ var init_constants = __esm({
|
|
|
1264
1264
|
"GROK_API_KEY",
|
|
1265
1265
|
"MINIMAX_API_KEY",
|
|
1266
1266
|
"ANTHROPIC_API_KEY",
|
|
1267
|
-
"NVIDIA_API_KEY"
|
|
1267
|
+
"NVIDIA_API_KEY",
|
|
1268
|
+
"DEEPSEEK_API_KEY"
|
|
1268
1269
|
]);
|
|
1269
1270
|
SPAWNED_ENV_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
1270
1271
|
// Runtime essentials - Node.js and Playwright need these to function
|
|
@@ -1605,11 +1606,11 @@ function buildAppiumCode(testName, target, steps) {
|
|
|
1605
1606
|
const x = Math.round(bounds.x + bounds.width / 2);
|
|
1606
1607
|
const y = Math.round(bounds.y + bounds.height / 2);
|
|
1607
1608
|
lines.push(` try {`);
|
|
1608
|
-
lines.push(` await (await findFirst(driver, ${candidatesLiteral})).addValue(${toJsStringLiteral(step.value ?? "")});`);
|
|
1609
|
-
lines.push(` } catch {`);
|
|
1610
1609
|
lines.push(` await __tapAt(driver, ${x}, ${y});`);
|
|
1611
1610
|
lines.push(` await driver.pause(${MOBILE_FOCUS_SETTLE_MS});`);
|
|
1612
1611
|
lines.push(` await __typeIntoFocused(driver, ${toJsStringLiteral(step.value ?? "")});`);
|
|
1612
|
+
lines.push(` } catch {`);
|
|
1613
|
+
lines.push(` await (await findFirst(driver, ${candidatesLiteral})).addValue(${toJsStringLiteral(step.value ?? "")});`);
|
|
1613
1614
|
lines.push(` }`);
|
|
1614
1615
|
} else {
|
|
1615
1616
|
lines.push(` await (await findFirst(driver, ${candidatesLiteral})).addValue(${toJsStringLiteral(step.value ?? "")});`);
|
|
@@ -2133,6 +2134,7 @@ var init_audit_pricing = __esm({
|
|
|
2133
2134
|
"MiniMax-M2.7": { input: 0.3, output: 1.2 },
|
|
2134
2135
|
"MiniMax-M2.7-highspeed": { input: 0.6, output: 2.4 },
|
|
2135
2136
|
"MiniMax-M2": { input: 0.3, output: 1.2 },
|
|
2137
|
+
"deepseek-v4-flash": { input: 0.14, output: 0.28 },
|
|
2136
2138
|
// Whisper bills per-minute, not per-token
|
|
2137
2139
|
"whisper-1": null,
|
|
2138
2140
|
// Historical / deprecated (kept so old audit rows still show a cost).
|
|
@@ -326286,7 +326288,7 @@ var require_package4 = __commonJS({
|
|
|
326286
326288
|
"package.json"(exports2, module2) {
|
|
326287
326289
|
module2.exports = {
|
|
326288
326290
|
name: "@validate.qa/runner",
|
|
326289
|
-
version: "1.0.
|
|
326291
|
+
version: "1.0.8",
|
|
326290
326292
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
326291
326293
|
bin: {
|
|
326292
326294
|
"validate-runner": "dist/cli.js"
|
|
@@ -327920,6 +327922,18 @@ async function sendKeysToFocusedInput(sessionId, value) {
|
|
|
327920
327922
|
body: JSON.stringify({ text: value, value: Array.from(value) })
|
|
327921
327923
|
});
|
|
327922
327924
|
}
|
|
327925
|
+
async function trySendElementValue(sessionId, elementId, value) {
|
|
327926
|
+
try {
|
|
327927
|
+
await wdRequest(`/session/${sessionId}/element/${elementId}/value`, {
|
|
327928
|
+
method: "POST",
|
|
327929
|
+
body: JSON.stringify({ text: value })
|
|
327930
|
+
});
|
|
327931
|
+
return null;
|
|
327932
|
+
} catch (error2) {
|
|
327933
|
+
if (isTransportError(error2)) throw error2;
|
|
327934
|
+
return error2;
|
|
327935
|
+
}
|
|
327936
|
+
}
|
|
327923
327937
|
function shouldAbortAfterStepFailure(action) {
|
|
327924
327938
|
switch (action) {
|
|
327925
327939
|
case "launchApp":
|
|
@@ -327961,12 +327975,28 @@ async function executeType(sessionId, step) {
|
|
|
327961
327975
|
const value = String(step.value);
|
|
327962
327976
|
const bounds = boundsFromStep(step);
|
|
327963
327977
|
let elementId = null;
|
|
327978
|
+
let lastInputError = null;
|
|
327964
327979
|
let tappedBounds = false;
|
|
327980
|
+
if (bounds) {
|
|
327981
|
+
await tapCoordinates(sessionId, bounds);
|
|
327982
|
+
tappedBounds = true;
|
|
327983
|
+
await new Promise((resolve) => setTimeout(resolve, MOBILE_FOCUS_SETTLE_MS));
|
|
327984
|
+
elementId = await getActiveElementId(sessionId);
|
|
327985
|
+
if (elementId) {
|
|
327986
|
+
lastInputError = await trySendElementValue(sessionId, elementId, value);
|
|
327987
|
+
if (!lastInputError) return;
|
|
327988
|
+
elementId = null;
|
|
327989
|
+
}
|
|
327990
|
+
}
|
|
327965
327991
|
if (step.target) {
|
|
327966
327992
|
try {
|
|
327967
327993
|
elementId = await findElement(sessionId, step.target, readStepTimeout(step));
|
|
327994
|
+
lastInputError = await trySendElementValue(sessionId, elementId, value);
|
|
327995
|
+
if (!lastInputError) return;
|
|
327996
|
+
elementId = null;
|
|
327968
327997
|
} catch (error2) {
|
|
327969
327998
|
if (!bounds) throw error2;
|
|
327999
|
+
lastInputError = error2;
|
|
327970
328000
|
}
|
|
327971
328001
|
}
|
|
327972
328002
|
if (!elementId && bounds) {
|
|
@@ -327979,14 +328009,11 @@ async function executeType(sessionId, step) {
|
|
|
327979
328009
|
elementId = await getActiveElementId(sessionId);
|
|
327980
328010
|
}
|
|
327981
328011
|
if (elementId) {
|
|
327982
|
-
|
|
327983
|
-
|
|
327984
|
-
|
|
327985
|
-
|
|
327986
|
-
|
|
327987
|
-
return;
|
|
327988
|
-
} catch (error2) {
|
|
327989
|
-
if (!bounds) throw error2;
|
|
328012
|
+
lastInputError = await trySendElementValue(sessionId, elementId, value);
|
|
328013
|
+
if (!lastInputError) return;
|
|
328014
|
+
elementId = null;
|
|
328015
|
+
if (!bounds) {
|
|
328016
|
+
throw lastInputError instanceof Error ? lastInputError : new Error(String(lastInputError));
|
|
327990
328017
|
}
|
|
327991
328018
|
}
|
|
327992
328019
|
if (bounds) {
|
|
@@ -327994,10 +328021,15 @@ async function executeType(sessionId, step) {
|
|
|
327994
328021
|
await tapCoordinates(sessionId, bounds);
|
|
327995
328022
|
await new Promise((resolve) => setTimeout(resolve, MOBILE_FOCUS_SETTLE_MS));
|
|
327996
328023
|
}
|
|
327997
|
-
|
|
327998
|
-
|
|
328024
|
+
try {
|
|
328025
|
+
await sendKeysToFocusedInput(sessionId, value);
|
|
328026
|
+
return;
|
|
328027
|
+
} catch (error2) {
|
|
328028
|
+
if (isTransportError(error2)) throw error2;
|
|
328029
|
+
lastInputError = error2;
|
|
328030
|
+
}
|
|
327999
328031
|
}
|
|
328000
|
-
throw new Error(
|
|
328032
|
+
throw new Error(`TYPE step could not send text to the focused target${lastInputError instanceof Error ? `: ${lastInputError.message}` : ""}`);
|
|
328001
328033
|
}
|
|
328002
328034
|
async function executeClear(sessionId, step) {
|
|
328003
328035
|
const bounds = boundsFromStep(step);
|
|
@@ -330657,16 +330689,7 @@ async function executeRun(run2, opts, headers, requestLiveBrowserHeartbeat = ()
|
|
|
330657
330689
|
}
|
|
330658
330690
|
return;
|
|
330659
330691
|
}
|
|
330660
|
-
if (runMode === "heal") {
|
|
330661
|
-
if (run2.framework === "APPIUM") {
|
|
330662
|
-
await postResult(opts.serverUrl, headers, run2.runId, {
|
|
330663
|
-
status: "ERROR",
|
|
330664
|
-
error: "CONFIG_ISSUE: Appium (mobile) tests are not auto-healable; skipped heal.",
|
|
330665
|
-
duration: Date.now() - startTime
|
|
330666
|
-
});
|
|
330667
|
-
log.warn("Skipped heal for APPIUM test (mobile tests are not healable)");
|
|
330668
|
-
return;
|
|
330669
|
-
}
|
|
330692
|
+
if (runMode === "heal" && run2.framework !== "APPIUM") {
|
|
330670
330693
|
const isApiTest2 = Array.isArray(run2.tags) && run2.tags.includes("@api");
|
|
330671
330694
|
if (isApiTest2) {
|
|
330672
330695
|
const testCode = run2.playwrightCode ?? "";
|
package/dist/cli.mjs
CHANGED
|
@@ -1269,7 +1269,8 @@ var init_constants = __esm({
|
|
|
1269
1269
|
"GROK_API_KEY",
|
|
1270
1270
|
"MINIMAX_API_KEY",
|
|
1271
1271
|
"ANTHROPIC_API_KEY",
|
|
1272
|
-
"NVIDIA_API_KEY"
|
|
1272
|
+
"NVIDIA_API_KEY",
|
|
1273
|
+
"DEEPSEEK_API_KEY"
|
|
1273
1274
|
]);
|
|
1274
1275
|
SPAWNED_ENV_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
1275
1276
|
// Runtime essentials - Node.js and Playwright need these to function
|
|
@@ -1610,11 +1611,11 @@ function buildAppiumCode(testName, target, steps) {
|
|
|
1610
1611
|
const x = Math.round(bounds.x + bounds.width / 2);
|
|
1611
1612
|
const y = Math.round(bounds.y + bounds.height / 2);
|
|
1612
1613
|
lines.push(` try {`);
|
|
1613
|
-
lines.push(` await (await findFirst(driver, ${candidatesLiteral})).addValue(${toJsStringLiteral(step.value ?? "")});`);
|
|
1614
|
-
lines.push(` } catch {`);
|
|
1615
1614
|
lines.push(` await __tapAt(driver, ${x}, ${y});`);
|
|
1616
1615
|
lines.push(` await driver.pause(${MOBILE_FOCUS_SETTLE_MS});`);
|
|
1617
1616
|
lines.push(` await __typeIntoFocused(driver, ${toJsStringLiteral(step.value ?? "")});`);
|
|
1617
|
+
lines.push(` } catch {`);
|
|
1618
|
+
lines.push(` await (await findFirst(driver, ${candidatesLiteral})).addValue(${toJsStringLiteral(step.value ?? "")});`);
|
|
1618
1619
|
lines.push(` }`);
|
|
1619
1620
|
} else {
|
|
1620
1621
|
lines.push(` await (await findFirst(driver, ${candidatesLiteral})).addValue(${toJsStringLiteral(step.value ?? "")});`);
|
|
@@ -2138,6 +2139,7 @@ var init_audit_pricing = __esm({
|
|
|
2138
2139
|
"MiniMax-M2.7": { input: 0.3, output: 1.2 },
|
|
2139
2140
|
"MiniMax-M2.7-highspeed": { input: 0.6, output: 2.4 },
|
|
2140
2141
|
"MiniMax-M2": { input: 0.3, output: 1.2 },
|
|
2142
|
+
"deepseek-v4-flash": { input: 0.14, output: 0.28 },
|
|
2141
2143
|
// Whisper bills per-minute, not per-token
|
|
2142
2144
|
"whisper-1": null,
|
|
2143
2145
|
// Historical / deprecated (kept so old audit rows still show a cost).
|
|
@@ -326291,7 +326293,7 @@ var require_package4 = __commonJS({
|
|
|
326291
326293
|
"package.json"(exports, module) {
|
|
326292
326294
|
module.exports = {
|
|
326293
326295
|
name: "@validate.qa/runner",
|
|
326294
|
-
version: "1.0.
|
|
326296
|
+
version: "1.0.8",
|
|
326295
326297
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
326296
326298
|
bin: {
|
|
326297
326299
|
"validate-runner": "dist/cli.js"
|
|
@@ -327928,6 +327930,18 @@ async function sendKeysToFocusedInput(sessionId, value) {
|
|
|
327928
327930
|
body: JSON.stringify({ text: value, value: Array.from(value) })
|
|
327929
327931
|
});
|
|
327930
327932
|
}
|
|
327933
|
+
async function trySendElementValue(sessionId, elementId, value) {
|
|
327934
|
+
try {
|
|
327935
|
+
await wdRequest(`/session/${sessionId}/element/${elementId}/value`, {
|
|
327936
|
+
method: "POST",
|
|
327937
|
+
body: JSON.stringify({ text: value })
|
|
327938
|
+
});
|
|
327939
|
+
return null;
|
|
327940
|
+
} catch (error2) {
|
|
327941
|
+
if (isTransportError(error2)) throw error2;
|
|
327942
|
+
return error2;
|
|
327943
|
+
}
|
|
327944
|
+
}
|
|
327931
327945
|
function shouldAbortAfterStepFailure(action) {
|
|
327932
327946
|
switch (action) {
|
|
327933
327947
|
case "launchApp":
|
|
@@ -327969,12 +327983,28 @@ async function executeType(sessionId, step) {
|
|
|
327969
327983
|
const value = String(step.value);
|
|
327970
327984
|
const bounds = boundsFromStep(step);
|
|
327971
327985
|
let elementId = null;
|
|
327986
|
+
let lastInputError = null;
|
|
327972
327987
|
let tappedBounds = false;
|
|
327988
|
+
if (bounds) {
|
|
327989
|
+
await tapCoordinates(sessionId, bounds);
|
|
327990
|
+
tappedBounds = true;
|
|
327991
|
+
await new Promise((resolve) => setTimeout(resolve, MOBILE_FOCUS_SETTLE_MS));
|
|
327992
|
+
elementId = await getActiveElementId(sessionId);
|
|
327993
|
+
if (elementId) {
|
|
327994
|
+
lastInputError = await trySendElementValue(sessionId, elementId, value);
|
|
327995
|
+
if (!lastInputError) return;
|
|
327996
|
+
elementId = null;
|
|
327997
|
+
}
|
|
327998
|
+
}
|
|
327973
327999
|
if (step.target) {
|
|
327974
328000
|
try {
|
|
327975
328001
|
elementId = await findElement(sessionId, step.target, readStepTimeout(step));
|
|
328002
|
+
lastInputError = await trySendElementValue(sessionId, elementId, value);
|
|
328003
|
+
if (!lastInputError) return;
|
|
328004
|
+
elementId = null;
|
|
327976
328005
|
} catch (error2) {
|
|
327977
328006
|
if (!bounds) throw error2;
|
|
328007
|
+
lastInputError = error2;
|
|
327978
328008
|
}
|
|
327979
328009
|
}
|
|
327980
328010
|
if (!elementId && bounds) {
|
|
@@ -327987,14 +328017,11 @@ async function executeType(sessionId, step) {
|
|
|
327987
328017
|
elementId = await getActiveElementId(sessionId);
|
|
327988
328018
|
}
|
|
327989
328019
|
if (elementId) {
|
|
327990
|
-
|
|
327991
|
-
|
|
327992
|
-
|
|
327993
|
-
|
|
327994
|
-
|
|
327995
|
-
return;
|
|
327996
|
-
} catch (error2) {
|
|
327997
|
-
if (!bounds) throw error2;
|
|
328020
|
+
lastInputError = await trySendElementValue(sessionId, elementId, value);
|
|
328021
|
+
if (!lastInputError) return;
|
|
328022
|
+
elementId = null;
|
|
328023
|
+
if (!bounds) {
|
|
328024
|
+
throw lastInputError instanceof Error ? lastInputError : new Error(String(lastInputError));
|
|
327998
328025
|
}
|
|
327999
328026
|
}
|
|
328000
328027
|
if (bounds) {
|
|
@@ -328002,10 +328029,15 @@ async function executeType(sessionId, step) {
|
|
|
328002
328029
|
await tapCoordinates(sessionId, bounds);
|
|
328003
328030
|
await new Promise((resolve) => setTimeout(resolve, MOBILE_FOCUS_SETTLE_MS));
|
|
328004
328031
|
}
|
|
328005
|
-
|
|
328006
|
-
|
|
328032
|
+
try {
|
|
328033
|
+
await sendKeysToFocusedInput(sessionId, value);
|
|
328034
|
+
return;
|
|
328035
|
+
} catch (error2) {
|
|
328036
|
+
if (isTransportError(error2)) throw error2;
|
|
328037
|
+
lastInputError = error2;
|
|
328038
|
+
}
|
|
328007
328039
|
}
|
|
328008
|
-
throw new Error(
|
|
328040
|
+
throw new Error(`TYPE step could not send text to the focused target${lastInputError instanceof Error ? `: ${lastInputError.message}` : ""}`);
|
|
328009
328041
|
}
|
|
328010
328042
|
async function executeClear(sessionId, step) {
|
|
328011
328043
|
const bounds = boundsFromStep(step);
|
|
@@ -330665,16 +330697,7 @@ async function executeRun(run2, opts, headers, requestLiveBrowserHeartbeat = ()
|
|
|
330665
330697
|
}
|
|
330666
330698
|
return;
|
|
330667
330699
|
}
|
|
330668
|
-
if (runMode === "heal") {
|
|
330669
|
-
if (run2.framework === "APPIUM") {
|
|
330670
|
-
await postResult(opts.serverUrl, headers, run2.runId, {
|
|
330671
|
-
status: "ERROR",
|
|
330672
|
-
error: "CONFIG_ISSUE: Appium (mobile) tests are not auto-healable; skipped heal.",
|
|
330673
|
-
duration: Date.now() - startTime
|
|
330674
|
-
});
|
|
330675
|
-
log.warn("Skipped heal for APPIUM test (mobile tests are not healable)");
|
|
330676
|
-
return;
|
|
330677
|
-
}
|
|
330700
|
+
if (runMode === "heal" && run2.framework !== "APPIUM") {
|
|
330678
330701
|
const isApiTest2 = Array.isArray(run2.tags) && run2.tags.includes("@api");
|
|
330679
330702
|
if (isApiTest2) {
|
|
330680
330703
|
const testCode = run2.playwrightCode ?? "";
|
package/package.json
CHANGED