@validate.qa/runner 1.0.20 → 1.0.22

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 CHANGED
@@ -66068,6 +66068,8 @@ ${constraints.join("\n")}`);
66068
66068
  function buildMobileFallbackScenarios(input) {
66069
66069
  if (input.mode === "survey")
66070
66070
  return [];
66071
+ if (input.featureName?.trim())
66072
+ return [];
66071
66073
  const orderedScreens = targetAppScreens(input.graph, input.appId).filter((state2) => state2.screenType?.toLowerCase() !== "error").filter((state2) => state2.visited || state2.firstSeenIteration === 0).sort((a, b) => a.firstSeenIteration - b.firstSeenIteration);
66072
66074
  if (orderedScreens.length === 0)
66073
66075
  return [];
@@ -66215,6 +66217,15 @@ ${constraints.join("\n")}`);
66215
66217
  fallbackReason: result.fallbackReason ?? "Mobile planner produced no scenarios"
66216
66218
  };
66217
66219
  }
66220
+ if (input.featureName?.trim()) {
66221
+ return {
66222
+ ...result,
66223
+ featureGroups: mobileFeatureGroups,
66224
+ warning: [result.warning, `Deep discovery could not plan any scenarios for "${input.featureName}" \u2014 the explorer did not reach that feature's screens this run. If the feature requires a signed-in session, verify TEST_USER_EMAIL / TEST_USER_PASSWORD are valid for this app, then re-run.`].filter(Boolean).join(" | "),
66225
+ fallbackUsed: true,
66226
+ fallbackReason: result.fallbackReason ?? `Planner produced no scenarios for feature "${input.featureName}"`
66227
+ };
66228
+ }
66218
66229
  }
