agent-qa 0.1.10 → 0.1.12
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.cjs +48 -26
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +48 -26
- package/dist/cli.js.map +1 -1
- package/package.json +9 -9
package/dist/cli.js
CHANGED
|
@@ -582,6 +582,7 @@ function buildTargets(platform) {
|
|
|
582
582
|
if (selection.capabilities.includes("web")) {
|
|
583
583
|
targets["example-web"] = { platform: "web", url: "https://example.com" };
|
|
584
584
|
targets["automation-exercise"] = { platform: "web", url: "https://automationexercise.com" };
|
|
585
|
+
targets["wai-bad"] = { platform: "web", url: "https://www.w3.org/WAI/demos/bad/before/home.html" };
|
|
585
586
|
}
|
|
586
587
|
if (selection.mobileRuntimes.includes("android")) {
|
|
587
588
|
targets["example-android"] = { platform: "android" };
|
|
@@ -635,6 +636,7 @@ var AUTOMATION_EXERCISE_TESTS = [
|
|
|
635
636
|
];
|
|
636
637
|
var HN_TOP_STORY_HOOK_ID = "h_aster-bloom-cloud-drift-ember-field-glade-hollow-ivory-jasper";
|
|
637
638
|
var HN_TOP_STORY_TEST_ID = "t_quad-adar-micro-magic-cross-cue-open-agog-rang-cours";
|
|
639
|
+
var BAD_A11Y_TEST_ID = "t_ponent-toa-base-fred-click-sigma-lad-agen-report-sticky";
|
|
638
640
|
function buildAutomationExerciseTest(test) {
|
|
639
641
|
return `test-id: ${test.id}
|
|
640
642
|
name: ${test.name}
|
|
@@ -715,6 +717,15 @@ steps:
|
|
|
715
717
|
- Verify the page shows "{{env:HN_FIRST_STORY_TITLE}}"
|
|
716
718
|
`;
|
|
717
719
|
}
|
|
720
|
+
function buildBadA11yTest() {
|
|
721
|
+
return `test-id: ${BAD_A11Y_TEST_ID}
|
|
722
|
+
name: W3C BAD accessibility smoke
|
|
723
|
+
target: wai-bad
|
|
724
|
+
steps:
|
|
725
|
+
- Verify the page says "Welcome to CityLights"
|
|
726
|
+
- Verify the page says "Inaccessible Home Page"
|
|
727
|
+
`;
|
|
728
|
+
}
|
|
718
729
|
function isSubscriptionProvider(provider) {
|
|
719
730
|
return provider === "openai-subscription" || provider === "anthropic-subscription";
|
|
720
731
|
}
|
|
@@ -826,6 +837,14 @@ function buildDefaultConfig(platform, providerOrLLMs, model, baseURL) {
|
|
|
826
837
|
dashboard: { port: 3100, artifactsDir: ".agent-qa/artifacts" },
|
|
827
838
|
mcp: { enabled: true, transport: "http", host: "127.0.0.1", port: 3471, path: "/mcp" },
|
|
828
839
|
cache: { dir: INIT_CACHE_DIR, ttl: "7d" },
|
|
840
|
+
...hasWeb(platform) ? {
|
|
841
|
+
accessibility: {
|
|
842
|
+
enabled: true,
|
|
843
|
+
standard: "wcag2aa",
|
|
844
|
+
runAfter: "every-step",
|
|
845
|
+
failOnViolation: false
|
|
846
|
+
}
|
|
847
|
+
} : {},
|
|
829
848
|
recording: { enabled: true },
|
|
830
849
|
memory: { enabled: true, provider: "local", dir: "agent-qa-memory" },
|
|
831
850
|
logging: { level: "warn" }
|
|
@@ -876,10 +895,14 @@ function addYamlComments(yamlStr) {
|
|
|
876
895
|
result += " # Optional: persist dashboard state to a custom SQLite path.\n";
|
|
877
896
|
result += " # dbPath: .agent-qa/dashboard.sqlite\n";
|
|
878
897
|
} else if (line === " ttl: 7d") {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
898
|
+
if (yamlStr.includes("\n accessibility:\n")) {
|
|
899
|
+
result += " # Accessibility checks power the W3C BAD demo test.\n";
|
|
900
|
+
} else {
|
|
901
|
+
result += " # Optional accessibility service example:\n";
|
|
902
|
+
result += " # accessibility:\n";
|
|
903
|
+
result += " # enabled: false\n";
|
|
904
|
+
result += " # standard: wcag2aa\n";
|
|
905
|
+
}
|
|
883
906
|
} else if (line === "registry:") {
|
|
884
907
|
result += " # Optional: local and cloud device/provider profiles.\n";
|
|
885
908
|
result += " # devices:\n";
|
|
@@ -950,9 +973,7 @@ function browserSetupCommand(platform) {
|
|
|
950
973
|
function mobileDriverSetupCommand(platform) {
|
|
951
974
|
const runtimes = normalizePlatformSelection(platform).mobileRuntimes;
|
|
952
975
|
if (runtimes.length === 0) return null;
|
|
953
|
-
|
|
954
|
-
if (runtimes.includes("android")) return "agent-qa install-mobile-drivers --android";
|
|
955
|
-
return "agent-qa install-mobile-drivers --ios";
|
|
976
|
+
return "agent-qa install-mobile-drivers --all";
|
|
956
977
|
}
|
|
957
978
|
function initNextSteps(platform) {
|
|
958
979
|
const steps = [];
|
|
@@ -986,21 +1007,13 @@ function createInitCommand() {
|
|
|
986
1007
|
const capabilities = await checkbox({
|
|
987
1008
|
message: "What platform will you test?",
|
|
988
1009
|
choices: [
|
|
989
|
-
{ value: "web", name: "Web", description: "Test web apps with Playwright" },
|
|
990
|
-
{ value: "mobile", name: "Mobile", description: "Test Android or iOS apps with Appium" }
|
|
1010
|
+
{ value: "web", name: "Web", description: "Test web apps with Playwright", checked: true },
|
|
1011
|
+
{ value: "mobile", name: "Mobile", description: "Test Android or iOS apps with Appium", checked: false }
|
|
991
1012
|
],
|
|
992
1013
|
required: true,
|
|
993
1014
|
validate: (value) => value.length > 0 || "Select at least one platform."
|
|
994
1015
|
});
|
|
995
|
-
const mobileRuntimes = capabilities.includes("mobile") ?
|
|
996
|
-
message: "Which mobile platforms will you test?",
|
|
997
|
-
choices: [
|
|
998
|
-
{ value: "android", name: "Android", description: "Install or reuse the UiAutomator2 Appium driver" },
|
|
999
|
-
{ value: "ios", name: "iOS", description: "Install or reuse the XCUITest Appium driver" }
|
|
1000
|
-
],
|
|
1001
|
-
required: true,
|
|
1002
|
-
validate: (value) => value.length > 0 || "Select at least one mobile platform."
|
|
1003
|
-
}) : [];
|
|
1016
|
+
const mobileRuntimes = capabilities.includes("mobile") ? ["android", "ios"] : [];
|
|
1004
1017
|
platform = { capabilities, mobileRuntimes };
|
|
1005
1018
|
const llmSetup = await checkbox({
|
|
1006
1019
|
message: `Subscription auth ${pc3.dim("(optional)")}`,
|
|
@@ -1116,6 +1129,9 @@ function createInitCommand() {
|
|
|
1116
1129
|
const hnTestPath = join2(testsDir, "hacker-news-top-story.yaml");
|
|
1117
1130
|
writeFileSync(hnTestPath, buildHackerNewsTopStoryTest());
|
|
1118
1131
|
console.log(pc3.green(`\u2713 Created ${hnTestPath}`));
|
|
1132
|
+
const badA11yTestPath = join2(testsDir, "bad-a11y.yaml");
|
|
1133
|
+
writeFileSync(badA11yTestPath, buildBadA11yTest());
|
|
1134
|
+
console.log(pc3.green(`\u2713 Created ${badA11yTestPath}`));
|
|
1119
1135
|
}
|
|
1120
1136
|
appendGitignore(dir);
|
|
1121
1137
|
console.log(pc3.green("\u2713 Updated .gitignore"));
|
|
@@ -1137,6 +1153,7 @@ function createInitCommand() {
|
|
|
1137
1153
|
if (hasWeb(platform)) {
|
|
1138
1154
|
console.log(` ${pc3.dim("\u2022")} tests/automation-exercise/*.yaml`);
|
|
1139
1155
|
console.log(` ${pc3.dim("\u2022")} tests/hacker-news-top-story.yaml`);
|
|
1156
|
+
console.log(` ${pc3.dim("\u2022")} tests/bad-a11y.yaml`);
|
|
1140
1157
|
console.log(` ${pc3.dim("\u2022")} suites/automation-exercise.suite.yaml`);
|
|
1141
1158
|
console.log(` ${pc3.dim("\u2022")} scripts/fetch-hn-top-story.mjs`);
|
|
1142
1159
|
}
|
|
@@ -1849,18 +1866,13 @@ function checkPlaywright(config) {
|
|
|
1849
1866
|
function appiumResolverCwd(configPath) {
|
|
1850
1867
|
return dirname5(resolve4(configPath));
|
|
1851
1868
|
}
|
|
1852
|
-
function mobileDriverInstallCommand(
|
|
1853
|
-
const hasAndroid = hasAndroidPlatform(config);
|
|
1854
|
-
const hasIOS = hasIOSPlatform(config);
|
|
1855
|
-
if (hasAndroid && hasIOS) return "agent-qa install-mobile-drivers --all";
|
|
1856
|
-
if (hasAndroid) return "agent-qa install-mobile-drivers --android";
|
|
1857
|
-
if (hasIOS) return "agent-qa install-mobile-drivers --ios";
|
|
1869
|
+
function mobileDriverInstallCommand() {
|
|
1858
1870
|
return "agent-qa install-mobile-drivers --all";
|
|
1859
1871
|
}
|
|
1860
1872
|
function checkAppium(config, configPath) {
|
|
1861
1873
|
return {
|
|
1862
1874
|
name: "Appium",
|
|
1863
|
-
fixInstructions: `${formatAppiumInstallGuidance2()} Then run \`${mobileDriverInstallCommand(
|
|
1875
|
+
fixInstructions: `${formatAppiumInstallGuidance2()} Then run \`${mobileDriverInstallCommand()}\`.`,
|
|
1864
1876
|
check: async () => {
|
|
1865
1877
|
if (!isMobilePlatform(config)) {
|
|
1866
1878
|
return { status: "skip", message: "not configured" };
|
|
@@ -1878,7 +1890,7 @@ function checkAppium(config, configPath) {
|
|
|
1878
1890
|
function checkAppiumDrivers(config, configPath) {
|
|
1879
1891
|
return {
|
|
1880
1892
|
name: "Appium drivers",
|
|
1881
|
-
fixInstructions: `Run \`${mobileDriverInstallCommand(
|
|
1893
|
+
fixInstructions: `Run \`${mobileDriverInstallCommand()}\``,
|
|
1882
1894
|
check: async () => {
|
|
1883
1895
|
if (!isMobilePlatform(config)) {
|
|
1884
1896
|
return { status: "skip", message: "not configured" };
|
|
@@ -2221,6 +2233,10 @@ async function createPlatformAdapter(platform) {
|
|
|
2221
2233
|
const { WebPlatformAdapter } = await import("@vostride/agent-qa-web");
|
|
2222
2234
|
return new WebPlatformAdapter();
|
|
2223
2235
|
}
|
|
2236
|
+
var runWebAccessibilityCheck = async (page, options) => {
|
|
2237
|
+
const { runAccessibilityCheck } = await import("@vostride/agent-qa-web");
|
|
2238
|
+
return runAccessibilityCheck(page, options);
|
|
2239
|
+
};
|
|
2224
2240
|
function buildPlatformConfig(platform, resolvedDevice, timeouts, globalBrowser, logCapture, farmSession, mobileResolved) {
|
|
2225
2241
|
if (platform === "web") {
|
|
2226
2242
|
return {
|
|
@@ -3216,6 +3232,8 @@ async function executeSuites(suiteFiles, opts, config, globalOpts, configContent
|
|
|
3216
3232
|
resolvedHooks: hooksContext?.resolvedHooks,
|
|
3217
3233
|
sandboxOptions: hooksContext?.sandboxOptions,
|
|
3218
3234
|
logCapture: suiteLogCapture,
|
|
3235
|
+
accessibility: config.services?.accessibility,
|
|
3236
|
+
accessibilityCheck: runWebAccessibilityCheck,
|
|
3219
3237
|
screenshotSize: plannerCfg.screenshotSize,
|
|
3220
3238
|
effectiveResolution: plannerCfg.effectiveResolution,
|
|
3221
3239
|
memoryProvider: suiteMemoryProvider,
|
|
@@ -4064,6 +4082,8 @@ Config for: ${test.name}`));
|
|
|
4064
4082
|
inlineHookDefs: resolvedHooks,
|
|
4065
4083
|
inlineHookSandboxOptions: sandboxOptions,
|
|
4066
4084
|
logCapture: testLogCapture,
|
|
4085
|
+
accessibility: config.services?.accessibility,
|
|
4086
|
+
accessibilityCheck: runWebAccessibilityCheck,
|
|
4067
4087
|
screenshotSize: plannerCfg.screenshotSize,
|
|
4068
4088
|
effectiveResolution: plannerCfg.effectiveResolution,
|
|
4069
4089
|
contextWindow: plannerCfg.contextWindow,
|
|
@@ -4165,6 +4185,8 @@ Config for: ${test.name}`));
|
|
|
4165
4185
|
inlineHookDefs: resolvedHooks,
|
|
4166
4186
|
inlineHookSandboxOptions: sandboxOptions,
|
|
4167
4187
|
logCapture: testLogCapture,
|
|
4188
|
+
accessibility: config.services?.accessibility,
|
|
4189
|
+
accessibilityCheck: runWebAccessibilityCheck,
|
|
4168
4190
|
screenshotSize: plannerCfg.screenshotSize,
|
|
4169
4191
|
effectiveResolution: plannerCfg.effectiveResolution,
|
|
4170
4192
|
contextWindow: plannerCfg.contextWindow
|