@exodus/xqa 1.12.0 → 1.13.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/dist/xqa.cjs +24 -7
- package/package.json +3 -3
package/dist/xqa.cjs
CHANGED
|
@@ -62958,6 +62958,7 @@ var STUCK_LOOP_RULE = `Stuck loop: emit a \`stuck-loop\` finding when any of the
|
|
|
62958
62958
|
var LOADING_STATE_RULE = `Transient loading state: when the screen shows spinners, skeleton screens, progress bars, "Loading..." text, or placeholder content NOT described in spec or app context \u2014 use \`screenshot\` to poll for resolution (up to 3 retries); switch to \`view_ui\` only on the final check or when you need element data to act \u2014 if loading persists after 3 retries, proceed with what is visible; if spec or app context explicitly describes a loading screen as a step, do not retry \u2014 call \`view_ui\` and assert normally`;
|
|
62959
62959
|
var EXPECTED_CONTENT_MISSING_RULE = `Expected content missing: when \`view_ui\` shows no loading indicator yet omits an element named or strongly implied by spec or app context \u2014 and its absence is not semantically consistent with the current screen \u2014 call \`wait_seconds\` with 2\u20135 seconds and retry \`view_ui\` up to 2 times; if element remains absent, emit a \`missing-content\` finding stating what was expected and what was observed`;
|
|
62960
62960
|
var CLIPPED_ELEMENT_RULE = `Never tap an element tagged \`[clipped-top]\`, \`[clipped-bottom]\`, \`[clipped-left]\`, or \`[clipped-right]\` \u2014 scroll to fully reveal it first, then re-call \`view_ui\` before tapping`;
|
|
62961
|
+
var A11Y_FALLBACK_RULE = `Missing a11y element: if you intend to tap or interact with a UI element and that element is absent from the most recent \`view_ui\` a11y tree \u2014 do NOT estimate its coordinates from the screenshot or attempt any pixel-based tap \u2014 instead, emit a \`missing-a11y-element\` finding that states: (1) your intent (what you were trying to do), (2) the approximate visual region where the element appeared (coords/size from the screenshot), (3) nearby labeled elements from the a11y tree that serve as landmarks \u2014 then continue: in freestyle mode keep exploring other reachable screens; in spec mode advance to the next step`;
|
|
62961
62962
|
var WHAT_TO_TEST_SECTION = `## What to Test
|
|
62962
62963
|
|
|
62963
62964
|
Test navigation elements first, interactions second.
|
|
@@ -62977,6 +62978,15 @@ Test navigation elements first, interactions second.
|
|
|
62977
62978
|
- Static labels, decorative images, dividers
|
|
62978
62979
|
|
|
62979
62980
|
If an interaction produces no observable change, retry once before flagging.`;
|
|
62981
|
+
var DESTRUCTIVE_ACTIONS_SECTION = `## Destructive Actions
|
|
62982
|
+
|
|
62983
|
+
Never confirm actions that have permanent, irreversible, or externally observable consequences. Examples: sending or signing transactions, transferring funds, broadcasting messages, deleting accounts or wallets, wiping data, resetting the app, revoking sessions, logging out, uninstall prompts, in-app purchases, granting permissions to third parties, or any dialog whose primary button is labeled \`Send\`, \`Confirm\`, \`Sign\`, \`Pay\`, \`Delete\`, \`Remove\`, \`Reset\`, \`Erase\`, \`Log out\`, \`Sign out\`, \`Approve\`, or equivalent.
|
|
62984
|
+
|
|
62985
|
+
Rules:
|
|
62986
|
+
- Navigate up to the confirmation step to verify the flow is reachable and the dialog renders correctly, then back out via cancel, close, or back \u2014 do not tap the destructive confirm.
|
|
62987
|
+
- If the only exit from a screen is the destructive confirm, emit a \`destructive-only-exit\` finding and halt that branch \u2014 do not proceed.
|
|
62988
|
+
- Treat irreversible in-app state changes (e.g. marking an item as consumed, claiming a one-time reward, rotating a seed) the same as destructive actions unless app context explicitly authorizes them.
|
|
62989
|
+
- When in doubt about reversibility, treat the action as destructive and back out.`;
|
|
62980
62990
|
var DEAD_END_SECTION = `## Dead End and Modal Detection
|
|
62981
62991
|
|
|
62982
62992
|
**Dead end** \u2014 when \`view_ui\` shows no interactive exit affordance, first consult App Knowledge for gesture-based navigation on this screen, then attempt ALL of before emitting a finding: (1) any visible back/close button, (2) swipe from the left edge (back gesture), (3) swipe down (dismiss gesture). If all fail, emit a \`dead-end\` finding describing what was visible and what was attempted.
|
|
@@ -63039,6 +63049,7 @@ var SPEC_RULES_SECTION = `## Rules
|
|
|
63039
63049
|
- ${LOADING_STATE_RULE}
|
|
63040
63050
|
- ${EXPECTED_CONTENT_MISSING_RULE}
|
|
63041
63051
|
- ${CLIPPED_ELEMENT_RULE}
|
|
63052
|
+
- ${A11Y_FALLBACK_RULE}
|
|
63042
63053
|
- Each item in \`**Assertions**\` is a mandatory pass/fail check \u2014 verify using \`view_ui\` when the assertion targets an element attribute, label, or presence in the tree; use \`screenshot\` when the assertion is purely visual; if neither can confirm, emit a \`spec-deviation\` finding based on what is observable
|
|
63043
63054
|
- Flag crash dialogs, unexpected system errors, or navigation failures that occur as a direct result of executing a spec step; if you observe a visibly broken element in passing while navigating, note it without interacting with it`;
|
|
63044
63055
|
function buildSpecModeBody({
|
|
@@ -63083,12 +63094,7 @@ var SPEC_MODE_TEMPLATE = (specContent, options) => {
|
|
|
63083
63094
|
${DEV_ENVIRONMENT_SECTION}` : "";
|
|
63084
63095
|
return buildSpecModeBody({ specContent, contextBlock, environmentSection });
|
|
63085
63096
|
};
|
|
63086
|
-
|
|
63087
|
-
const { appContext, initialState: initialState2, buildEnv } = options ?? {};
|
|
63088
|
-
const contextBlock = buildContextSections(appContext, initialState2);
|
|
63089
|
-
const environmentSection = buildEnv === "dev" ? `
|
|
63090
|
-
|
|
63091
|
-
${DEV_ENVIRONMENT_SECTION}` : "";
|
|
63097
|
+
function buildFreestyleBody({ contextBlock, environmentSection }) {
|
|
63092
63098
|
return `You are a navigation and interaction testing agent. Your first action MUST be a \`view_ui\` call. Your role is to find broken navigation flows and non-functional interactive elements. Do not report content bugs, copy errors, or visual style issues unless they directly prevent a navigation action from completing.
|
|
63093
63099
|
|
|
63094
63100
|
${contextBlock}
|
|
@@ -63106,6 +63112,7 @@ ${TOOL_SELECTION_SECTION}
|
|
|
63106
63112
|
- ${LOADING_STATE_RULE}
|
|
63107
63113
|
- ${EXPECTED_CONTENT_MISSING_RULE}
|
|
63108
63114
|
- ${CLIPPED_ELEMENT_RULE}
|
|
63115
|
+
- ${A11Y_FALLBACK_RULE}
|
|
63109
63116
|
|
|
63110
63117
|
## Exploration Strategy
|
|
63111
63118
|
|
|
@@ -63113,11 +63120,21 @@ Explore breadth-first: map all screens reachable from the current screen before
|
|
|
63113
63120
|
|
|
63114
63121
|
${WHAT_TO_TEST_SECTION}
|
|
63115
63122
|
|
|
63123
|
+
${DESTRUCTIVE_ACTIONS_SECTION}
|
|
63124
|
+
|
|
63116
63125
|
${DEAD_END_SECTION}${environmentSection}
|
|
63117
63126
|
|
|
63118
63127
|
## Output
|
|
63119
63128
|
|
|
63120
63129
|
CRITICAL: Call \`set_output\` each time your findings change \u2014 when you discover something new, confirm a false positive, or revise a finding. Each call replaces the previous output entirely, so always pass the full current list. Do not reply in plain text.`;
|
|
63130
|
+
}
|
|
63131
|
+
var FREESTYLE_TEMPLATE = (options) => {
|
|
63132
|
+
const { appContext, initialState: initialState2, buildEnv } = options ?? {};
|
|
63133
|
+
const contextBlock = buildContextSections(appContext, initialState2);
|
|
63134
|
+
const environmentSection = buildEnv === "dev" ? `
|
|
63135
|
+
|
|
63136
|
+
${DEV_ENVIRONMENT_SECTION}` : "";
|
|
63137
|
+
return buildFreestyleBody({ contextBlock, environmentSection });
|
|
63121
63138
|
};
|
|
63122
63139
|
function generateExplorerPrompt({
|
|
63123
63140
|
mode,
|
|
@@ -76458,7 +76475,7 @@ function resolveXqaDirectory() {
|
|
|
76458
76475
|
return result.value;
|
|
76459
76476
|
}
|
|
76460
76477
|
var program2 = new Command();
|
|
76461
|
-
program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.
|
|
76478
|
+
program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.13.0"}${false ? ` (dev build +${"5e72ba0"})` : ""}`);
|
|
76462
76479
|
program2.command("init").description("Initialize a new xqa project in the current directory").action(() => {
|
|
76463
76480
|
runInitCommand();
|
|
76464
76481
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/xqa",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"typescript": "^5.8.3",
|
|
27
27
|
"vitest": "^3.2.1",
|
|
28
28
|
"zod": "^3.0.0",
|
|
29
|
-
"@qa-agents/eslint-config": "0.0.0",
|
|
30
|
-
"@qa-agents/explorer": "0.0.0",
|
|
31
29
|
"@qa-agents/display": "0.0.0",
|
|
30
|
+
"@qa-agents/explorer": "0.0.0",
|
|
31
|
+
"@qa-agents/eslint-config": "0.0.0",
|
|
32
32
|
"@qa-agents/mobile-ios": "0.0.0",
|
|
33
33
|
"@qa-agents/pipeline": "0.0.0",
|
|
34
34
|
"@qa-agents/shared": "0.0.0",
|