swipium 1.3.0 → 1.5.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/CHANGELOG.md +142 -0
- package/README.md +89 -25
- package/THREAT_MODEL.md +1 -1
- package/dist/appMap/automationLink.js +13 -3
- package/dist/appMap/automationLink.js.map +1 -1
- package/dist/appMap/build.js +28 -6
- package/dist/appMap/build.js.map +1 -1
- package/dist/appMap/codeIndex.js +29 -3
- package/dist/appMap/codeIndex.js.map +1 -1
- package/dist/appMap/featureIndex.js +20 -2
- package/dist/appMap/featureIndex.js.map +1 -1
- package/dist/appMap/featureModel.js +42 -6
- package/dist/appMap/featureModel.js.map +1 -1
- package/dist/appMap/firstRunApply.js +22 -4
- package/dist/appMap/firstRunApply.js.map +1 -1
- package/dist/appMap/fsWalk.js +19 -2
- package/dist/appMap/fsWalk.js.map +1 -1
- package/dist/appMap/issues.js +0 -20
- package/dist/appMap/issues.js.map +1 -1
- package/dist/appMap/migrations.js +1 -1
- package/dist/appMap/migrations.js.map +1 -1
- package/dist/appMap/prelaunch.js.map +1 -1
- package/dist/appMap/projectRegistry.js +8 -2
- package/dist/appMap/projectRegistry.js.map +1 -1
- package/dist/appMap/query.js +20 -4
- package/dist/appMap/query.js.map +1 -1
- package/dist/appMap/runtimeMerge.js +9 -2
- package/dist/appMap/runtimeMerge.js.map +1 -1
- package/dist/appMap/schema.js.map +1 -1
- package/dist/appMap/screenMatch.js +5 -1
- package/dist/appMap/screenMatch.js.map +1 -1
- package/dist/appMap/staticScan.js +134 -22
- package/dist/appMap/staticScan.js.map +1 -1
- package/dist/appMap/store.js +4 -79
- package/dist/appMap/store.js.map +1 -1
- package/dist/appMap/tsAstScan.js +31 -9
- package/dist/appMap/tsAstScan.js.map +1 -1
- package/dist/artifacts/bundletool.js +44 -7
- package/dist/artifacts/bundletool.js.map +1 -1
- package/dist/artifacts/resolve.js +33 -6
- package/dist/artifacts/resolve.js.map +1 -1
- package/dist/automation/capabilities.js +109 -27
- package/dist/automation/capabilities.js.map +1 -1
- package/dist/automation/gestures.js +5 -1
- package/dist/automation/gestures.js.map +1 -1
- package/dist/automation/plan.js +65 -17
- package/dist/automation/plan.js.map +1 -1
- package/dist/automation/report.js +12 -2
- package/dist/automation/report.js.map +1 -1
- package/dist/automation/selectors.js +8 -3
- package/dist/automation/selectors.js.map +1 -1
- package/dist/automation/types.js.map +1 -1
- package/dist/automation/waits.js +9 -3
- package/dist/automation/waits.js.map +1 -1
- package/dist/automation/webview.js +7 -1
- package/dist/automation/webview.js.map +1 -1
- package/dist/automationGen/appiumModel.js +3 -1
- package/dist/automationGen/appiumModel.js.map +1 -1
- package/dist/automationGen/ciEmitter.js +1 -1
- package/dist/automationGen/ciEmitter.js.map +1 -1
- package/dist/automationGen/jsEmitter.js +29 -21
- package/dist/automationGen/jsEmitter.js.map +1 -1
- package/dist/automationGen/projectProfile.js +5 -1
- package/dist/automationGen/projectProfile.js.map +1 -1
- package/dist/automationGen/pythonEmitter.js +3 -3
- package/dist/automationGen/pythonEmitter.js.map +1 -1
- package/dist/automationGen/readmeEmitter.js.map +1 -1
- package/dist/automationGen/suitePlan.js +11 -6
- package/dist/automationGen/suitePlan.js.map +1 -1
- package/dist/automationGen/validation.js +33 -5
- package/dist/automationGen/validation.js.map +1 -1
- package/dist/build/parseBuildLog.js +234 -30
- package/dist/build/parseBuildLog.js.map +1 -1
- package/dist/build/plan.js +33 -12
- package/dist/build/plan.js.map +1 -1
- package/dist/ci/preflight.js.map +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/scan.js +1 -1
- package/dist/cli/scan.js.map +1 -1
- package/dist/cli/suite.js +2 -2
- package/dist/cli/suite.js.map +1 -1
- package/dist/cli/verify.js.map +1 -1
- package/dist/context/detect.js +10 -4
- package/dist/context/detect.js.map +1 -1
- package/dist/context/findApps.js +16 -2
- package/dist/context/findApps.js.map +1 -1
- package/dist/context/scan.js.map +1 -1
- package/dist/core/target.js +7 -5
- package/dist/core/target.js.map +1 -1
- package/dist/core/targetPlan.js +135 -17
- package/dist/core/targetPlan.js.map +1 -1
- package/dist/drivers/DirectDriver.js +17 -7
- package/dist/drivers/DirectDriver.js.map +1 -1
- package/dist/drivers/SimctlDriver.js +4 -1
- package/dist/drivers/SimctlDriver.js.map +1 -1
- package/dist/drivers/WdaDriver.js +15 -5
- package/dist/drivers/WdaDriver.js.map +1 -1
- package/dist/explore/candidates.js +5 -1
- package/dist/explore/candidates.js.map +1 -1
- package/dist/explore/graph.js +11 -2
- package/dist/explore/graph.js.map +1 -1
- package/dist/explore/memory.js +4 -1
- package/dist/explore/memory.js.map +1 -1
- package/dist/explore/planner.js +54 -9
- package/dist/explore/planner.js.map +1 -1
- package/dist/explore/policy.js +6 -1
- package/dist/explore/policy.js.map +1 -1
- package/dist/explore/runner.js +179 -23
- package/dist/explore/runner.js.map +1 -1
- package/dist/explore/signatures.js +3 -1
- package/dist/explore/signatures.js.map +1 -1
- package/dist/explore/suite.js +3 -1
- package/dist/explore/suite.js.map +1 -1
- package/dist/featureTesting/executionBootstrap.js +128 -19
- package/dist/featureTesting/executionBootstrap.js.map +1 -1
- package/dist/featureTesting/featureMap.js +4 -1
- package/dist/featureTesting/featureMap.js.map +1 -1
- package/dist/featureTesting/featureScope.js +94 -13
- package/dist/featureTesting/featureScope.js.map +1 -1
- package/dist/featureTesting/mapFeatureScope.js +37 -8
- package/dist/featureTesting/mapFeatureScope.js.map +1 -1
- package/dist/featureTesting/objectiveModel.js +5 -1
- package/dist/featureTesting/objectiveModel.js.map +1 -1
- package/dist/featureTesting/resultMerge.js +10 -2
- package/dist/featureTesting/resultMerge.js.map +1 -1
- package/dist/featureTesting/sources.js +4 -1
- package/dist/featureTesting/sources.js.map +1 -1
- package/dist/featureTesting/suiteBridge.js +7 -1
- package/dist/featureTesting/suiteBridge.js.map +1 -1
- package/dist/featureTesting/synonyms.js +31 -3
- package/dist/featureTesting/synonyms.js.map +1 -1
- package/dist/featureTesting/testCaseFactory.js +16 -4
- package/dist/featureTesting/testCaseFactory.js.map +1 -1
- package/dist/featureTesting/testPlan.js +32 -10
- package/dist/featureTesting/testPlan.js.map +1 -1
- package/dist/firstRun/classifyScreen.js +4 -1
- package/dist/firstRun/classifyScreen.js.map +1 -1
- package/dist/firstRun/firstRunPlanner.js +5 -2
- package/dist/firstRun/firstRunPlanner.js.map +1 -1
- package/dist/firstRun/firstRunRunner.js +84 -23
- package/dist/firstRun/firstRunRunner.js.map +1 -1
- package/dist/firstRun/generatedDataPolicy.js +16 -6
- package/dist/firstRun/generatedDataPolicy.js.map +1 -1
- package/dist/firstRun/inputPlanner.js +40 -6
- package/dist/firstRun/inputPlanner.js.map +1 -1
- package/dist/firstRun/paywallPolicy.js.map +1 -1
- package/dist/fixtures/catalog.js +39 -6
- package/dist/fixtures/catalog.js.map +1 -1
- package/dist/flows/generate.js +53 -12
- package/dist/flows/generate.js.map +1 -1
- package/dist/flows/lint.js +88 -14
- package/dist/flows/lint.js.map +1 -1
- package/dist/flows/pack.js +18 -2
- package/dist/flows/pack.js.map +1 -1
- package/dist/flows/repair.js +71 -20
- package/dist/flows/repair.js.map +1 -1
- package/dist/flows/run.js +164 -51
- package/dist/flows/run.js.map +1 -1
- package/dist/flows/schema.js +57 -20
- package/dist/flows/schema.js.map +1 -1
- package/dist/flows/seedExec.js +5 -1
- package/dist/flows/seedExec.js.map +1 -1
- package/dist/ios/signing.js +32 -3
- package/dist/ios/signing.js.map +1 -1
- package/dist/issues/classify.js +12 -4
- package/dist/issues/classify.js.map +1 -1
- package/dist/issues/fingerprint.js +11 -5
- package/dist/issues/fingerprint.js.map +1 -1
- package/dist/issues/index.js +4 -20
- package/dist/issues/index.js.map +1 -1
- package/dist/issues/metrics.js +2 -1
- package/dist/issues/metrics.js.map +1 -1
- package/dist/issues/recurrence.js.map +1 -1
- package/dist/issues/report.js +8 -4
- package/dist/issues/report.js.map +1 -1
- package/dist/issues/reportBridge.js +36 -5
- package/dist/issues/reportBridge.js.map +1 -1
- package/dist/issues/schema.js.map +1 -1
- package/dist/issues/store.js.map +1 -1
- package/dist/lib/android.js +9 -1
- package/dist/lib/android.js.map +1 -1
- package/dist/lib/device.js +21 -5
- package/dist/lib/device.js.map +1 -1
- package/dist/lib/image.js +11 -2
- package/dist/lib/image.js.map +1 -1
- package/dist/lib/lockfile.js +60 -0
- package/dist/lib/lockfile.js.map +1 -0
- package/dist/lib/needsInput.js +6 -3
- package/dist/lib/needsInput.js.map +1 -1
- package/dist/lib/png.js +2 -1
- package/dist/lib/png.js.map +1 -1
- package/dist/lib/result.js +16 -1
- package/dist/lib/result.js.map +1 -1
- package/dist/lib/schemaHash.js +4 -2
- package/dist/lib/schemaHash.js.map +1 -1
- package/dist/lib/sensitive.js +3 -1
- package/dist/lib/sensitive.js.map +1 -1
- package/dist/lib/simctl.js.map +1 -1
- package/dist/lib/spawn.js +29 -10
- package/dist/lib/spawn.js.map +1 -1
- package/dist/lib/wda.js +27 -10
- package/dist/lib/wda.js.map +1 -1
- package/dist/lib/wdaConfig.js +12 -5
- package/dist/lib/wdaConfig.js.map +1 -1
- package/dist/lib/wdaTune.js +52 -23
- package/dist/lib/wdaTune.js.map +1 -1
- package/dist/mobileAudit/checks.js +141 -19
- package/dist/mobileAudit/checks.js.map +1 -1
- package/dist/mobileAudit/profiles.js +120 -19
- package/dist/mobileAudit/profiles.js.map +1 -1
- package/dist/mobileAudit/results.js +7 -2
- package/dist/mobileAudit/results.js.map +1 -1
- package/dist/mobileAudit/runner.js +144 -19
- package/dist/mobileAudit/runner.js.map +1 -1
- package/dist/oracle/auth.js.map +1 -1
- package/dist/oracle/failures.js +888 -131
- package/dist/oracle/failures.js.map +1 -1
- package/dist/oracle/health.js +90 -14
- package/dist/oracle/health.js.map +1 -1
- package/dist/oracle/locator.js +147 -18
- package/dist/oracle/locator.js.map +1 -1
- package/dist/oracle/record.js.map +1 -1
- package/dist/orchestration/goal.js +3 -9
- package/dist/orchestration/goal.js.map +1 -1
- package/dist/orchestration/testThis/execute.js +126 -0
- package/dist/orchestration/testThis/execute.js.map +1 -0
- package/dist/orchestration/testThis/pipeline.js +324 -0
- package/dist/orchestration/testThis/pipeline.js.map +1 -0
- package/dist/orchestration/testThis/plan.js +430 -0
- package/dist/orchestration/testThis/plan.js.map +1 -0
- package/dist/orchestration/testThis/terminal.js +118 -0
- package/dist/orchestration/testThis/terminal.js.map +1 -0
- package/dist/orchestration/testThis/types.js +12 -0
- package/dist/orchestration/testThis/types.js.map +1 -0
- package/dist/plan/plan.js.map +1 -1
- package/dist/prompts/index.js +3 -3
- package/dist/prompts/index.js.map +1 -1
- package/dist/report/coverage.js +0 -1
- package/dist/report/coverage.js.map +1 -1
- package/dist/report/evidence.js.map +1 -1
- package/dist/report/export.js +59 -37
- package/dist/report/export.js.map +1 -1
- package/dist/report/flake.js +13 -14
- package/dist/report/flake.js.map +1 -1
- package/dist/report/history.js +72 -38
- package/dist/report/history.js.map +1 -1
- package/dist/report/policy.js +11 -3
- package/dist/report/policy.js.map +1 -1
- package/dist/report/qaLevel.js +2 -8
- package/dist/report/qaLevel.js.map +1 -1
- package/dist/report/readiness.js +42 -12
- package/dist/report/readiness.js.map +1 -1
- package/dist/report/summary.js.map +1 -1
- package/dist/report/timing.js +23 -23
- package/dist/report/timing.js.map +1 -1
- package/dist/server.js +42 -37
- package/dist/server.js.map +1 -1
- package/dist/services/automationGenerate.js.map +1 -1
- package/dist/services/build.js +8 -2
- package/dist/services/build.js.map +1 -1
- package/dist/services/preflight.js +38 -6
- package/dist/services/preflight.js.map +1 -1
- package/dist/services/prepareAndroid.js +46 -10
- package/dist/services/prepareAndroid.js.map +1 -1
- package/dist/services/prepareIos.js +72 -10
- package/dist/services/prepareIos.js.map +1 -1
- package/dist/services/report.js +173 -37
- package/dist/services/report.js.map +1 -1
- package/dist/services/smoke.js +36 -6
- package/dist/services/smoke.js.map +1 -1
- package/dist/services/suiteGenerate.js +16 -4
- package/dist/services/suiteGenerate.js.map +1 -1
- package/dist/services/testSuiteKnowledge.js +38 -6
- package/dist/services/testSuiteKnowledge.js.map +1 -1
- package/dist/session/attach.js +16 -0
- package/dist/session/attach.js.map +1 -1
- package/dist/session/processRegistry.js +164 -0
- package/dist/session/processRegistry.js.map +1 -0
- package/dist/session/progress.js +1 -1
- package/dist/session/progress.js.map +1 -1
- package/dist/session/store.js +216 -43
- package/dist/session/store.js.map +1 -1
- package/dist/snapshot/overlays.js +7 -2
- package/dist/snapshot/overlays.js.map +1 -1
- package/dist/snapshot/parse.js +2 -8
- package/dist/snapshot/parse.js.map +1 -1
- package/dist/snapshot/present.js +27 -3
- package/dist/snapshot/present.js.map +1 -1
- package/dist/state/profile.js +36 -9
- package/dist/state/profile.js.map +1 -1
- package/dist/suite/compile.js +7 -2
- package/dist/suite/compile.js.map +1 -1
- package/dist/suite/lint.js +21 -3
- package/dist/suite/lint.js.map +1 -1
- package/dist/suite/pom.js +26 -4
- package/dist/suite/pom.js.map +1 -1
- package/dist/suite/testcase.js +6 -4
- package/dist/suite/testcase.js.map +1 -1
- package/dist/testSuite/exporter.js +6 -2
- package/dist/testSuite/exporter.js.map +1 -1
- package/dist/testSuite/generator.js +31 -6
- package/dist/testSuite/generator.js.map +1 -1
- package/dist/testSuite/issueLinks.js.map +1 -1
- package/dist/testSuite/lint.js +1 -1
- package/dist/testSuite/lint.js.map +1 -1
- package/dist/testSuite/merge.js +8 -2
- package/dist/testSuite/merge.js.map +1 -1
- package/dist/testSuite/schema.js +16 -11
- package/dist/testSuite/schema.js.map +1 -1
- package/dist/testSuite/store.js +9 -1
- package/dist/testSuite/store.js.map +1 -1
- package/dist/tools/act.js +107 -43
- package/dist/tools/act.js.map +1 -1
- package/dist/tools/agent.js +123 -25
- package/dist/tools/agent.js.map +1 -1
- package/dist/tools/appControl.js +16 -3
- package/dist/tools/appControl.js.map +1 -1
- package/dist/tools/appMap.js +331 -63
- package/dist/tools/appMap.js.map +1 -1
- package/dist/tools/assertVisual.js +12 -2
- package/dist/tools/assertVisual.js.map +1 -1
- package/dist/tools/automationGenerate.js +276 -241
- package/dist/tools/automationGenerate.js.map +1 -1
- package/dist/tools/build.js +92 -41
- package/dist/tools/build.js.map +1 -1
- package/dist/tools/bundletool.js +139 -28
- package/dist/tools/bundletool.js.map +1 -1
- package/dist/tools/capabilities.js +45 -71
- package/dist/tools/capabilities.js.map +1 -1
- package/dist/tools/clearOverlay.js +45 -8
- package/dist/tools/clearOverlay.js.map +1 -1
- package/dist/tools/detectContext.js +1 -1
- package/dist/tools/detectContext.js.map +1 -1
- package/dist/tools/device.js +44 -7
- package/dist/tools/device.js.map +1 -1
- package/dist/tools/doctor.js +38 -15
- package/dist/tools/doctor.js.map +1 -1
- package/dist/tools/explore.js +96 -22
- package/dist/tools/explore.js.map +1 -1
- package/dist/tools/featureTesting.js +153 -114
- package/dist/tools/featureTesting.js.map +1 -1
- package/dist/tools/firstRun.js +95 -60
- package/dist/tools/firstRun.js.map +1 -1
- package/dist/tools/flow.js +236 -101
- package/dist/tools/flow.js.map +1 -1
- package/dist/tools/flowGenerate.js +51 -47
- package/dist/tools/flowGenerate.js.map +1 -1
- package/dist/tools/flowRepair.js +24 -4
- package/dist/tools/flowRepair.js.map +1 -1
- package/dist/tools/generate.js +236 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/getArtifact.js +21 -3
- package/dist/tools/getArtifact.js.map +1 -1
- package/dist/tools/health.js +3 -1
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/history.js +40 -10
- package/dist/tools/history.js.map +1 -1
- package/dist/tools/ios.js +157 -25
- package/dist/tools/ios.js.map +1 -1
- package/dist/tools/issues.js +19 -150
- package/dist/tools/issues.js.map +1 -1
- package/dist/tools/jobs.js +23 -4
- package/dist/tools/jobs.js.map +1 -1
- package/dist/tools/locator.js +36 -8
- package/dist/tools/locator.js.map +1 -1
- package/dist/tools/metro.js +61 -16
- package/dist/tools/metro.js.map +1 -1
- package/dist/tools/mobileAudit.js +67 -15
- package/dist/tools/mobileAudit.js.map +1 -1
- package/dist/tools/network.js +6 -1
- package/dist/tools/network.js.map +1 -1
- package/dist/tools/note.js +20 -6
- package/dist/tools/note.js.map +1 -1
- package/dist/tools/permissions.js +31 -6
- package/dist/tools/permissions.js.map +1 -1
- package/dist/tools/plan.js +5 -2
- package/dist/tools/plan.js.map +1 -1
- package/dist/tools/prepareIosTarget.js +31 -8
- package/dist/tools/prepareIosTarget.js.map +1 -1
- package/dist/tools/prepareTarget.js +97 -18
- package/dist/tools/prepareTarget.js.map +1 -1
- package/dist/tools/report.js +24 -5
- package/dist/tools/report.js.map +1 -1
- package/dist/tools/resolveArtifact.js +9 -5
- package/dist/tools/resolveArtifact.js.map +1 -1
- package/dist/tools/resolveTarget.js +11 -2
- package/dist/tools/resolveTarget.js.map +1 -1
- package/dist/tools/screenInfo.js +8 -2
- package/dist/tools/screenInfo.js.map +1 -1
- package/dist/tools/screenRecord.js +74 -11
- package/dist/tools/screenRecord.js.map +1 -1
- package/dist/tools/screenshot.js +23 -6
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/seed.js +38 -6
- package/dist/tools/seed.js.map +1 -1
- package/dist/tools/smoke.js +16 -3
- package/dist/tools/smoke.js.map +1 -1
- package/dist/tools/snapshot.js +59 -6
- package/dist/tools/snapshot.js.map +1 -1
- package/dist/tools/startSession.js +54 -9
- package/dist/tools/startSession.js.map +1 -1
- package/dist/tools/state.js +62 -15
- package/dist/tools/state.js.map +1 -1
- package/dist/tools/suite.js +350 -298
- package/dist/tools/suite.js.map +1 -1
- package/dist/tools/testSuite.js +94 -28
- package/dist/tools/testSuite.js.map +1 -1
- package/dist/tools/testThis.js +30 -793
- package/dist/tools/testThis.js.map +1 -1
- package/dist/tools/visual.js +124 -18
- package/dist/tools/visual.js.map +1 -1
- package/dist/tools/visualText.js +51 -6
- package/dist/tools/visualText.js.map +1 -1
- package/dist/tools/wait.js +18 -3
- package/dist/tools/wait.js.map +1 -1
- package/dist/tools/wda.js +157 -29
- package/dist/tools/wda.js.map +1 -1
- package/dist/version.js +17 -49
- package/dist/version.js.map +1 -1
- package/dist/visual/ocr.js +12 -2
- package/dist/visual/ocr.js.map +1 -1
- package/dist/visual/provider.js +7 -3
- package/dist/visual/provider.js.map +1 -1
- package/docs/mcp-server.md +44 -4
- package/docs/tools.md +42 -100
- package/package.json +14 -5
- package/dist/appMap/diff.js +0 -60
- package/dist/appMap/diff.js.map +0 -1
- package/dist/automation/maestroIr.js +0 -282
- package/dist/automation/maestroIr.js.map +0 -1
- package/dist/interop/maestro.js +0 -151
- package/dist/interop/maestro.js.map +0 -1
- package/dist/tools/idling.js +0 -104
- package/dist/tools/idling.js.map +0 -1
- package/dist/tools/inputCapabilities.js +0 -30
- package/dist/tools/inputCapabilities.js.map +0 -1
- package/dist/tools/maestro.js +0 -78
- package/dist/tools/maestro.js.map +0 -1
package/dist/visual/ocr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ocr.js","sourceRoot":"","sources":["../../src/visual/ocr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAwB,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAA+C,MAAM,eAAe,CAAC;AAkB1H,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,EAAE,UAA+C,CAAC;IACrF,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;QAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"ocr.js","sourceRoot":"","sources":["../../src/visual/ocr.ts"],"names":[],"mappings":"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"}
|
package/dist/visual/provider.js
CHANGED
|
@@ -5,14 +5,16 @@ import { loadProjectConfig } from '../cli/scan.js';
|
|
|
5
5
|
import { resolveCommandTemplate } from '../lib/commandTemplate.js';
|
|
6
6
|
import { assertNoGitScope, run } from '../lib/spawn.js';
|
|
7
7
|
function isProviderObject(value) {
|
|
8
|
-
return !!value && typeof value === 'object' && !Array.isArray(value) &&
|
|
8
|
+
return !!value && typeof value === 'object' && !Array.isArray(value) && 'command' in value;
|
|
9
9
|
}
|
|
10
10
|
export function resolveVisualProvider(command, vars, defaultTimeoutMs) {
|
|
11
11
|
const raw = isProviderObject(command) ? command.command : command;
|
|
12
12
|
const resolved = resolveCommandTemplate(raw, vars);
|
|
13
13
|
assertNoGitScope(resolved.command, resolved.args);
|
|
14
14
|
const io = isProviderObject(command) && command.io === 'json' ? 'json' : 'argv';
|
|
15
|
-
const timeoutMs = isProviderObject(command) && Number.isFinite(command.timeoutMs) && command.timeoutMs > 0
|
|
15
|
+
const timeoutMs = isProviderObject(command) && Number.isFinite(command.timeoutMs) && command.timeoutMs > 0
|
|
16
|
+
? Math.floor(command.timeoutMs)
|
|
17
|
+
: defaultTimeoutMs;
|
|
16
18
|
return { ...resolved, io, timeoutMs };
|
|
17
19
|
}
|
|
18
20
|
export async function runVisualProvider(command, vars, payload, defaultTimeoutMs) {
|
|
@@ -52,7 +54,9 @@ export async function maskScreenshotForProvider(root, imagePath, context) {
|
|
|
52
54
|
rmSync(outputPath, { force: true });
|
|
53
55
|
throw new Error('visualMaskCommand did not produce a masked imagePath or output file');
|
|
54
56
|
}
|
|
55
|
-
const masksApplied = Array.isArray(parsed.masksApplied)
|
|
57
|
+
const masksApplied = Array.isArray(parsed.masksApplied)
|
|
58
|
+
? parsed.masksApplied.filter((v) => typeof v === 'string')
|
|
59
|
+
: ['external_mask'];
|
|
56
60
|
return { imagePath: produced, tempPaths: produced === imagePath ? [] : [produced], masksApplied, providerConfigured: true };
|
|
57
61
|
}
|
|
58
62
|
export function boundedProviderObject(value, redact, maxChars = 8000) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/visual/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAA8C,MAAM,2BAA2B,CAAC;AAC/G,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAkBxD,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/visual/provider.ts"],"names":[],"mappings":"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"}
|
package/docs/mcp-server.md
CHANGED
|
@@ -6,15 +6,17 @@ Swipium runs as a local stdio MCP server. The MCP client starts the process and
|
|
|
6
6
|
|
|
7
7
|
- Node.js 20 or newer.
|
|
8
8
|
- A mobile app repository as the MCP `cwd`.
|
|
9
|
-
- Android
|
|
10
|
-
-
|
|
9
|
+
- Android platform-tools with `adb` on your PATH, usually from Android Studio.
|
|
10
|
+
- Android Emulator package plus at least one AVD for Android Emulator workflows.
|
|
11
|
+
- Xcode with an iOS Simulator runtime and at least one simulator for iOS workflows.
|
|
12
|
+
- WebDriverAgent for structured iOS UI-tree access, taps, typing, and swipes. Visual-only iOS checks can still use `simctl` without WDA.
|
|
11
13
|
|
|
12
14
|
## Server Command
|
|
13
15
|
|
|
14
16
|
No global install:
|
|
15
17
|
|
|
16
18
|
```jsonc
|
|
17
|
-
{
|
|
19
|
+
{
|
|
18
20
|
"mcpServers": {
|
|
19
21
|
"swipium": {
|
|
20
22
|
"command": "npx",
|
|
@@ -41,6 +43,8 @@ Global install:
|
|
|
41
43
|
}
|
|
42
44
|
```
|
|
43
45
|
|
|
46
|
+
`npx -y swipium` is the canonical setup for npm users. From a source checkout, build with `npm run build` and use `node /absolute/path/to/swipium/dist/index.js` as the command instead.
|
|
47
|
+
|
|
44
48
|
## Claude Code
|
|
45
49
|
|
|
46
50
|
```bash
|
|
@@ -83,6 +87,42 @@ args = ["-y", "swipium"]
|
|
|
83
87
|
cwd = "/absolute/path/to/your/mobile-app"
|
|
84
88
|
```
|
|
85
89
|
|
|
90
|
+
Known caveat: Codex builds after ~0.120.0 have an open tool-injection regression (openai/codex#19425). Set `cwd` explicitly, and if `qa_*` tools do not appear after setup, switch `command` to an absolute path and restart Codex.
|
|
91
|
+
|
|
92
|
+
## Claude Desktop
|
|
93
|
+
|
|
94
|
+
Add to `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`), then restart Claude Desktop:
|
|
95
|
+
|
|
96
|
+
```jsonc
|
|
97
|
+
{
|
|
98
|
+
"mcpServers": {
|
|
99
|
+
"swipium": {
|
|
100
|
+
"command": "npx",
|
|
101
|
+
"args": ["-y", "swipium"],
|
|
102
|
+
"cwd": "/absolute/path/to/your/mobile-app",
|
|
103
|
+
"timeout": 600000
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Cursor
|
|
110
|
+
|
|
111
|
+
Add to `.cursor/mcp.json` in the mobile app repository, or `~/.cursor/mcp.json` for all projects:
|
|
112
|
+
|
|
113
|
+
```jsonc
|
|
114
|
+
{
|
|
115
|
+
"mcpServers": {
|
|
116
|
+
"swipium": {
|
|
117
|
+
"command": "npx",
|
|
118
|
+
"args": ["-y", "swipium"],
|
|
119
|
+
"cwd": "/absolute/path/to/your/mobile-app",
|
|
120
|
+
"timeout": 600000
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
86
126
|
## Verification
|
|
87
127
|
|
|
88
128
|
Run:
|
|
@@ -100,7 +140,7 @@ qa_capabilities
|
|
|
100
140
|
|
|
101
141
|
Use `qa_doctor` with `platform:"android"`, `platform:"ios"`, or `platform:"both"` when checking platform-specific readiness.
|
|
102
142
|
|
|
103
|
-
Expected tool count:
|
|
143
|
+
Expected tool count: 60.
|
|
104
144
|
|
|
105
145
|
If the client lists fewer tools, restart the MCP client. MCP clients often keep an old server process alive after package upgrades.
|
|
106
146
|
|
package/docs/tools.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Tool Reference
|
|
2
2
|
|
|
3
|
-
Swipium exposes
|
|
3
|
+
Swipium 1.5.0 exposes 60 public MCP tools. The intended default entry point is `qa_test_this`.
|
|
4
|
+
|
|
5
|
+
This is the production public surface. Lower-level visual, seeded-state, report-history, and issue-lifecycle helpers from earlier development builds were merged into canonical workflows or deferred from public MCP registration; use the grouped tools below as the supported entry points.
|
|
4
6
|
|
|
5
7
|
## Start
|
|
6
8
|
|
|
@@ -15,6 +17,7 @@ Use these tools to orient the agent, start autopilot work, poll jobs, handle blo
|
|
|
15
17
|
| `qa_status` | Returns compact session status and recommended next action. | The agent needs to recover context during a session. |
|
|
16
18
|
| `qa_explain_blocker` | Explains a typed blocker, likely owner, and recovery path. | A run stops with a blocker and the user needs a concise explanation. |
|
|
17
19
|
| `qa_continue_from_blocker` | Resumes after user input and registers secret values for redaction. | A blocker asks for credentials, OTP, target choice, or approval data. |
|
|
20
|
+
| `qa_next_best_action` | Returns the single best next tool to call (with args) and why, deterministically. | The agent wants the orchestration sequence decided for it. |
|
|
18
21
|
| `qa_get_artifact` | Fetches artifact metadata or contents by `swipium://` URI. | A report, screenshot, dump, log, or generated file must be read. |
|
|
19
22
|
| `qa_job_cancel` | Cancels a running job and aborts its spawned children. | A long-running job must be stopped early. |
|
|
20
23
|
|
|
@@ -35,14 +38,13 @@ Use these tools to verify the local environment, create sessions, and prepare si
|
|
|
35
38
|
|
|
36
39
|
## Build
|
|
37
40
|
|
|
38
|
-
Use these tools to resolve a device and an installable artifact, or build one from source locally. `qa_build` is consent-gated;
|
|
41
|
+
Use these tools to resolve a device and an installable artifact, or build one from source locally. `qa_build` with `mode:"run"` is consent-gated; everything else is side-effect free.
|
|
39
42
|
|
|
40
43
|
| Tool | What it does | Use when |
|
|
41
44
|
| --- | --- | --- |
|
|
42
45
|
| `qa_resolve_target` | Picks the best device or simulator (prefers online over needing a boot; honors a requested platform or device). | The agent needs to choose where to run. |
|
|
43
46
|
| `qa_resolve_artifact` | Finds the best installable `.apk`/`.aab`/`.ipa`/`.app` and explains where it looked. | An artifact path is unknown or ambiguous. |
|
|
44
|
-
| `
|
|
45
|
-
| `qa_build` | Builds from source as a consent-gated job, captures a build log, and re-resolves the artifact. | No reusable artifact exists and the project must be compiled. |
|
|
47
|
+
| `qa_build` | `mode:"plan"` (default) proposes the exact build commands per framework and platform without running them; `mode:"run"` builds from source as a consent-gated job, captures a build log, and re-resolves the artifact. | The agent needs to know how the app would be built, or no reusable artifact exists and the project must be compiled. |
|
|
46
48
|
| `qa_bundletool` | Converts an `.aab` to an installable APK: a universal `.apk` or a device-specific APK set. | Only an Android App Bundle is available. |
|
|
47
49
|
|
|
48
50
|
## Device
|
|
@@ -52,13 +54,11 @@ Use these tools to inspect and control the device and app environment without ra
|
|
|
52
54
|
| Tool | What it does | Use when |
|
|
53
55
|
| --- | --- | --- |
|
|
54
56
|
| `qa_device_info` | Reports model, SDK, ABIs, locale, screen, orientation, and installed apps (read-only). | The agent needs device context before testing. |
|
|
55
|
-
| `qa_permissions` | Lists, grants, or revokes runtime permissions. Revoke is consent-gated. | A flow needs a known permission state. |
|
|
56
57
|
| `qa_orientation` | Sets portrait, landscape, or auto orientation. | A screen must be tested in a specific orientation. |
|
|
57
58
|
| `qa_geolocation` | Spoofs a GPS location on the emulator. Consent-gated. | Testing map or location-aware screens. |
|
|
58
59
|
| `qa_network` | Reports, sets offline/online, or restores airplane-mode state. Consent-gated and auto-restored. | Testing offline behavior or network errors. |
|
|
59
60
|
| `qa_metro` | Reports, starts, stops, or diagnoses the RN/Expo Metro bundler with RedBox detection. | A debug RN/Expo build needs Metro. |
|
|
60
61
|
| `qa_app_control` | Runs launch, foreground, background, force_stop, restart, clear_data, or fresh_start. Destructive actions are guarded. | The app lifecycle must be controlled directly. |
|
|
61
|
-
| `qa_screen_info` | Reports screen width, height, density, orientation, mode, and coordinate landmarks. | Coordinate-space context is needed for visual work. |
|
|
62
62
|
| `qa_screen_record` | Records a screen video to an mp4 artifact (start/stop). Consent-gated with sensitive-screen warnings. | A run needs a video of the reproduction. |
|
|
63
63
|
|
|
64
64
|
## Drive
|
|
@@ -68,29 +68,14 @@ Use these tools to observe the UI, act on it, collect evidence, and record resul
|
|
|
68
68
|
| Tool | What it does | Use when |
|
|
69
69
|
| --- | --- | --- |
|
|
70
70
|
| `qa_snapshot` | Captures compact structured UI elements where the backend supports it. | The agent needs selectors, visible text, or UI state. |
|
|
71
|
+
| `qa_inspect` | Returns the full attributes of a single `@eN` element from the latest snapshot. | One element's details are needed without dumping the whole tree. |
|
|
71
72
|
| `qa_act` | Taps, types, clears, swipes, scrolls, presses keys, opens URLs, waits, and observes after action. | The agent needs to drive the app step by step. |
|
|
72
73
|
| `qa_clear_overlay` | Attempts to dismiss common overlays blocking a target. | Popups, permissions, modals, or sheets block the next action. |
|
|
73
74
|
| `qa_check_health` | Checks foreground app status, crash signals, ANR, error boundaries, and native health. | The agent needs to distinguish app bugs from environment issues. |
|
|
74
75
|
| `qa_screenshot` | Captures a screenshot artifact with coordinate-space metadata. | Visual evidence is required. |
|
|
75
76
|
| `qa_note` | Records a structured QA outcome in the session. | The agent needs to log pass, fail, blocked, skipped, or finding details. |
|
|
76
77
|
| `qa_assert_visual` | Captures a visual assertion with evidence. | The agent needs to document that a visual condition is true or false. |
|
|
77
|
-
| `qa_visual` | Runs local visual operations: baseline capture, regression diff, image-target matching with tappable coordinates, and optional OCR. | A screen is visual-only or needs pixel-level regression checks. |
|
|
78
|
-
| `qa_visual_find_text` | Locates on-screen text with OCR and returns structured regions with coordinate-space conversion. | A target has visible text but no structured selector. |
|
|
79
|
-
| `qa_locator_suggest` | Scores each element's locator durability and grades automation readiness. | The agent needs to know which controls need testIDs before generating automation. |
|
|
80
|
-
| `qa_input_capabilities` | Reports backend text-entry limits: ASCII, Unicode, clipboard, and WDA typing frequency. | Typing fails or behaves oddly and the agent needs the backend's input limits. |
|
|
81
78
|
| `qa_wait` | Waits without a shell for `device_online`, `metro_ready`, or `job_done`. | The agent needs to block on a condition without raw `adb`/`sleep`. |
|
|
82
|
-
| `qa_idling_status` | Reads app-declared idling hooks or label-heuristic settling before automation. | The agent needs to know the app has settled before acting. |
|
|
83
|
-
|
|
84
|
-
## State
|
|
85
|
-
|
|
86
|
-
Use these tools to create and verify reproducible preconditions instead of only reporting them as missing. All mutating seed and state actions are consent-gated and recorded.
|
|
87
|
-
|
|
88
|
-
| Tool | What it does | Use when |
|
|
89
|
-
| --- | --- | --- |
|
|
90
|
-
| `qa_seed` | Creates a declared precondition via a fixture seed using a deeplink, script, or API hook. Consent-gated. | A workflow is blocked by missing test data. |
|
|
91
|
-
| `qa_state_prepare` | Prepares a reproducible state profile: reset, launch, seed, and verify a ledger. | A test needs a known starting state. |
|
|
92
|
-
| `qa_state_verify` | Verifies a state profile without treating setup drift as an app bug. | The precondition must be confirmed before testing. |
|
|
93
|
-
| `qa_state_teardown` | Runs state-profile teardown and restores declared environment state. | A run must leave the environment clean. |
|
|
94
79
|
|
|
95
80
|
## Run
|
|
96
81
|
|
|
@@ -101,8 +86,6 @@ Use these tools to run broader QA workflows and produce reports.
|
|
|
101
86
|
| `qa_smoke` | Runs launch smoke, baseline health, screenshot evidence, and saved flows. | The app is prepared and the agent needs a deterministic smoke pass. |
|
|
102
87
|
| `qa_explore` | Performs bounded guided exploration, builds a screen graph, and records evidence. | The agent needs to discover reachable workflows or collect runtime app-map data. |
|
|
103
88
|
| `qa_report` | Generates a session report with findings, blockers, evidence, mutations, workarounds, next actions, and separate app and coverage verdicts. | A run should be summarized or exported. |
|
|
104
|
-
| `qa_report_compare` | Compares the current `report.json` against a baseline report. | A run should be checked for regression against a known-good report. |
|
|
105
|
-
| `qa_run_history` | Summarizes local run history with pass rate, failures, flaky flows, and confidence calibration. | The user wants trends across runs, not a single report. |
|
|
106
89
|
|
|
107
90
|
## App Map
|
|
108
91
|
|
|
@@ -113,8 +96,8 @@ Use these tools to build and read Swipium's durable app knowledge map.
|
|
|
113
96
|
| `qa_app_map_build` | Builds or updates the app map from static analysis and runtime observations. | The project needs durable QA memory. |
|
|
114
97
|
| `qa_app_map_read` | Reads compact app-map sections such as features, screens, auth, automation, or test suite. | The agent needs app context without flooding the transcript. |
|
|
115
98
|
| `qa_app_map_query` | Searches features, screens, tests, and code links with ranked results. | The user asks about a feature, screen, or test surface. |
|
|
116
|
-
| `qa_app_map_feature_scope` | Resolves a feature
|
|
117
|
-
| `
|
|
99
|
+
| `qa_app_map_feature_scope` | Resolves a feature id or free-text query into a focused testing scope: ranked candidates, code symbols, screens, existing tests, an objective model, and a recommended plan. Read-only; works before a map exists. | The user names a feature and the agent needs its scope. |
|
|
100
|
+
| `qa_app_map_update` | Applies targeted, provenance-tracked updates (note, test cases, automation suite, environment, feature coverage) without a full rebuild. | The map needs a small correction or annotation. |
|
|
118
101
|
|
|
119
102
|
## Feature Testing
|
|
120
103
|
|
|
@@ -122,47 +105,38 @@ Use these tools to test a specific feature by name, backed by the app knowledge
|
|
|
122
105
|
|
|
123
106
|
| Tool | What it does | Use when |
|
|
124
107
|
| --- | --- | --- |
|
|
125
|
-
| `
|
|
126
|
-
| `qa_feature_test_plan` | Produces a feature test plan: scope, objective, generated cases, fixtures, automation readiness, and an execution plan. Read-only. | A feature needs a concrete test plan before running. |
|
|
127
|
-
| `qa_test_feature` | Runs a focused feature test: scope, targeted exploration toward the feature, recorded cases, then updates the feature map and report. | The user asks to test a specific feature. |
|
|
108
|
+
| `qa_test_feature` | Tests a named feature: `mode:"plan"` (default) returns the read-only test plan (scope, objective, generated cases, fixtures, execution plan); `mode:"execute"` runs targeted exploration toward the feature, records cases, then updates the feature map and report. | The user asks to plan or run a test of a specific feature. |
|
|
128
109
|
|
|
129
|
-
## Flows
|
|
110
|
+
## Flows
|
|
130
111
|
|
|
131
|
-
Use these tools to create, validate, run, and
|
|
112
|
+
Use these tools to create, validate, run, compile, and repair reusable flows.
|
|
132
113
|
|
|
133
114
|
| Tool | What it does | Use when |
|
|
134
115
|
| --- | --- | --- |
|
|
135
|
-
| `qa_flow_check` | Parses and statically validates a Swipium flow. | A flow file should be checked before execution. |
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `qa_flow_generate` | Generates a flow from recorded actions. | A manual or exploratory run should become a reusable flow. |
|
|
116
|
+
| `qa_flow_check` | Parses and statically validates a Swipium flow (static lint of the YAML). | A flow file should be checked before execution. |
|
|
117
|
+
| `qa_flow_run` | `mode:"run"` (default) executes a Swipium flow against a prepared simulator session; `mode:"plan"` is a read-only execution preview against backend capabilities without touching a device. | A saved flow needs to run against the app, or its feasibility should be checked before a run. |
|
|
118
|
+
| `qa_flow_compile` | Compiles a generated POM suite into runnable Flow V2 for `qa_flow_run` and `swipium ci`. | A generated suite needs executable flow output. |
|
|
139
119
|
| `qa_flow_repair` | Suggests or patches a stronger locator for a failed flow step from the current screen. | A flow step fails on a brittle locator. |
|
|
140
|
-
| `qa_suite_generate` | Generates a POM-style suite from recorded behavior. | The run should become a structured test suite. |
|
|
141
|
-
| `qa_suite_compile` | Compiles a generated suite into runnable Swipium flows. | A generated suite needs executable flow output. |
|
|
142
|
-
| `qa_suite_lint` | Lints generated page objects for brittle, coordinate-only, or dynamic locators. | A generated suite needs a durability check. |
|
|
143
|
-
| `qa_pom_generate` | Generates page objects and a locator audit from recorded actions. | A run should produce reusable page objects. |
|
|
144
|
-
| `qa_testcase_generate` | Generates test-case documentation from recorded behavior. | The run should produce human-readable test cases and steps. |
|
|
145
120
|
|
|
146
|
-
##
|
|
121
|
+
## Generate
|
|
147
122
|
|
|
148
|
-
Use
|
|
123
|
+
Use `qa_generate` to turn a session's recorded actions into reusable, per-run test assets. Pick the output with `target`; `mode:"plan"` gives a read-only preview. For the durable repo-level test suite that grows across runs, use `qa_suite_generate` instead.
|
|
149
124
|
|
|
150
125
|
| Tool | What it does | Use when |
|
|
151
126
|
| --- | --- | --- |
|
|
152
|
-
| `
|
|
153
|
-
| `qa_test_suite_update` | Merges cases into the persistent suite, deduping by feature, objective, and steps. | A run produced cases to fold into the suite. |
|
|
154
|
-
| `qa_test_suite_generate` | Generates or refreshes canonical cases from a recorded run and exploration. | The suite needs to be (re)built from observed behavior. |
|
|
155
|
-
| `qa_test_suite_export` | Exports the persistent suite to markdown, a yaml directory, json, or junit. | The suite must be shared or fed to CI. |
|
|
156
|
-
| `qa_test_suite_lint` | Validates the suite for missing expected/actual, stale map links, and duplicate ids. | The suite must be trusted before a release sign-off. |
|
|
127
|
+
| `qa_generate` | Generates test assets from recorded actions: `target:"flow"` (repeatable Flow V2 YAML), `target:"pom"` (page objects + locator audit), `target:"suite"` (full per-run `.swipium/` POM suite with compile/replay gates), `target:"testcases"` (test-case catalog docs), or `target:"appium"` (runnable Appium POM code in JS/TS/Python, with bootstrap from `projectRoot`). `mode:"plan"` previews without writing; for `target:"appium"` it returns the full automation plan with blockers. | A manual or exploratory run should become a reusable flow, page objects, a structured suite, test-case docs, or automation code. |
|
|
157
128
|
|
|
158
|
-
##
|
|
129
|
+
## Persistent Test Suite
|
|
159
130
|
|
|
160
|
-
Use these tools to
|
|
131
|
+
Use these tools to grow and maintain a canonical test suite that persists across runs in `.swipium/test-suite.json`. This is the durable repo-level suite — distinct from the per-run assets `qa_generate` emits.
|
|
161
132
|
|
|
162
133
|
| Tool | What it does | Use when |
|
|
163
134
|
| --- | --- | --- |
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
135
|
+
| `qa_suite_read` | Reads the canonical suite, filtered by functionality or status, as summary, json, or markdown. | The agent needs the durable suite without re-deriving it. |
|
|
136
|
+
| `qa_suite_update` | Merges cases into the persistent suite, deduping by feature, objective, and steps. | A run produced cases to fold into the suite. |
|
|
137
|
+
| `qa_suite_generate` | Generates or refreshes canonical cases from a recorded run and exploration, merging into the durable suite (not per-run assets — use `qa_generate` for those). | The durable suite needs to be (re)built from observed behavior. |
|
|
138
|
+
| `qa_suite_export` | Exports the persistent suite to markdown, a yaml directory, json, or junit. | The suite must be shared or fed to CI. |
|
|
139
|
+
| `qa_suite_lint` | Validates the durable suite (missing expected/actual, stale map links, duplicate ids) and, when `.swipium/pages` exists, also lints generated page objects for brittle locators. | The suite and generated pages must be trusted before a release sign-off. |
|
|
166
140
|
|
|
167
141
|
## Issue Memory and Mobile Audit
|
|
168
142
|
|
|
@@ -171,79 +145,47 @@ Use these tools for a durable, per-project issue ledger and executable mobile-QA
|
|
|
171
145
|
| Tool | What it does | Use when |
|
|
172
146
|
| --- | --- | --- |
|
|
173
147
|
| `qa_issue_log` | Lists the durable issue ledger with counts, recurrence candidates, and linked evidence. | The agent needs the project's known issues. |
|
|
174
|
-
| `qa_issue_history` | Shows the append-only event trail for one issue. | An issue's lifecycle needs auditing. |
|
|
175
|
-
| `qa_issue_mark_fixed` | Records a fix (date, commit, version, how-fixed) so future runs detect regressions. | A reported issue has been resolved. |
|
|
176
|
-
| `qa_issue_triage` | Changes an issue's category, severity, or owner, or appends a note. | An issue needs reclassification. |
|
|
177
|
-
| `qa_issue_suppress` | Suppresses known noise with a reason and expiration; it stays visible as known-noise. | A recurring non-bug should stop dominating reports. |
|
|
178
|
-
| `qa_issue_verify_fixed` | Links passing test or audit evidence to a fixed issue. | A report should honestly claim an issue was verified this run. |
|
|
179
|
-
| `qa_issue_metrics` | Summarizes issue trends: opened, fixed, reopened, verified, aging, and reopen rate. | The user wants issue quality trends. |
|
|
180
148
|
| `qa_mobile_audit` | Plans or executes a named mobile-QA profile (smoke, account_cycle, store_compliance, resilience, release_gate). | A structured, repeatable audit is needed; execution records issues and evidence. |
|
|
181
149
|
|
|
182
150
|
## First Run
|
|
183
151
|
|
|
184
|
-
Use
|
|
152
|
+
Use this tool for login, account creation, onboarding, permissions, OTP, and paywall screens.
|
|
185
153
|
|
|
186
154
|
| Tool | What it does | Use when |
|
|
187
155
|
| --- | --- | --- |
|
|
188
|
-
| `
|
|
189
|
-
| `qa_first_run_continue` | Executes bounded first-run steps with safe generated data when allowed and stops at gates. | The plan can safely proceed in a test or staging environment. |
|
|
190
|
-
|
|
191
|
-
## Automation
|
|
156
|
+
| `qa_first_run` | `mode:"plan"` (default) classifies the current first-run screen and creates a safe plan without acting; `mode:"continue"` executes bounded first-run steps (`until: one_step`/`until_gate`/`until_home`) with safe generated data when allowed and stops at gates. | The agent reaches login, signup, onboarding, permission, OTP, paywall, or home screens. |
|
|
192
157
|
|
|
193
|
-
|
|
158
|
+
## Detailed Reference: Device, Build, and Feature Tools
|
|
194
159
|
|
|
195
|
-
|
|
196
|
-
| --- | --- | --- |
|
|
197
|
-
| `qa_automation_plan` | Plans generated JS, TS, or Python Appium automation from project profile and recorded actions. | The user asks to automate the tested behavior. |
|
|
198
|
-
| `qa_automation_generate` | Generates an Appium POM suite from recorded actions and validates it. | The run should produce automation code. |
|
|
199
|
-
| `qa_automation_validate` | Validates generated automation code without a device. | Generated files need checks for secrets, durability, capabilities, syntax, and empty files. |
|
|
200
|
-
|
|
201
|
-
## Detailed Reference: Device, Visual, State, History, Build, and Feature Tools
|
|
202
|
-
|
|
203
|
-
Technical detail for the tools added alongside the device-parity, visual-intelligence, seeded-state, reporting, build, and feature-testing phases. Most take a `sessionId` from `qa_start_session`; the build, artifact, and read-only feature tools also accept a `projectRoot` so they work before a session exists. Mutating actions accept `consentId` + `approve` and are recorded in the report's mutation ledger.
|
|
160
|
+
Technical detail for retained public device, build, feature, app-map, and agent-helper tools. Most take a `sessionId` from `qa_start_session`; the build, artifact, and read-only feature tools also accept a `projectRoot` so they work before a session exists. Mutating actions accept `consentId` + `approve` and are recorded in the report's mutation ledger.
|
|
204
161
|
|
|
205
162
|
### Device and app environment
|
|
206
163
|
|
|
207
164
|
- **`qa_device_info`** — read-only Android introspection. *Inputs:* `listPackages?`, `packageFilter?`. *Outputs:* `props` (manufacturer, model, SDK, release, ABIs, locale, timezone), `screen` (`width`/`height`/`density`), `orientation`/`rotation`/`autoRotate`, `installedThirdPartyCount`, optional `packages[]`. No consent.
|
|
208
165
|
- **`qa_orientation`** — set rotation. *Inputs:* `orientation: portrait | landscape | auto`. *Outputs:* resulting `orientation`/`rotation`/`autoRotate`. Non-destructive; logged as an environment change.
|
|
209
166
|
- **`qa_geolocation`** — spoof GPS via `adb emu geo fix <lng> <lat>`. *Inputs:* `lat`, `lng` (decimal degrees). *Outputs:* `{ lat, lng, set }`. Consent-gated (medium). Emulator/`direct` backend only; iOS and real devices return `BACKEND_UNSUPPORTED`.
|
|
210
|
-
- **`qa_permissions`** — runtime permission control. *Inputs:* `action: list | grant | revoke`, `package?` (default session `appId`), `permission?` (`android.permission.*`, required for grant/revoke). *Outputs:* `granted[]`/`denied[]` (list) or `{ package, permission, action }`. `list` is read-only; `grant` is consent-gated low (it can mask a permission-prompt bug); `revoke` is consent-gated medium (can break app state).
|
|
211
167
|
- **`qa_network`** — offline/online via `cmd connectivity airplane-mode` (Android 11+). *Inputs:* `action: status | offline | online | restore`. *Outputs:* `network` (`online`/`offline`), `restoreAvailable`. `offline`/`online` consent-gated (medium); the original airplane state is recorded on first change and auto-restored at `qa_report`, on `restore`, and on server shutdown.
|
|
212
168
|
- **`qa_metro`** — RN/Expo Metro lifecycle. *Inputs:* `action: status | diagnose | start | stop`. *Outputs:* `framework`, `metroListening`, `reverseSet`, `serving`, `ready`, `metroPid`, plus `redBox` + `recovery[]` (+ logcat artifact) for `diagnose`. `start` is consent-gated (low): it runs `adb reverse tcp:8081 tcp:8081` and spawns Metro (`npx expo start --dev-client` or `npx react-native start`) detached, logging to an artifact and tracking the PID; `stop` signals the whole process group.
|
|
213
169
|
- **`qa_app_control`** — app lifecycle. *Inputs:* `action: launch | foreground | background | force_stop | restart | clear_data | fresh_start`, `acknowledgeBundleRisk?`. *Outputs:* `packageName`, `action`, `processKilled`, `foreground`, `foregroundIsApp`. `clear_data`/`fresh_start` are destructive → consent-gated (high); on debug RN/Expo builds they additionally require `acknowledgeBundleRisk:true` because a data wipe can remove the cached JS bundle.
|
|
214
|
-
- **`qa_screen_info`** — coordinate-space metadata for visual-fallback work. *Outputs:* `screen` (`width`/`height`/`density`), `orientation`, session `mode`, `latestScreenshot`, named `landmarks` and `bands` (device pixels, origin top-left), `counters`, `budget`. Read-only.
|
|
215
170
|
- **`qa_screen_record`** — screen video. *Inputs:* `action: start | status | stop`, `save?: always | on_failure`, `failed?`. *Outputs:* `recording`/`capturing`/`autoStopped`, `seconds`, and on stop a `uri` (mp4 artifact) + `bytes`. Consent-gated (medium); refused on sensitive sessions. Android uses `adb screenrecord --time-limit 180`; iOS uses `simctl io recordVideo`. One recording per session.
|
|
216
171
|
|
|
217
|
-
### Visual intelligence (local-first)
|
|
218
|
-
|
|
219
|
-
- **`qa_visual`** — deterministic visual ops + regression. *Inputs:* `action: baseline | diff | find_image | ocr`, `name?` (baseline/diff), `template?` (find_image PNG path), `threshold?` (diff, default 0.02), `minScore?` (find_image, default 0.85), `force?`. *Outputs:* always include `coordinateSpace` (screenshot↔device scale); `diff` adds `changedRatio`/`pass`/`changedBoxDevice`; `find_image` adds `devicePoint`. `baseline`/`diff`/`find_image` are local and need no consent; `ocr` is consent-gated and requires a configured `ocrCommand`. Withheld when a secure (password/OTP) field is on screen unless `force:true`.
|
|
220
|
-
- **`qa_visual_find_text`** — OCR text locator. *Inputs:* `query`, `minConfidence?` (default 0.8). *Outputs:* `found`, matched `region` (text/confidence/bbox), `devicePoint`, `coordinateSpace`. Consent-gated (the screenshot is passed to the configured local OCR provider); requires `ocrCommand` returning JSON regions.
|
|
221
|
-
|
|
222
|
-
### Seeded state
|
|
223
|
-
|
|
224
|
-
- **`qa_seed`** — create a declared precondition. *Inputs:* `fixture` (must declare a `seed`: `deeplink | script | api`). *Outputs:* `{ fixture, type, seeded, warnings[] }`. Consent-gated; risk scales by type (`script` high, `api` medium, `deeplink` low). Git commands are refused (`GIT_SCOPE_FORBIDDEN`); a failed seed is reported as a SETUP failure (`missing_test_data`), never an app bug.
|
|
225
|
-
- **`qa_state_prepare`** — apply a state profile as one transaction. *Inputs:* `profile` (`.swipium/state/<name>.yaml` or inline YAML). *Outputs:* a state `ledger` + `ledgerUri`. Consent-gated when it mutates (reset/launch/seed); refuses debug-bundle-loss resets unless acknowledged.
|
|
226
|
-
- **`qa_state_verify`** — confirm a profile's declared checks (e.g. `assertVisible`). *Inputs:* `profile`. *Outputs:* verification `ledger`. Non-mutating; failures are setup/state blockers, not app-test failures.
|
|
227
|
-
- **`qa_state_teardown`** — run profile teardown. *Inputs:* `profile`. *Outputs:* teardown `ledger`. Consent-gated when it mutates; restores declared state such as `networkOnline` and runs fixture cleanup hooks.
|
|
228
|
-
|
|
229
|
-
### Report history
|
|
230
|
-
|
|
231
|
-
- **`qa_report_compare`** — diff two reports. *Inputs:* `current`, `baseline` (paths to `report.json`), `trendRoot?`. *Outputs:* new/fixed failures, changed screenshots, outcome changes, runtime regression, optional flake status, and a `summary`. Filesystem-only — no session or device.
|
|
232
|
-
- **`qa_run_history`** — local trend summary. *Inputs:* `sessionId?` or `projectRoot?`. *Outputs:* report count, per-flow `passRate`, median/average runtime, top failures, flaky flows, confidence calibration, and slowest steps. Reads `.swipium/runs/**/report.json` (and legacy `.swipium/ci/**`).
|
|
233
|
-
|
|
234
172
|
### Build and artifact resolution
|
|
235
173
|
|
|
236
174
|
- **`qa_resolve_target`** — choose the best device or simulator, deterministically and side-effect free. *Inputs:* `sessionId?`, `projectRoot?`, `platform?` (`android`/`ios`), `device?` (name/serial/udid), `preferRealDevice?`. *Outputs:* `selection` (kind + id), a human `reason`, `alternatives[]`, `preconditions` (e.g. WDA/signing), and `willBoot`. Does not boot anything — `qa_prepare_target`/`qa_ios` do that.
|
|
237
|
-
- **`qa_resolve_artifact`** — find the best installable artifact and explain the search. *Inputs:* `sessionId?`, `projectRoot?`, `platform?` (`android`/`ios`/`any`), `buildType?` (`debug`/`release`/`any`), `path?` (explicit artifact), `allowOutsideRoot?`, `requireInstallableOn?` (`android-emulator`/`android-real`/`ios-simulator`/`ios-real`). *Outputs:* the resolved `.apk`/`.aab`/`.ipa`/`.app` and its type; on failure, the exact globs searched plus a `
|
|
238
|
-
- **`
|
|
239
|
-
- **`
|
|
240
|
-
- **`qa_bundletool`** — convert an Android App Bundle to an installable APK. *Inputs:* `sessionId` (required), `aab?` (default: the best `.aab` under the project), `force?`, `connectedDevice?` (device-specific APK set vs a universal APK), `install?` (also run `install-apks`), `deviceId?`, `consentId?`/`approve?`. *Outputs:* the generated APK or APK-set path. `install` is consent-gated because it installs app code on a device/emulator.
|
|
175
|
+
- **`qa_resolve_artifact`** — find the best installable artifact and explain the search. *Inputs:* `sessionId?`, `projectRoot?`, `platform?` (`android`/`ios`/`any`), `buildType?` (`debug`/`release`/`any`), `path?` (explicit artifact), `allowOutsideRoot?`, `requireInstallableOn?` (`android-emulator`/`android-real`/`ios-simulator`/`ios-real`). *Outputs:* the resolved `.apk`/`.aab`/`.ipa`/`.app` and its type; on failure, the exact globs searched plus a `qa_build { mode:"plan" }` → `qa_build { mode:"run" }` next step. Read-only.
|
|
176
|
+
- **`qa_build`** — plan or run a from-source build. *Inputs:* `mode?` (`plan` (default) / `run`), `platform` (`android`/`ios`), `variant?` (`debug`/`release`); `sessionId?`/`projectRoot?` for `mode:"plan"`; `sessionId` (required), `timeoutMs?`, `consentId?`/`approve?` for `mode:"run"`. *Outputs:* in `plan` mode the detected `framework`, the exact build commands, the expected artifact path, and a cost estimate — side-effect free, with a typed error when no supported framework (Expo, bare React Native, native Android/iOS, Flutter) is detected; in `run` mode a `jobId` to poll with `qa_job_status`, and on completion a build-log artifact and the re-resolved artifact path. `mode:"run"` is consent-gated (it compiles the app).
|
|
177
|
+
- **`qa_bundletool`** — convert an Android App Bundle to an installable APK. *Inputs:* `sessionId` (required), `aab?` (default: the best `.aab` under the project), `force?`, `connectedDevice?` (device-specific APK set vs a universal APK), `install?` (also run `install-apks`), `device?` (adb serial), `consentId?`/`approve?`. *Outputs:* the generated APK or APK-set path. `install` is consent-gated because it installs app code on a device/emulator.
|
|
241
178
|
|
|
242
179
|
### Feature-focused testing
|
|
243
180
|
|
|
244
|
-
- **`
|
|
245
|
-
- **`
|
|
246
|
-
|
|
181
|
+
- **`qa_app_map_feature_scope`** — map a feature to the app, read-only. *Inputs:* `query` (free text, e.g. "weather analysis") or `featureId` (exact map feature id), `sessionId?` (adds runtime screen-graph evidence), `projectRoot?` (static code scope), `platform?`, `includeCode?` (default true), `limit?`. *Outputs:* in query mode, ranked `candidates` each tagged by `source` (`code`/`screen`/`route`/`runtime`/`test`) with confidence, plus a test `objective` and `strategy`; in featureId mode, the map feature's source files, screens, coverage, blockers, and recommended plan. No consent. Query mode works before a map exists; returns `found:false` with guidance when nothing matches.
|
|
182
|
+
- **`qa_test_feature`** — run a focused test toward a named feature. *Inputs:* `feature` (required), `sessionId` (required), `mode?` (`plan` (default) / `execute` (focused run as a job) / `interactive` (run until the first question)), `platform?`, `device?`, `creativity?`, `allowAdversarial?`, `maxScreens?`, `maxActions?`, `timeoutMs?`, `generateCases?`, `consentId?`/`approve?`. *Outputs:* in `plan` mode the read-only test plan (scope, objective, generated cases, fixtures, execution plan); in `execute` mode a `jobId` whose run performs targeted exploration toward the feature, records cases, updates the feature map, and emits a report. `execute`/`interactive` are consent-gated.
|
|
183
|
+
|
|
184
|
+
### App-map maintenance and agent helpers
|
|
185
|
+
|
|
186
|
+
- **`qa_inspect`** — full attributes of one element. *Inputs:* `sessionId`, `ref` (e.g. `@e3`). *Outputs:* `class`, `id`, `contentDesc`, `text`, `bounds`, the interaction flags (`clickable`/`scrollable`/`focused`/`enabled`/…), and the raw `attrs`. Secret values are redacted and a secure field's value is masked as `«secure»`. Read-only; refs come from the most recent `qa_snapshot` and invalidate after navigation.
|
|
187
|
+
- **`qa_next_best_action`** — deterministic next-step recommendation. *Inputs:* `sessionId`, `goal?` (`smoke`/`explore`/`create_automation_suite`/`release_gate`/`test_login`/`reproduce_bug`). *Outputs:* `nextBestAction` (the `tool`, suggested `args`, and `why`). Read-only.
|
|
188
|
+
- **`qa_app_map_update`** — targeted, provenance-tracked map edits. *Inputs:* `projectRoot?`/`sessionId?` plus any of `note`, `testCases[]`, `automationSuite`, `environment`, `featureCoverage`. *Outputs:* `applied[]` and the `appMapUri`. Recomputes confidence and coverage and persists. Requires an existing map (`qa_app_map_build` first).
|
|
247
189
|
|
|
248
190
|
## Recommended Entry Points
|
|
249
191
|
|
|
@@ -260,8 +202,8 @@ Technical detail for the tools added alongside the device-parity, visual-intelli
|
|
|
260
202
|
| "Read app memory" | `qa_app_map_read` |
|
|
261
203
|
| "Test the X feature" | `qa_test_feature` |
|
|
262
204
|
| "Find/build an artifact" | `qa_resolve_artifact` / `qa_build` |
|
|
263
|
-
| "Create a flow" | `
|
|
264
|
-
| "Generate automation" | `
|
|
205
|
+
| "Create a flow" | `qa_generate` with `target:"flow"` |
|
|
206
|
+
| "Generate automation" | `qa_generate` with `target:"appium"` |
|
|
265
207
|
|
|
266
208
|
## Extension Pattern
|
|
267
209
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swipium",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Swipium MCP server for simulator-based mobile QA workflows, evidence capture, app maps, and generated test suites.",
|
|
6
6
|
"keywords": [
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|
|
30
30
|
"docs",
|
|
31
|
-
"THREAT_MODEL.md"
|
|
31
|
+
"THREAT_MODEL.md",
|
|
32
|
+
"CHANGELOG.md"
|
|
32
33
|
],
|
|
33
34
|
"engines": {
|
|
34
35
|
"node": ">=20"
|
|
35
36
|
},
|
|
36
37
|
"repository": {
|
|
37
38
|
"type": "git",
|
|
38
|
-
"url": "
|
|
39
|
+
"url": "https://github.com/GeroPalombo/swipium"
|
|
39
40
|
},
|
|
40
41
|
"bugs": {
|
|
41
42
|
"url": "https://github.com/geropalombo/swipium/issues"
|
|
@@ -45,14 +46,18 @@
|
|
|
45
46
|
"access": "public"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {
|
|
48
|
-
"
|
|
49
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
50
|
+
"build": "npm run clean && tsc && chmod +x dist/index.js",
|
|
49
51
|
"dev": "tsc -w",
|
|
50
52
|
"start": "node dist/index.js",
|
|
51
53
|
"verify": "npm run build && node dist/index.js verify",
|
|
52
54
|
"typecheck": "tsc --noEmit",
|
|
55
|
+
"lint": "eslint .",
|
|
56
|
+
"format": "prettier --write .",
|
|
57
|
+
"format:check": "prettier --check .",
|
|
53
58
|
"test": "vitest run",
|
|
54
59
|
"audit:prod": "npm audit --omit=dev --audit-level=moderate",
|
|
55
|
-
"release:check": "npm run typecheck && npm test && npm run audit:prod && npm pack --dry-run",
|
|
60
|
+
"release:check": "npm run typecheck && npm run lint && npm run format:check && npm test && npm run audit:prod && npm pack --dry-run",
|
|
56
61
|
"prepack": "npm run build",
|
|
57
62
|
"prepublishOnly": "npm run build",
|
|
58
63
|
"inspector": "npm run build && npx @modelcontextprotocol/inspector node dist/index.js"
|
|
@@ -64,8 +69,12 @@
|
|
|
64
69
|
"zod": "^3.25.76"
|
|
65
70
|
},
|
|
66
71
|
"devDependencies": {
|
|
72
|
+
"@eslint/js": "^10.0.1",
|
|
67
73
|
"@types/node": "^22.10.2",
|
|
74
|
+
"eslint": "^10.6.0",
|
|
75
|
+
"prettier": "^3.9.4",
|
|
68
76
|
"typescript": "^5.7.2",
|
|
77
|
+
"typescript-eslint": "^8.62.1",
|
|
69
78
|
"vitest": "^4.1.7"
|
|
70
79
|
}
|
|
71
80
|
}
|
package/dist/appMap/diff.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
// Map diff (SWIPIUM-REQ-01 qa_app_map_diff). Reports added/removed/changed screens, feature
|
|
2
|
-
// coverage changes, stale test cases, locator-readiness changes, and new untested code areas
|
|
3
|
-
// between two AppKnowledgeMap snapshots. Pure — the tool layer resolves which two maps to compare.
|
|
4
|
-
function ids(arr) {
|
|
5
|
-
return new Set(arr.map((a) => a.id));
|
|
6
|
-
}
|
|
7
|
-
export function diffAppMaps(baseline, current) {
|
|
8
|
-
const baseStatic = ids(baseline.staticTopology.screens);
|
|
9
|
-
const curStatic = ids(current.staticTopology.screens);
|
|
10
|
-
const baseRuntime = ids(baseline.runtimeTopology.screens);
|
|
11
|
-
const curRuntime = ids(current.runtimeTopology.screens);
|
|
12
|
-
const staticAdded = [...curStatic].filter((id) => !baseStatic.has(id));
|
|
13
|
-
const staticRemoved = [...baseStatic].filter((id) => !curStatic.has(id));
|
|
14
|
-
const runtimeAdded = [...curRuntime].filter((id) => !baseRuntime.has(id));
|
|
15
|
-
const runtimeRemoved = [...baseRuntime].filter((id) => !curRuntime.has(id));
|
|
16
|
-
// changed runtime screens: visits / link / readiness drift
|
|
17
|
-
const changedScreens = [];
|
|
18
|
-
const locatorReadinessChanges = [];
|
|
19
|
-
for (const cur of current.runtimeTopology.screens) {
|
|
20
|
-
const prev = baseline.runtimeTopology.screens.find((s) => s.id === cur.id || s.signature === cur.signature);
|
|
21
|
-
if (!prev)
|
|
22
|
-
continue;
|
|
23
|
-
if (prev.linkedStaticScreenId !== cur.linkedStaticScreenId) {
|
|
24
|
-
changedScreens.push({ id: cur.id, field: 'linkedStaticScreenId', was: prev.linkedStaticScreenId ?? null, now: cur.linkedStaticScreenId ?? null });
|
|
25
|
-
}
|
|
26
|
-
if (prev.locatorReadiness !== cur.locatorReadiness) {
|
|
27
|
-
locatorReadinessChanges.push({ id: cur.id, was: prev.locatorReadiness, now: cur.locatorReadiness });
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
// feature coverage changes
|
|
31
|
-
const featureCoverageChanges = [];
|
|
32
|
-
for (const cur of current.features) {
|
|
33
|
-
const prev = baseline.features.find((f) => f.id === cur.id);
|
|
34
|
-
if (prev && prev.testCoverage !== cur.testCoverage) {
|
|
35
|
-
featureCoverageChanges.push({ featureId: cur.id, was: prev.testCoverage, now: cur.testCoverage });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// stale tests: cases whose feature/screen no longer exists in current
|
|
39
|
-
const curFeatureIds = ids(current.features);
|
|
40
|
-
const staleTests = current.testSuite.cases
|
|
41
|
-
.filter((c) => (c.featureId && !curFeatureIds.has(c.featureId)) || (c.screenId && !curStatic.has(c.screenId) && !curRuntime.has(c.screenId)) || c.stale)
|
|
42
|
-
.map((c) => c.id);
|
|
43
|
-
// new untested code areas: newly added static screens with no linked runtime screen
|
|
44
|
-
const linkedStatic = new Set(current.runtimeTopology.screens.map((r) => r.linkedStaticScreenId).filter(Boolean));
|
|
45
|
-
const newUntestedCodeAreas = staticAdded.filter((id) => !linkedStatic.has(id));
|
|
46
|
-
const summary = `+${staticAdded.length}/-${staticRemoved.length} static screens, +${runtimeAdded.length}/-${runtimeRemoved.length} runtime screens; ` +
|
|
47
|
-
`${featureCoverageChanges.length} coverage change(s), ${locatorReadinessChanges.length} locator-readiness change(s), ` +
|
|
48
|
-
`${staleTests.length} stale test(s), ${newUntestedCodeAreas.length} new untested area(s)`;
|
|
49
|
-
return {
|
|
50
|
-
staticScreens: { added: staticAdded, removed: staticRemoved },
|
|
51
|
-
runtimeScreens: { added: runtimeAdded, removed: runtimeRemoved },
|
|
52
|
-
changedScreens,
|
|
53
|
-
featureCoverageChanges,
|
|
54
|
-
locatorReadinessChanges,
|
|
55
|
-
staleTests,
|
|
56
|
-
newUntestedCodeAreas,
|
|
57
|
-
summary,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=diff.js.map
|
package/dist/appMap/diff.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/appMap/diff.ts"],"names":[],"mappings":"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"}
|