@sun-asterisk/sungen 3.2.0-beta.142 → 3.2.0-beta.143
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/capabilities/context-router.d.ts +11 -2
- package/dist/capabilities/context-router.d.ts.map +1 -1
- package/dist/capabilities/context-router.js +10 -3
- package/dist/capabilities/context-router.js.map +1 -1
- package/dist/capabilities/discover.js +1 -1
- package/dist/capabilities/discover.js.map +1 -1
- package/dist/generators/test-generator/adapters/appium/appium-adapter.d.ts +54 -0
- package/dist/generators/test-generator/adapters/appium/appium-adapter.d.ts.map +1 -0
- package/dist/generators/test-generator/adapters/appium/appium-adapter.js +52 -0
- package/dist/generators/test-generator/adapters/appium/appium-adapter.js.map +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/after-all.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/after-each.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/before-all.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/before-each.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/imports.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/scenario.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/alert-accept-action.hbs +4 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/alert-dismiss-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/alert-fill-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/check-action.hbs +10 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/clear-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/click-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/click-element-with-text.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/click-select-action.hbs +4 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/dismiss-action.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/double-click-action.hbs +6 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/drag-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/expand-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/fill-action.hbs +14 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/fill-editor-action.hbs +12 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/frame-enter-action.hbs +6 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/frame-exit-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/hide-keyboard-action.hbs +4 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/hover-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/keyboard-global-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/press-action.hbs +4 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/radio-select-action.hbs +4 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +19 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/select-action.hbs +5 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/table-action-in-row.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/uncheck-action.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/unknown-element-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/upload-action.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/wait-for-page.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/wait-for-role-with-data.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/wait-for-role.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/alert-text-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/attribute-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/clipboard-text-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/column-cell-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +14 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/count-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/disabled-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/empty-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/enabled-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/focused-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/have-text-assertion.hbs +15 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/have-value-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/is-hidden-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +12 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/list-item-count-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/loading-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/page-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/route-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/selected-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/sorted-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/table-column-exists.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/table-empty.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/table-match-data.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/table-row-count.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/table-row-exists.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/table-row-not-exists.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/visible-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/background-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/grant-permission-action.hbs +11 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/long-press-action.hbs +5 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/open-notifications-action.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/pinch-zoom-action.hbs +5 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/pull-to-refresh-action.hbs +5 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/rotate-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/set-clipboard-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/set-geolocation-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/swipe-action.hbs +5 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/tap-top-action.hbs +24 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/navigation/navigation.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/navigation/wait-for-element-with-text.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/navigation/wait-for-element.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/navigation/wait-timeout.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/partials/appium-selector-expr.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/partials/appium-selector.hbs +15 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/partials/locator.hbs +8 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/setup/application-running.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/setup/clear-auth.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/setup/clear-browser-state.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/setup/clear-database.hbs +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/setup/user-login-todo.hbs +2 -0
- package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +226 -0
- package/dist/generators/test-generator/adapters/index.d.ts +1 -0
- package/dist/generators/test-generator/adapters/index.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/index.js +9 -1
- package/dist/generators/test-generator/adapters/index.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +1 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +7 -37
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +13 -1
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/harness/audit.d.ts +1 -1
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +14 -4
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/drivers.yaml +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +8 -0
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md +184 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-mobile-gestures.md +109 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md +316 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +184 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md +109 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +316 -0
- package/dist/orchestrator/templates/env.appium.example +25 -0
- package/dist/orchestrator/templates/specs-pw-shape-reporter.ts +92 -0
- package/dist/orchestrator/templates/wdio.conf.ts +295 -0
- package/dist/utils/selector-types.d.ts +1 -1
- package/dist/utils/selector-types.d.ts.map +1 -1
- package/dist/utils/selector-types.js +5 -0
- package/dist/utils/selector-types.js.map +1 -1
- package/package.json +3 -3
- package/src/capabilities/context-router.ts +15 -3
- package/src/capabilities/discover.ts +1 -1
- package/src/generators/test-generator/adapters/appium/appium-adapter.ts +57 -0
- package/src/generators/test-generator/adapters/appium/templates/after-all.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/after-each.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/before-all.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/before-each.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/imports.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/scenario.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/alert-accept-action.hbs +4 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/alert-dismiss-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/alert-fill-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/check-action.hbs +10 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/clear-action.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/click-action.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/click-element-with-text.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/click-select-action.hbs +4 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/dismiss-action.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/double-click-action.hbs +6 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/drag-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/expand-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/fill-action.hbs +14 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/fill-editor-action.hbs +12 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/frame-enter-action.hbs +6 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/frame-exit-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/hide-keyboard-action.hbs +4 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/hover-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/keyboard-global-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/press-action.hbs +4 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/radio-select-action.hbs +4 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +19 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/select-action.hbs +5 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/table-action-in-row.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/uncheck-action.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/unknown-element-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/upload-action.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/wait-for-page.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/wait-for-role-with-data.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/wait-for-role.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/alert-text-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/attribute-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/clipboard-text-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/column-cell-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +14 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/count-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/disabled-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/empty-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/enabled-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/focused-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/have-text-assertion.hbs +15 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/have-value-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/is-hidden-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +12 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/list-item-count-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/loading-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/page-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/route-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/selected-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/sorted-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/table-column-exists.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/table-empty.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/table-match-data.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/table-row-count.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/table-row-exists.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/table-row-not-exists.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/visible-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/background-action.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/grant-permission-action.hbs +11 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/long-press-action.hbs +5 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/open-notifications-action.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/pinch-zoom-action.hbs +5 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/pull-to-refresh-action.hbs +5 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/rotate-action.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/set-clipboard-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/set-geolocation-action.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/swipe-action.hbs +5 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/tap-top-action.hbs +24 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/navigation/navigation.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/navigation/wait-for-element-with-text.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/navigation/wait-for-element.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/navigation/wait-timeout.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/partials/appium-selector-expr.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/partials/appium-selector.hbs +15 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/partials/locator.hbs +8 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/setup/application-running.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/setup/clear-auth.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/setup/clear-browser-state.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/setup/clear-database.hbs +1 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/setup/user-login-todo.hbs +2 -0
- package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +226 -0
- package/src/generators/test-generator/adapters/index.ts +7 -0
- package/src/generators/test-generator/step-mapper.ts +8 -5
- package/src/generators/test-generator/template-engine.ts +13 -1
- package/src/harness/audit.ts +12 -4
- package/src/harness/catalog/drivers.yaml +1 -1
- package/src/orchestrator/ai-rules-updater.ts +8 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md +184 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-mobile-gestures.md +109 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md +316 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +184 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md +109 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +316 -0
- package/src/orchestrator/templates/env.appium.example +25 -0
- package/src/orchestrator/templates/specs-pw-shape-reporter.ts +92 -0
- package/src/orchestrator/templates/wdio.conf.ts +295 -0
- package/src/utils/selector-types.ts +5 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebdriverIO runner config for sungen mobile (Appium) tests.
|
|
3
|
+
* Mobile equivalent of playwright.config.ts. Run with: npm run test:mobile
|
|
4
|
+
*
|
|
5
|
+
* Capabilities default to the app configured at `sungen init --mobile`, but every value can be
|
|
6
|
+
* overridden at runtime via env vars — no need to edit this file to target another app/device:
|
|
7
|
+
* APP_PACKAGE=com.other.app ANDROID_UDID=emulator-5556 npm run test:mobile
|
|
8
|
+
* (the launch activity is auto-detected from APP_PACKAGE; set APP_ACTIVITY only to pin a non-standard one)
|
|
9
|
+
* APP_APK=/path/to/app.apk npm run test:mobile # install + run from an .apk (Appium derives pkg/activity)
|
|
10
|
+
*
|
|
11
|
+
* iOS Simulator (opt in with MOBILE_PLATFORM=ios; needs Xcode + the xcuitest driver):
|
|
12
|
+
* MOBILE_PLATFORM=ios IOS_BUNDLE_ID=com.example.app npm run test:mobile # app already installed on the sim
|
|
13
|
+
* MOBILE_PLATFORM=ios IOS_APP=/path/MyApp.app npm run test:mobile # Appium installs a Simulator build
|
|
14
|
+
* (+ optional IOS_DEVICE='iPhone 16' IOS_VERSION='18.0' IOS_UDID=<sim-udid>)
|
|
15
|
+
*
|
|
16
|
+
* The @wdio/appium-service auto-starts a local Appium server (auto-detecting the uiautomator2 / xcuitest driver).
|
|
17
|
+
*/
|
|
18
|
+
/// <reference types="node" />
|
|
19
|
+
/// <reference types="@wdio/globals/types" />
|
|
20
|
+
// Load .env.appium (if present) into process.env FIRST — so every override below (ANDROID_HOME / JAVA_HOME /
|
|
21
|
+
// ANDROID_UDID / APP_PACKAGE / IOS_BUNDLE_ID / MOBILE_PLATFORM / SUNGEN_ENV …) can come from a dedicated
|
|
22
|
+
// .env.appium file instead of shell exports. A separate file (not the generic .env) keeps Appium config from
|
|
23
|
+
// clashing with other .env vars (e.g. FIGMA_PAT). dotenv is a dependency; a missing .env.appium is a no-op.
|
|
24
|
+
import dotenv from 'dotenv';
|
|
25
|
+
dotenv.config({ path: '.env.appium' });
|
|
26
|
+
import * as fs from 'node:fs';
|
|
27
|
+
import * as path from 'node:path';
|
|
28
|
+
import PwShapeReporter from './specs/reporters/pw-shape-reporter';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Auto-select MOBILE specs and classify each by its target OS (dual-target routing).
|
|
32
|
+
*
|
|
33
|
+
* sungen emits one spec per feature; the test runner differs by platform:
|
|
34
|
+
* - mobile/appium specs import from '@wdio/globals' ← run these with wdio
|
|
35
|
+
* - web/playwright specs import from '@playwright/test' ← run those with `playwright test`
|
|
36
|
+
* The '@wdio/globals' import is the machine-readable "platform = mobile" marker, so we keep
|
|
37
|
+
* only those files and never feed Playwright specs into the (incompatible) mocha runner.
|
|
38
|
+
*
|
|
39
|
+
* Each mobile spec also carries a `// sungen:platform=<mobile|android|ios>` marker (emitted from the
|
|
40
|
+
* feature's @platform:* tag). It routes the spec per OS:
|
|
41
|
+
* - mobile → cross-platform: runs on BOTH the Android and iOS capability sets
|
|
42
|
+
* - android → Android cap only
|
|
43
|
+
* - ios → iOS cap only
|
|
44
|
+
* A spec with no marker (older codegen) defaults to `mobile` (runs on both) so nothing is dropped.
|
|
45
|
+
*
|
|
46
|
+
* Override with SUNGEN_SPECS=<glob-or-path> for a single spec (still classified by its marker).
|
|
47
|
+
*/
|
|
48
|
+
function readPlatformMarker(file: string): 'mobile' | 'android' | 'ios' {
|
|
49
|
+
try {
|
|
50
|
+
const m = /sungen:platform=(mobile|android|ios)/.exec(fs.readFileSync(file, 'utf-8'));
|
|
51
|
+
return (m?.[1] as 'mobile' | 'android' | 'ios') || 'mobile';
|
|
52
|
+
} catch {
|
|
53
|
+
return 'mobile';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function classifyMobileSpecs(root: string): Array<{ file: string; platform: string }> {
|
|
57
|
+
if (!fs.existsSync(root)) return [];
|
|
58
|
+
return (fs.readdirSync(root, { recursive: true }) as string[])
|
|
59
|
+
.filter((rel) => rel.endsWith('.spec.ts'))
|
|
60
|
+
.map((rel) => path.join(root, rel))
|
|
61
|
+
.filter((full) => {
|
|
62
|
+
try {
|
|
63
|
+
return fs.readFileSync(full, 'utf-8').includes('@wdio/globals');
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.map((file) => ({ file, platform: readPlatformMarker(file) }));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const specEntries = process.env.SUNGEN_SPECS
|
|
72
|
+
? [process.env.SUNGEN_SPECS].map((file) => ({ file, platform: readPlatformMarker(file) }))
|
|
73
|
+
: classifyMobileSpecs(path.join(process.cwd(), 'specs', 'generated'));
|
|
74
|
+
|
|
75
|
+
// Android cap runs android + mobile (everything except ios-only); iOS cap runs ios + mobile.
|
|
76
|
+
const androidSpecs = specEntries.filter((e) => e.platform !== 'ios').map((e) => e.file);
|
|
77
|
+
const iosSpecs = specEntries.filter((e) => e.platform !== 'android').map((e) => e.file);
|
|
78
|
+
const mobileSpecs = specEntries.map((e) => e.file); // union — top-level fallback
|
|
79
|
+
|
|
80
|
+
// App under test — env overrides the init-configured defaults.
|
|
81
|
+
const APP_PACKAGE = process.env.APP_PACKAGE || '__APP_PACKAGE__';
|
|
82
|
+
const APP_ACTIVITY = process.env.APP_ACTIVITY || '__APP_ACTIVITY__';
|
|
83
|
+
const APP_APK = process.env.APP_APK; // optional: install + launch from an .apk file
|
|
84
|
+
// appActivity is OPTIONAL: UiAutomator2 auto-resolves the package's launcher activity when it's
|
|
85
|
+
// omitted, and the per-scenario relaunch uses activateApp(package) (no activity). So Android needs
|
|
86
|
+
// only APP_PACKAGE — set APP_ACTIVITY only to pin a non-standard launcher. iOS has no activity
|
|
87
|
+
// concept at all (bundleId only). Only pass the cap when APP_ACTIVITY is a real value (not the
|
|
88
|
+
// unfilled scaffold placeholder / empty), so a package-only setup launches cleanly.
|
|
89
|
+
const HAS_REAL_APP_ACTIVITY = !!APP_ACTIVITY && APP_ACTIVITY !== '__APP_ACTIVITY__';
|
|
90
|
+
|
|
91
|
+
// ── iOS (Simulator) — opt in with MOBILE_PLATFORM=ios; every value is env-overridable ──────────
|
|
92
|
+
// MOBILE_PLATFORM=ios IOS_BUNDLE_ID=com.example.app npm run test:mobile
|
|
93
|
+
// - IOS_APP=/path/MyApp.app → Appium installs a SIMULATOR build (.app or zipped .app) first.
|
|
94
|
+
// (A device .ipa won't run on a Simulator — wrong binary/platform.)
|
|
95
|
+
// - IOS_BUNDLE_ID=com.x → attach to an app already installed on the sim (simctl install first).
|
|
96
|
+
// - IOS_DEVICE / IOS_VERSION → pick the simulator; IOS_UDID targets a specific one.
|
|
97
|
+
//
|
|
98
|
+
// MOBILE_PLATFORM selects which capability set(s) run:
|
|
99
|
+
// android (default) → Android cap only (runs @platform:android + @platform:mobile specs)
|
|
100
|
+
// ios → iOS cap only (runs @platform:ios + @platform:mobile specs)
|
|
101
|
+
// both → BOTH caps in one run (a @platform:mobile spec executes on each — write once, run both)
|
|
102
|
+
const MOBILE_PLATFORM = (process.env.MOBILE_PLATFORM || 'android').toLowerCase();
|
|
103
|
+
const RUN_ANDROID = MOBILE_PLATFORM === 'android' || MOBILE_PLATFORM === 'both';
|
|
104
|
+
const RUN_IOS = MOBILE_PLATFORM === 'ios' || MOBILE_PLATFORM === 'both';
|
|
105
|
+
const IOS_APP = process.env.IOS_APP;
|
|
106
|
+
const IOS_BUNDLE_ID = process.env.IOS_BUNDLE_ID || '__IOS_BUNDLE_ID__';
|
|
107
|
+
const IOS_DEVICE = process.env.IOS_DEVICE || '__IOS_DEVICE__';
|
|
108
|
+
const IOS_VERSION = process.env.IOS_VERSION || '__IOS_VERSION__';
|
|
109
|
+
// platformVersion is OPTIONAL on a real device: with IOS_UDID set, XCUITest reads the iOS version off
|
|
110
|
+
// the connected device. Only pass the cap when IOS_VERSION is a real value (not the unfilled scaffold
|
|
111
|
+
// placeholder). On a Simulator set it (or IOS_DEVICE) so Appium picks a matching runtime.
|
|
112
|
+
const HAS_REAL_IOS_VERSION = !!IOS_VERSION && IOS_VERSION !== '__IOS_VERSION__';
|
|
113
|
+
const IOS_UDID = process.env.IOS_UDID;
|
|
114
|
+
// Real iPhone (device) — WebDriverAgent must be code-signed onto it. Set IOS_TEAM_ID (your Apple
|
|
115
|
+
// Team ID) to switch the iOS cap into real-device mode; the Simulator ignores these (they're only
|
|
116
|
+
// emitted when IOS_TEAM_ID is present, so Simulator runs are unchanged). For a real device also set
|
|
117
|
+
// IOS_UDID (the device udid, NOT a sim) and the REAL IOS_BUNDLE_ID (Android package ≠ iOS bundle id).
|
|
118
|
+
const IOS_TEAM_ID = process.env.IOS_TEAM_ID; // → appium:xcodeOrgId
|
|
119
|
+
const IOS_SIGNING_ID = process.env.IOS_SIGNING_ID || 'Apple Development'; // → appium:xcodeSigningId
|
|
120
|
+
const IOS_WDA_BUNDLE_ID = process.env.IOS_WDA_BUNDLE_ID || 'com.sungen.wda'; // → appium:updatedWDABundleId; default gives WDA a unique id (required for free teams) so you needn't set it
|
|
121
|
+
|
|
122
|
+
// ── i18n (device locale) ────────────────────────────────────────────────────
|
|
123
|
+
// SUNGEN_ENV doubles as the locale selector (the same var that swaps the test-data overlay).
|
|
124
|
+
// When its value looks like a locale code ("vi", "ja", "vi-VN"), drive the DEVICE locale via
|
|
125
|
+
// appium:language/appium:locale so an app that localizes from device locale on first launch picks
|
|
126
|
+
// it up, and force a data reset (noReset:false) so that first-launch path actually re-runs (clears
|
|
127
|
+
// any persisted in-app language override). Non-locale envs ("staging", "production") are left
|
|
128
|
+
// untouched, so existing suites are unaffected. SUNGEN_LOCALE overrides explicitly when the device
|
|
129
|
+
// locale must differ from the overlay name. Country defaults are used only when the code omits a region.
|
|
130
|
+
const LOCALE_COUNTRY: Record<string, string> = {
|
|
131
|
+
vi: 'VN',
|
|
132
|
+
ja: 'JP',
|
|
133
|
+
en: 'US',
|
|
134
|
+
ko: 'KR',
|
|
135
|
+
zh: 'CN',
|
|
136
|
+
th: 'TH',
|
|
137
|
+
id: 'ID',
|
|
138
|
+
fr: 'FR',
|
|
139
|
+
de: 'DE',
|
|
140
|
+
es: 'ES',
|
|
141
|
+
pt: 'BR',
|
|
142
|
+
ru: 'RU',
|
|
143
|
+
};
|
|
144
|
+
function resolveLocaleCaps(): Record<string, unknown> {
|
|
145
|
+
const raw = process.env.SUNGEN_LOCALE || process.env.SUNGEN_ENV;
|
|
146
|
+
if (!raw) return {};
|
|
147
|
+
const m = /^([a-z]{2})(?:[-_]([A-Za-z]{2}))?$/.exec(raw.trim());
|
|
148
|
+
if (!m) return {}; // not a locale code (e.g. "staging") → don't touch the device locale
|
|
149
|
+
const language = m[1];
|
|
150
|
+
const country = (m[2] || LOCALE_COUNTRY[language] || language).toUpperCase();
|
|
151
|
+
return {
|
|
152
|
+
'appium:language': language,
|
|
153
|
+
'appium:locale': country,
|
|
154
|
+
'appium:noReset': false,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const localeCaps = resolveLocaleCaps();
|
|
158
|
+
|
|
159
|
+
export const config: WebdriverIO.Config = {
|
|
160
|
+
runner: 'local',
|
|
161
|
+
tsConfigPath: './tsconfig.json',
|
|
162
|
+
|
|
163
|
+
specs: mobileSpecs,
|
|
164
|
+
// SUNGEN_MAX_INSTANCES=2 lets a MOBILE_PLATFORM=both run execute the Android and iOS capability
|
|
165
|
+
// in PARALLEL (separate devices; uiautomator2/XCUITest do not share ports; the reporter writes
|
|
166
|
+
// per-platform files so results cannot collide). Default stays 1 — serial is the safe choice on
|
|
167
|
+
// a laptop driving an emulator + a simulator at once.
|
|
168
|
+
maxInstances: Number(process.env.SUNGEN_MAX_INSTANCES || 1),
|
|
169
|
+
|
|
170
|
+
// Global auto-wait for $/$$ matchers (toBeDisplayed, click, …). Default is 3s, too short for a
|
|
171
|
+
// heavy app's cold (re)launch — each scenario terminates+activates its app, so the first
|
|
172
|
+
// find/click must wait out the splash/first-frame. 20s keeps slow native/Flutter apps green.
|
|
173
|
+
waitforTimeout: 20000,
|
|
174
|
+
|
|
175
|
+
// Capability set(s) selected by MOBILE_PLATFORM (android | ios | both). Each cap carries its OWN
|
|
176
|
+
// `specs` (per-OS routing): the Android cap runs android + mobile specs, the iOS cap runs ios +
|
|
177
|
+
// mobile specs, so MOBILE_PLATFORM=both executes a @platform:mobile spec on each in a single run.
|
|
178
|
+
// i18n localeCaps (appium:language/locale + noReset:false) apply to both when SUNGEN_ENV is a locale.
|
|
179
|
+
capabilities: [
|
|
180
|
+
...(RUN_ANDROID
|
|
181
|
+
? [
|
|
182
|
+
{
|
|
183
|
+
platformName: 'Android',
|
|
184
|
+
'appium:automationName': 'UiAutomator2',
|
|
185
|
+
'appium:udid': process.env.ANDROID_UDID || '__ANDROID_UDID__',
|
|
186
|
+
// APP_APK installs from a file (Appium reads pkg/activity from the manifest);
|
|
187
|
+
// otherwise target an already-installed app by package + activity.
|
|
188
|
+
...(APP_APK
|
|
189
|
+
? { 'appium:app': APP_APK }
|
|
190
|
+
: {
|
|
191
|
+
'appium:appPackage': APP_PACKAGE,
|
|
192
|
+
// Omit when unset → UiAutomator2 launches the package's default launcher activity.
|
|
193
|
+
...(HAS_REAL_APP_ACTIVITY ? { 'appium:appActivity': APP_ACTIVITY } : {}),
|
|
194
|
+
}),
|
|
195
|
+
'appium:noReset': true,
|
|
196
|
+
'appium:autoGrantPermissions': true,
|
|
197
|
+
'appium:newCommandTimeout': 300,
|
|
198
|
+
// i18n: when SUNGEN_ENV/SUNGEN_LOCALE is a locale code, this overrides noReset→false and
|
|
199
|
+
// adds appium:language/appium:locale so the app boots in that locale. Empty otherwise.
|
|
200
|
+
...localeCaps,
|
|
201
|
+
// Per-capability spec routing (supported by WDIO at runtime; not in the TS cap type → cast).
|
|
202
|
+
specs: androidSpecs,
|
|
203
|
+
} as any,
|
|
204
|
+
]
|
|
205
|
+
: []),
|
|
206
|
+
...(RUN_IOS
|
|
207
|
+
? [
|
|
208
|
+
{
|
|
209
|
+
platformName: 'iOS',
|
|
210
|
+
'appium:automationName': 'XCUITest',
|
|
211
|
+
'appium:deviceName': IOS_DEVICE,
|
|
212
|
+
// Omit when unknown (real device, no IOS_VERSION) → XCUITest reads it from the device by udid.
|
|
213
|
+
...(HAS_REAL_IOS_VERSION ? { 'appium:platformVersion': IOS_VERSION } : {}),
|
|
214
|
+
// target a specific simulator if given (else Appium uses the matching device/version)
|
|
215
|
+
...(IOS_UDID ? { 'appium:udid': IOS_UDID } : {}),
|
|
216
|
+
// IOS_APP installs a Simulator build (.app/.zip); otherwise attach to an installed bundleId.
|
|
217
|
+
...(IOS_APP
|
|
218
|
+
? { 'appium:app': IOS_APP }
|
|
219
|
+
: IOS_BUNDLE_ID
|
|
220
|
+
? { 'appium:bundleId': IOS_BUNDLE_ID }
|
|
221
|
+
: {}),
|
|
222
|
+
// Real-device WDA signing — emitted only when IOS_TEAM_ID is set (Simulator: omitted → unchanged).
|
|
223
|
+
...(IOS_TEAM_ID
|
|
224
|
+
? {
|
|
225
|
+
'appium:xcodeOrgId': IOS_TEAM_ID,
|
|
226
|
+
'appium:xcodeSigningId': IOS_SIGNING_ID,
|
|
227
|
+
// Pass -allowProvisioningUpdates -allowProvisioningDeviceRegistration to xcodebuild so it
|
|
228
|
+
// auto-creates/refreshes the WDA profile + registers the device (needed for automatic
|
|
229
|
+
// signing on a real device; without it WDA build fails fast with "xcodebuild code 65").
|
|
230
|
+
'appium:allowProvisioningDeviceRegistration': true,
|
|
231
|
+
...(IOS_WDA_BUNDLE_ID ? { 'appium:updatedWDABundleId': IOS_WDA_BUNDLE_ID } : {}),
|
|
232
|
+
}
|
|
233
|
+
: {}),
|
|
234
|
+
'appium:noReset': true,
|
|
235
|
+
'appium:newCommandTimeout': 300,
|
|
236
|
+
...localeCaps,
|
|
237
|
+
specs: iosSpecs,
|
|
238
|
+
} as any,
|
|
239
|
+
]
|
|
240
|
+
: []),
|
|
241
|
+
],
|
|
242
|
+
|
|
243
|
+
logLevel: 'warn',
|
|
244
|
+
framework: 'mocha',
|
|
245
|
+
// 'spec' for console + PwShapeReporter for a Playwright-shaped JSON the delivery/dashboard reuse.
|
|
246
|
+
reporters: ['spec', [PwShapeReporter, {}]],
|
|
247
|
+
|
|
248
|
+
// Auto-start a local Appium server on :4723 (base path '/')
|
|
249
|
+
services: ['appium'],
|
|
250
|
+
port: 4723,
|
|
251
|
+
path: '/',
|
|
252
|
+
|
|
253
|
+
mochaOpts: {
|
|
254
|
+
ui: 'bdd',
|
|
255
|
+
timeout: 120000,
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// iOS + locale: XCUITest's `noReset:false` does NOT actually clear the app's data container
|
|
259
|
+
// (verified live 2026-06-11) — a Flutter app that persisted its language on a previous launch keeps
|
|
260
|
+
// it and ignores the new device locale, so the i18n run asserts the wrong language. Wipe the app
|
|
261
|
+
// data via simctl BEFORE the session so first-launch locale detection re-runs. Android needs no
|
|
262
|
+
// hook (its noReset:false reset works natively).
|
|
263
|
+
beforeSession: async (_config, capabilities) => {
|
|
264
|
+
if (Object.keys(localeCaps).length === 0) return; // not a locale run
|
|
265
|
+
const caps = capabilities as Record<string, unknown>;
|
|
266
|
+
if (String(caps['platformName'] || '').toLowerCase() !== 'ios') return;
|
|
267
|
+
const { execSync } = await import('node:child_process');
|
|
268
|
+
const fsm = await import('node:fs');
|
|
269
|
+
const udid = (caps['appium:udid'] as string) || 'booted';
|
|
270
|
+
// Wipe the session-default app AND every per-feature dual-id bundle the worker's specs declare
|
|
271
|
+
// (__IOS_BUNDLE__ markers) — a multi-app iOS locale run must reset each app, not just the first.
|
|
272
|
+
const bundleIds = new Set<string>();
|
|
273
|
+
if (typeof caps['appium:bundleId'] === 'string') bundleIds.add(caps['appium:bundleId'] as string);
|
|
274
|
+
for (const spec of specs || []) {
|
|
275
|
+
try {
|
|
276
|
+
const src = fsm.readFileSync(String(spec).replace('file://', ''), 'utf-8');
|
|
277
|
+
const m = /__IOS_BUNDLE__ = '([^']+)'/.exec(src);
|
|
278
|
+
if (m) bundleIds.add(m[1]);
|
|
279
|
+
} catch { /* unreadable spec — skip */ }
|
|
280
|
+
}
|
|
281
|
+
for (const bundleId of bundleIds) {
|
|
282
|
+
try { execSync(`xcrun simctl terminate ${udid} ${bundleId}`, { stdio: 'ignore' }); } catch { /* not running */ }
|
|
283
|
+
try {
|
|
284
|
+
const dataDir = execSync(`xcrun simctl get_app_container ${udid} ${bundleId} data`).toString().trim();
|
|
285
|
+
if (dataDir) execSync(`rm -rf "${dataDir}/Library" "${dataDir}/Documents"`);
|
|
286
|
+
console.log(`[sungen] iOS locale run: wiped app data for ${bundleId} (first-launch locale re-detect)`);
|
|
287
|
+
} catch { /* app not installed yet */ }
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
// Per-scenario app reset lives in each generated spec's `beforeEach` (terminate+activate the app
|
|
292
|
+
// from that feature's `Path:`). One run can therefore host screens from different apps — each spec
|
|
293
|
+
// launches its own — so there's no single-app reset hook here. The capabilities above only bootstrap
|
|
294
|
+
// the session (default app / device); the real app per scenario comes from the spec.
|
|
295
|
+
};
|
|
@@ -15,6 +15,11 @@ export const VALID_SELECTOR_TYPES = [
|
|
|
15
15
|
'upload',
|
|
16
16
|
'frame',
|
|
17
17
|
'table',
|
|
18
|
+
// === Mobile (Appium) strategies — resolved by the appium adapter (MOB-3) ===
|
|
19
|
+
'accessibility-id', // cross-platform — Android content-desc / iOS accessibilityIdentifier
|
|
20
|
+
'xpath', // cross-platform, last resort
|
|
21
|
+
'android-uiautomator', // Android only — UiSelector expressions
|
|
22
|
+
'ios-predicate', // iOS only — NSPredicate strings
|
|
18
23
|
] as const;
|
|
19
24
|
|
|
20
25
|
export type SelectorType = (typeof VALID_SELECTOR_TYPES)[number];
|