66219
66230
  if (input.mode === "survey" && result.featureGroups.length === 0 && mobileFeatureGroups.length > 0) {
66220
66231
  return {
@@ -66495,7 +66506,8 @@ Max iterations: ${MAX_SCENARIO_ITERATIONS}. You will be warned near the end.`;
66495
66506
  This app has stored login credentials under these keys:
66496
66507
  ${keyList}
66497
66508
 
66498
- When a scenario needs a signed-in session or fills a login/sign-up form, fill each credential field with \`mobile_fill_credential\`: pass the field ref and the KEY (e.g. \`{ ref: "e5", credentialKey: "TEST_USER_EMAIL" }\`). The runner types the real value on the device and the generated test stores a \`{{KEY}}\` placeholder that replay resolves \u2014 you never see, log, or echo the secret.
66509
+ When a scenario needs a signed-in session, complete the FULL login sequence \u2014 filling the fields alone does NOT log you in:
66510
+ 1. Reach the email/password form. 2. Fill each credential field with \`mobile_fill_credential\` (pass the field ref and the KEY, e.g. \`{ ref: "e5", credentialKey: "TEST_USER_EMAIL" }\`) \u2014 the runner types the real value on the device and the generated test stores a \`{{KEY}}\` placeholder that replay resolves; you never see the secret. 3. TAP THE SUBMIT button (Sign In / Log In / Continue). 4. Re-snapshot and VERIFY an authenticated screen appeared. If login fails twice, do NOT keep retrying or wander: call finish_generate with verified:false and say the login could not be completed (the credentials may be invalid for this app).
66499
66511
 
66500
66512
  SECURITY RULES:
66501
66513
  - NEVER call \`mobile_type\` with a real email, password, or token value \u2014 the runner will REJECT the call and you lose an iteration. Use \`mobile_fill_credential\` for every credential field.
@@ -328471,7 +328483,7 @@ var require_package4 = __commonJS({
328471
328483
  "package.json"(exports2, module2) {
328472
328484
  module2.exports = {
328473
328485
  name: "@validate.qa/runner",
328474
- version: "1.0.20",
328486
+ version: "1.0.22",
328475
328487
  description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
328476
328488
  bin: {
328477
328489
  "validate-runner": "dist/cli.js"
@@ -330240,6 +330252,10 @@ async function startMobileNetworkCapture(options) {
330240
330252
 
330241
330253
  // src/services/appium-executor.ts
330242
330254
  var DEFAULT_STEP_TIMEOUT_MS = 1e4;
330255
+ var MOBILE_NEW_COMMAND_TIMEOUT_SECONDS = (() => {
330256
+ const raw = Number(process.env.VALIDATEQA_MOBILE_NEW_COMMAND_TIMEOUT);
330257
+ return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 600;
330258
+ })();
330243
330259
  var VERIFICATION_ACTIONS = /* @__PURE__ */ new Set(["assertVisible", "assertText", "waitForElement"]);
330244
330260
  var WD_SESSION_CREATE_TIMEOUT_MS = 12e4;
330245
330261
  var WD_ACTION_TIMEOUT_MS = 3e4;
@@ -330339,6 +330355,14 @@ async function createSession(target) {
330339
330355
  ...target.deviceId ? { "appium:udid": target.deviceId } : {},
330340
330356
  ...target.platformVersion ? { "appium:platformVersion": target.platformVersion } : {},
330341
330357
  "appium:noReset": true,
330358
+ // Appium's default newCommandTimeout is 60s — it kills the session if no
330359
+ // WebDriver command arrives in that window. A discovery session is driven
330360
+ // by an AI loop where a single model turn (or a pause on a permission
330361
+ // dialog) can exceed 60s, so the default silently terminates the session
330362
+ // mid-run and every later command 404s ("invalid session id"), failing the
330363
+ // whole survey. The runner owns session teardown explicitly, so a long
330364
+ // idle window is safe. Env-overridable.
330365
+ "appium:newCommandTimeout": MOBILE_NEW_COMMAND_TIMEOUT_SECONDS,
330342
330366
  ...realCaps
330343
330367
  } : {
330344
330368
  platformName: "Android",
@@ -330347,6 +330371,8 @@ async function createSession(target) {
330347
330371
  ...target.deviceId ? { "appium:udid": target.deviceId } : {},
330348
330372
  ...target.platformVersion ? { "appium:platformVersion": target.platformVersion } : {},
330349
330373
  "appium:noReset": true,
330374
+ // See the iOS branch: the 60s default kills AI-driven discovery sessions.
330375
+ "appium:newCommandTimeout": MOBILE_NEW_COMMAND_TIMEOUT_SECONDS,
330350
330376
  ...realCaps
330351
330377
  };
330352
330378
  const result = await wdRequest("/session", {
package/dist/cli.mjs CHANGED
@@ -66073,6 +66073,8 @@ ${constraints.join("\n")}`);
66073
66073
  function buildMobileFallbackScenarios(input) {
66074
66074
  if (input.mode === "survey")
66075
66075
  return [];
66076
+ if (input.featureName?.trim())
66077
+ return [];
66076
66078
  const orderedScreens = targetAppScreens(input.graph, input.appId).filter((state2) => state2.screenType?.toLowerCase() !== "error").filter((state2) => state2.visited || state2.firstSeenIteration === 0).sort((a, b) => a.firstSeenIteration - b.firstSeenIteration);
66077
66079
  if (orderedScreens.length === 0)
66078
66080
  return [];
@@ -66220,6 +66222,15 @@ ${constraints.join("\n")}`);
66220
66222
  fallbackReason: result.fallbackReason ?? "Mobile planner produced no scenarios"
66221
66223
  };
66222
66224
  }
66225
+ if (input.featureName?.trim()) {
66226
+ return {
66227
+ ...result,
66228
+ featureGroups: mobileFeatureGroups,
66229
+ warning: [result.warning, `Deep discovery could not plan any scenarios for "${input.featureName}" \u2014 the explorer did not reach that feature's screens this run. If the feature requires a signed-in session, verify TEST_USER_EMAIL / TEST_USER_PASSWORD are valid for this app, then re-run.`].filter(Boolean).join(" | "),
66230
+ fallbackUsed: true,
66231
+ fallbackReason: result.fallbackReason ?? `Planner produced no scenarios for feature "${input.featureName}"`
66232
+ };
66233
+ }
66223
66234
  }
