@validate.qa/runner 1.0.18 → 1.0.19
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 +34 -3
- package/dist/cli.mjs +34 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -62040,7 +62040,7 @@ var require_mobile_explorer = __commonJS({
|
|
|
62040
62040
|
}
|
|
62041
62041
|
sections.push("");
|
|
62042
62042
|
if (mode === "survey") {
|
|
62043
|
-
sections.push(
|
|
62043
|
+
sections.push(`**Mission:** Map every reachable screen. For each new screen: mobile_snapshot -> capture_screen -> record_transition. Get PAST the entry gate into the app's real main content \u2014 the login/landing screens are the ENTRANCE, not the app. If test credentials are provided (see the Test Credentials section), SIGN IN with them FIRST and map the authenticated app; that is the real product surface. Use a guest/demo/skip entry (e.g. "See Demo Profile", "Continue as guest") ONLY as a fallback when no credentials are available or login cannot be completed \u2014 demo mode is a limited sandbox, not the authenticated app. Do NOT submit forms with junk data or mutate real data. Call finish_exploration ONLY when every reachable screen \u2014 including the authenticated content \u2014 has been captured and no unvisited frontier screens remain.`);
|
|
62044
62044
|
} else {
|
|
62045
62045
|
sections.push("**Mission:** Use the focus features like a real user. Tap, type, submit, and observe outcomes. After a meaningful flow, call record_journey. Call finish_exploration when the flows are covered.");
|
|
62046
62046
|
}
|
|
@@ -62098,7 +62098,14 @@ var require_mobile_explorer = __commonJS({
|
|
|
62098
62098
|
This app has stored login credentials under these keys:
|
|
62099
62099
|
${keyList}
|
|
62100
62100
|
|
|
62101
|
-
|
|
62101
|
+
LOG IN FIRST \u2014 before broad exploration. The authenticated app is the real product surface; a survey that only maps the logged-out/demo screens has missed most of the app. This OVERRIDES the "do not submit forms" rule for the login form ONLY. The login sequence is:
|
|
62102
|
+
1. Reach the email/password sign-in form (tap "Sign in with Email" / "Login" from the landing screen if needed).
|
|
62103
|
+
2. Fill the email field: \`mobile_fill_credential({ ref, credentialKey: "TEST_USER_EMAIL" })\`. Fill the password field: \`mobile_fill_credential({ ref, credentialKey: "TEST_USER_PASSWORD" })\`. The runner substitutes the real value on the device; you never see, log, or echo it.
|
|
62104
|
+
3. TAP THE SUBMIT BUTTON (e.g. "Sign In", "Log In", "Continue"). Filling the fields does NOT log you in \u2014 you MUST tap submit.
|
|
62105
|
+
4. VERIFY you are actually signed in: re-snapshot and confirm an authenticated signal appeared (a home/feed/dashboard with real content, an account/profile tab, a "Sign out" option, or your user identity). If you are still on the login form, the login failed \u2014 check for an error, re-enter, and submit again (up to 2 attempts).
|
|
62106
|
+
5. Only AFTER you have confirmed you are signed in, map the authenticated app.
|
|
62107
|
+
|
|
62108
|
+
PREFER real login over any "demo"/"guest"/"skip" entry: those give a limited sandbox, NOT the authenticated app. Use them only if login is impossible.
|
|
62102
62109
|
|
|
62103
62110
|
SECURITY RULES:
|
|
62104
62111
|
- NEVER call \`mobile_type\` with an 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.
|
|
@@ -62405,6 +62412,8 @@ ${existingScreens.slice(0, 100).map((s) => `- ${s.screenId}${s.name ? ` "${s.nam
|
|
|
62405
62412
|
let summary = "";
|
|
62406
62413
|
let truncated = false;
|
|
62407
62414
|
let truncatedReason;
|
|
62415
|
+
let finishRedirects = 0;
|
|
62416
|
+
const MAX_FINISH_REDIRECTS = 2;
|
|
62408
62417
|
try {
|
|
62409
62418
|
try {
|
|
62410
62419
|
const seed = await driver.snapshot();
|
|
@@ -62534,6 +62543,20 @@ ${statePacket}` }
|
|
|
62534
62543
|
continue;
|
|
62535
62544
|
}
|
|
62536
62545
|
if (toolName === "finish_exploration") {
|
|
62546
|
+
const frontier = mode === "survey" ? state2.getFrontier() : [];
|
|
62547
|
+
const budgetRemainingPct = (maxIterations - iteration) / maxIterations;
|
|
62548
|
+
if (frontier.length > 0 && budgetRemainingPct >= 0.2 && finishRedirects < MAX_FINISH_REDIRECTS) {
|
|
62549
|
+
finishRedirects++;
|
|
62550
|
+
const targets = frontier.slice(0, 6).join(", ");
|
|
62551
|
+
log2(`
|
|
62552
|
+
finish_exploration bounced (${finishRedirects}/${MAX_FINISH_REDIRECTS}): ${frontier.length} frontier screen(s) still unvisited, ${Math.round(budgetRemainingPct * 100)}% budget left.`);
|
|
62553
|
+
pushResult({
|
|
62554
|
+
acknowledged: false,
|
|
62555
|
+
keepExploring: true,
|
|
62556
|
+
reason: `Not done yet \u2014 ${frontier.length} screen(s) were seen via transitions but never visited, and ${Math.round(budgetRemainingPct * 100)}% of the iteration budget remains. A survey must map EVERY reachable screen. Navigate into the unvisited screens (e.g. ${targets}), snapshot + capture_screen each, then call finish_exploration only once no unvisited screens remain. If a screen is genuinely unreachable (needs credentials you don't have, or leaves the app), note that and move to the next one.`
|
|
62557
|
+
});
|
|
62558
|
+
continue;
|
|
62559
|
+
}
|
|
62537
62560
|
explorationComplete = true;
|
|
62538
62561
|
summary = String(toolArgs.summary ?? "");
|
|
62539
62562
|
log2(`
|
|
@@ -62752,6 +62775,14 @@ Exploration complete: ${summary}`);
|
|
|
62752
62775
|
...actionResult.error ? { error: actionResult.error } : {},
|
|
62753
62776
|
// Report only the KEY that was filled — never the value.
|
|
62754
62777
|
filledCredentialKey: key,
|
|
62778
|
+
// Code-level reinforcement of the login sequence: filling a field does
|
|
62779
|
+
// NOT submit the form. The observed failure was fill-without-submit —
|
|
62780
|
+
// the model filled email+password then wandered off (into demo content)
|
|
62781
|
+
// without ever tapping Sign In, so it never reached the authenticated
|
|
62782
|
+
// app. This nudge fires on every credential fill so the model is
|
|
62783
|
+
// reminded to complete + verify the login rather than treating the fill
|
|
62784
|
+
// as "logged in".
|
|
62785
|
+
nextStep: "Credential filled \u2014 this does NOT log you in. Once all credential fields are filled, tap the submit button (Sign In / Log In / Continue), then re-snapshot and confirm an authenticated screen (home/feed/account/Sign out) appeared before exploring further.",
|
|
62755
62786
|
screenId,
|
|
62756
62787
|
observation,
|
|
62757
62788
|
...absorbed.externalBlocked ? { blockedExternalApp: true, externalApp: absorbed.externalOwner } : {},
|
|
@@ -328429,7 +328460,7 @@ var require_package4 = __commonJS({
|
|
|
328429
328460
|
"package.json"(exports2, module2) {
|
|
328430
328461
|
module2.exports = {
|
|
328431
328462
|
name: "@validate.qa/runner",
|
|
328432
|
-
version: "1.0.
|
|
328463
|
+
version: "1.0.19",
|
|
328433
328464
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
328434
328465
|
bin: {
|
|
328435
328466
|
"validate-runner": "dist/cli.js"
|
package/dist/cli.mjs
CHANGED
|
@@ -62045,7 +62045,7 @@ var require_mobile_explorer = __commonJS({
|
|
|
62045
62045
|
}
|
|
62046
62046
|
sections.push("");
|
|
62047
62047
|
if (mode === "survey") {
|
|
62048
|
-
sections.push(
|
|
62048
|
+
sections.push(`**Mission:** Map every reachable screen. For each new screen: mobile_snapshot -> capture_screen -> record_transition. Get PAST the entry gate into the app's real main content \u2014 the login/landing screens are the ENTRANCE, not the app. If test credentials are provided (see the Test Credentials section), SIGN IN with them FIRST and map the authenticated app; that is the real product surface. Use a guest/demo/skip entry (e.g. "See Demo Profile", "Continue as guest") ONLY as a fallback when no credentials are available or login cannot be completed \u2014 demo mode is a limited sandbox, not the authenticated app. Do NOT submit forms with junk data or mutate real data. Call finish_exploration ONLY when every reachable screen \u2014 including the authenticated content \u2014 has been captured and no unvisited frontier screens remain.`);
|
|
62049
62049
|
} else {
|
|
62050
62050
|
sections.push("**Mission:** Use the focus features like a real user. Tap, type, submit, and observe outcomes. After a meaningful flow, call record_journey. Call finish_exploration when the flows are covered.");
|
|
62051
62051
|
}
|
|
@@ -62103,7 +62103,14 @@ var require_mobile_explorer = __commonJS({
|
|
|
62103
62103
|
This app has stored login credentials under these keys:
|
|
62104
62104
|
${keyList}
|
|
62105
62105
|
|
|
62106
|
-
|
|
62106
|
+
LOG IN FIRST \u2014 before broad exploration. The authenticated app is the real product surface; a survey that only maps the logged-out/demo screens has missed most of the app. This OVERRIDES the "do not submit forms" rule for the login form ONLY. The login sequence is:
|
|
62107
|
+
1. Reach the email/password sign-in form (tap "Sign in with Email" / "Login" from the landing screen if needed).
|
|
62108
|
+
2. Fill the email field: \`mobile_fill_credential({ ref, credentialKey: "TEST_USER_EMAIL" })\`. Fill the password field: \`mobile_fill_credential({ ref, credentialKey: "TEST_USER_PASSWORD" })\`. The runner substitutes the real value on the device; you never see, log, or echo it.
|
|
62109
|
+
3. TAP THE SUBMIT BUTTON (e.g. "Sign In", "Log In", "Continue"). Filling the fields does NOT log you in \u2014 you MUST tap submit.
|
|
62110
|
+
4. VERIFY you are actually signed in: re-snapshot and confirm an authenticated signal appeared (a home/feed/dashboard with real content, an account/profile tab, a "Sign out" option, or your user identity). If you are still on the login form, the login failed \u2014 check for an error, re-enter, and submit again (up to 2 attempts).
|
|
62111
|
+
5. Only AFTER you have confirmed you are signed in, map the authenticated app.
|
|
62112
|
+
|
|
62113
|
+
PREFER real login over any "demo"/"guest"/"skip" entry: those give a limited sandbox, NOT the authenticated app. Use them only if login is impossible.
|
|
62107
62114
|
|
|
62108
62115
|
SECURITY RULES:
|
|
62109
62116
|
- NEVER call \`mobile_type\` with an 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.
|
|
@@ -62410,6 +62417,8 @@ ${existingScreens.slice(0, 100).map((s) => `- ${s.screenId}${s.name ? ` "${s.nam
|
|
|
62410
62417
|
let summary = "";
|
|
62411
62418
|
let truncated = false;
|
|
62412
62419
|
let truncatedReason;
|
|
62420
|
+
let finishRedirects = 0;
|
|
62421
|
+
const MAX_FINISH_REDIRECTS = 2;
|
|
62413
62422
|
try {
|
|
62414
62423
|
try {
|
|
62415
62424
|
const seed = await driver.snapshot();
|
|
@@ -62539,6 +62548,20 @@ ${statePacket}` }
|
|
|
62539
62548
|
continue;
|
|
62540
62549
|
}
|
|
62541
62550
|
if (toolName === "finish_exploration") {
|
|
62551
|
+
const frontier = mode === "survey" ? state2.getFrontier() : [];
|
|
62552
|
+
const budgetRemainingPct = (maxIterations - iteration) / maxIterations;
|
|
62553
|
+
if (frontier.length > 0 && budgetRemainingPct >= 0.2 && finishRedirects < MAX_FINISH_REDIRECTS) {
|
|
62554
|
+
finishRedirects++;
|
|
62555
|
+
const targets = frontier.slice(0, 6).join(", ");
|
|
62556
|
+
log2(`
|
|
62557
|
+
finish_exploration bounced (${finishRedirects}/${MAX_FINISH_REDIRECTS}): ${frontier.length} frontier screen(s) still unvisited, ${Math.round(budgetRemainingPct * 100)}% budget left.`);
|
|
62558
|
+
pushResult({
|
|
62559
|
+
acknowledged: false,
|
|
62560
|
+
keepExploring: true,
|
|
62561
|
+
reason: `Not done yet \u2014 ${frontier.length} screen(s) were seen via transitions but never visited, and ${Math.round(budgetRemainingPct * 100)}% of the iteration budget remains. A survey must map EVERY reachable screen. Navigate into the unvisited screens (e.g. ${targets}), snapshot + capture_screen each, then call finish_exploration only once no unvisited screens remain. If a screen is genuinely unreachable (needs credentials you don't have, or leaves the app), note that and move to the next one.`
|
|
62562
|
+
});
|
|
62563
|
+
continue;
|
|
62564
|
+
}
|
|
62542
62565
|
explorationComplete = true;
|
|
62543
62566
|
summary = String(toolArgs.summary ?? "");
|
|
62544
62567
|
log2(`
|
|
@@ -62757,6 +62780,14 @@ Exploration complete: ${summary}`);
|
|
|
62757
62780
|
...actionResult.error ? { error: actionResult.error } : {},
|
|
62758
62781
|
// Report only the KEY that was filled — never the value.
|
|
62759
62782
|
filledCredentialKey: key,
|
|
62783
|
+
// Code-level reinforcement of the login sequence: filling a field does
|
|
62784
|
+
// NOT submit the form. The observed failure was fill-without-submit —
|
|
62785
|
+
// the model filled email+password then wandered off (into demo content)
|
|
62786
|
+
// without ever tapping Sign In, so it never reached the authenticated
|
|
62787
|
+
// app. This nudge fires on every credential fill so the model is
|
|
62788
|
+
// reminded to complete + verify the login rather than treating the fill
|
|
62789
|
+
// as "logged in".
|
|
62790
|
+
nextStep: "Credential filled \u2014 this does NOT log you in. Once all credential fields are filled, tap the submit button (Sign In / Log In / Continue), then re-snapshot and confirm an authenticated screen (home/feed/account/Sign out) appeared before exploring further.",
|
|
62760
62791
|
screenId,
|
|
62761
62792
|
observation,
|
|
62762
62793
|
...absorbed.externalBlocked ? { blockedExternalApp: true, externalApp: absorbed.externalOwner } : {},
|
|
@@ -328434,7 +328465,7 @@ var require_package4 = __commonJS({
|
|
|
328434
328465
|
"package.json"(exports, module) {
|
|
328435
328466
|
module.exports = {
|
|
328436
328467
|
name: "@validate.qa/runner",
|
|
328437
|
-
version: "1.0.
|
|
328468
|
+
version: "1.0.19",
|
|
328438
328469
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
328439
328470
|
bin: {
|
|
328440
328471
|
"validate-runner": "dist/cli.js"
|
package/package.json
CHANGED