66224
66235
  if (input.mode === "survey" && result.featureGroups.length === 0 && mobileFeatureGroups.length > 0) {
66225
66236
  return {
@@ -66500,7 +66511,8 @@ Max iterations: ${MAX_SCENARIO_ITERATIONS}. You will be warned near the end.`;
66500
66511
  This app has stored login credentials under these keys:
66501
66512
  ${keyList}
66502
66513
 
66503
- When a scenario needs a signed-in session or fills a login/sign-up form, fill each credential field with \`mobile_fill_credential\`: pass the field ref and the KEY (e.g. \`{ ref: "e5", credentialKey: "TEST_USER_EMAIL" }\`). The runner types the real value on the device and the generated test stores a \`{{KEY}}\` placeholder that replay resolves \u2014 you never see, log, or echo the secret.
66514
+ When a scenario needs a signed-in session, complete the FULL login sequence \u2014 filling the fields alone does NOT log you in:
66515
+ 1. Reach the email/password form. 2. Fill each credential field with \`mobile_fill_credential\` (pass the field ref and the KEY, e.g. \`{ ref: "e5", credentialKey: "TEST_USER_EMAIL" }\`) \u2014 the runner types the real value on the device and the generated test stores a \`{{KEY}}\` placeholder that replay resolves; you never see the secret. 3. TAP THE SUBMIT button (Sign In / Log In / Continue). 4. Re-snapshot and VERIFY an authenticated screen appeared. If login fails twice, do NOT keep retrying or wander: call finish_generate with verified:false and say the login could not be completed (the credentials may be invalid for this app).
66504
66516
 
66505
66517
  SECURITY RULES:
66506
66518
  - NEVER call \`mobile_type\` with a real email, password, or token value \u2014 the runner will REJECT the call and you lose an iteration. Use \`mobile_fill_credential\` for every credential field.
@@ -328476,7 +328488,7 @@ var require_package4 = __commonJS({
328476
328488
  "package.json"(exports, module) {
328477
328489
  module.exports = {
328478
328490
  name: "@validate.qa/runner",
328479
- version: "1.0.20",
328491
+ version: "1.0.22",
328480
328492
  description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
328481
328493
  bin: {
328482
328494
  "validate-runner": "dist/cli.js"
@@ -330248,6 +330260,10 @@ async function startMobileNetworkCapture(options) {
330248
330260
 
330249
330261
  // src/services/appium-executor.ts
330250
330262
  var DEFAULT_STEP_TIMEOUT_MS = 1e4;
330263
+ var MOBILE_NEW_COMMAND_TIMEOUT_SECONDS = (() => {
330264
+ const raw = Number(process.env.VALIDATEQA_MOBILE_NEW_COMMAND_TIMEOUT);
330265
+ return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 600;
330266
+ })();
330251
330267
  var VERIFICATION_ACTIONS = /* @__PURE__ */ new Set(["assertVisible", "assertText", "waitForElement"]);
330252
330268
  var WD_SESSION_CREATE_TIMEOUT_MS = 12e4;
330253
330269
  var WD_ACTION_TIMEOUT_MS = 3e4;
@@ -330347,6 +330363,14 @@ async function createSession(target) {
330347
330363
  ...target.deviceId ? { "appium:udid": target.deviceId } : {},
330348
330364
  ...target.platformVersion ? { "appium:platformVersion": target.platformVersion } : {},
330349
330365
  "appium:noReset": true,
330366
+ // Appium's default newCommandTimeout is 60s — it kills the session if no
330367
+ // WebDriver command arrives in that window. A discovery session is driven
330368
+ // by an AI loop where a single model turn (or a pause on a permission
330369
+ // dialog) can exceed 60s, so the default silently terminates the session
330370
+ // mid-run and every later command 404s ("invalid session id"), failing the
330371
+ // whole survey. The runner owns session teardown explicitly, so a long
330372
+ // idle window is safe. Env-overridable.
330373
+ "appium:newCommandTimeout": MOBILE_NEW_COMMAND_TIMEOUT_SECONDS,
330350
330374
  ...realCaps
330351
330375
  } : {
330352
330376
  platformName: "Android",
@@ -330355,6 +330379,8 @@ async function createSession(target) {
330355
330379
  ...target.deviceId ? { "appium:udid": target.deviceId } : {},
330356
330380
  ...target.platformVersion ? { "appium:platformVersion": target.platformVersion } : {},
330357
330381
  "appium:noReset": true,
330382
+ // See the iOS branch: the 60s default kills AI-driven discovery sessions.
330383
+ "appium:newCommandTimeout": MOBILE_NEW_COMMAND_TIMEOUT_SECONDS,
330358
330384
  ...realCaps
330359
330385
  };
330360
330386
  const result = await wdRequest("/session", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@validate.qa/runner",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
5
5
  "bin": {
6
6
  "validate-runner": "dist/cli.js"