From 3b2db5a1348ae9f5f3a6b7cf596274deb3f3fa0e Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Wed, 22 Jul 2026 11:32:56 -0400 Subject: [PATCH 1/6] Add Appium-based integration test tier and Avalonia headless UI test tier - Add test/DemaConsulting.SysML2Workbench.UiTests: Avalonia.Headless + xUnit headless UI tests exercising view/viewmodel behavior without a real window, runnable on all OSes with no special setup. - Add test/DemaConsulting.SysML2Workbench.IntegrationTests: Appium.WebDriver based end-to-end tests driving the compiled Desktop app through the OS accessibility tree, following the Avalonia Appium testing docs. AppFixture branches by OS: Windows via NovaWindows driver (implemented and exercised), macOS (Mac2) and Linux (AT-SPI) paths are structurally present but intentionally unimplemented/skipped pending future CI provisioning. - Add AutomationProperties.AutomationId to key interactive controls (menu items, dock control, About dialog OK button, workspace panel tree/buttons, predefined views list) so Appium tests can reliably locate elements. - Update .github/workflows/build.yaml: filter existing cross-platform test job(s) to Category!=Integration, add new windows-latest job that builds/publishes the Desktop app, installs Appium + appium-novawindows-driver, runs the Appium server, and runs the IntegrationTests project. Apply the same filter in build.ps1. - Add both new projects to SysML2Workbench.slnx. - Update docs/design/introduction.md and add docs/design/ots/appium.md, docs/verification/ots/appium.md, docs/reqstream/ots/appium.yaml, docs/sysml2/model/ots.sysml entry, requirements.yaml include, .cspell.yaml terms, and README.md to describe the new three/four-tier test strategy and its Windows-only CI automation scope. - Update .reviewmark.yaml with a new OTS-Appium review-set and extend the MainWindowShell/WorkspacePanel review-sets to cover the new UiTests files. --- .cspell.yaml | 8 ++ .github/workflows/build.yaml | 122 ++++++++++++++++++ .reviewmark.yaml | 11 ++ README.md | 16 +++ SysML2Workbench.slnx | 2 + build.ps1 | 6 +- docs/design/introduction.md | 48 ++++++- docs/design/ots/appium.md | 53 ++++++++ docs/reqstream/ots/appium.yaml | 20 +++ docs/sysml2/model/ots.sysml | 7 + docs/verification/ots/appium.md | 36 ++++++ requirements.yaml | 1 + .../AppShellSubsystem/AboutDialogView.axaml | 2 +- .../AppShellSubsystem/MainWindowView.axaml | 20 +-- .../PredefinedViewsToolView.axaml | 3 +- .../WorkspacePanelToolView.axaml | 9 +- .../AppFixture.cs | 122 ++++++++++++++++++ .../AppFixtureCollection.cs | 11 ++ ...ng.SysML2Workbench.IntegrationTests.csproj | 22 ++++ .../GlobalUsings.cs | 1 + .../MainWindowShellIntegrationTests.cs | 90 +++++++++++++ .../SkippableOnNonWindowsFactAttribute.cs | 33 +++++ .../MainWindowShellUiTests.cs | 91 +++++++++++++ .../WorkspacePanelUiTests.cs | 100 ++++++++++++++ ...aConsulting.SysML2Workbench.UiTests.csproj | 21 +++ .../GlobalUsings.cs | 1 + .../TestAppBuilder.cs | 29 +++++ 27 files changed, 865 insertions(+), 20 deletions(-) create mode 100644 docs/design/ots/appium.md create mode 100644 docs/reqstream/ots/appium.yaml create mode 100644 docs/verification/ots/appium.md create mode 100644 test/DemaConsulting.SysML2Workbench.IntegrationTests/AppFixture.cs create mode 100644 test/DemaConsulting.SysML2Workbench.IntegrationTests/AppFixtureCollection.cs create mode 100644 test/DemaConsulting.SysML2Workbench.IntegrationTests/DemaConsulting.SysML2Workbench.IntegrationTests.csproj create mode 100644 test/DemaConsulting.SysML2Workbench.IntegrationTests/GlobalUsings.cs create mode 100644 test/DemaConsulting.SysML2Workbench.IntegrationTests/MainWindowShellIntegrationTests.cs create mode 100644 test/DemaConsulting.SysML2Workbench.IntegrationTests/SkippableOnNonWindowsFactAttribute.cs create mode 100644 test/DemaConsulting.SysML2Workbench.UiTests/AppShellSubsystem/MainWindowShellUiTests.cs create mode 100644 test/DemaConsulting.SysML2Workbench.UiTests/AppShellSubsystem/WorkspacePanelUiTests.cs create mode 100644 test/DemaConsulting.SysML2Workbench.UiTests/DemaConsulting.SysML2Workbench.UiTests.csproj create mode 100644 test/DemaConsulting.SysML2Workbench.UiTests/GlobalUsings.cs create mode 100644 test/DemaConsulting.SysML2Workbench.UiTests/TestAppBuilder.cs diff --git a/.cspell.yaml b/.cspell.yaml index 7b340c9..52e8cf2 100644 --- a/.cspell.yaml +++ b/.cspell.yaml @@ -81,6 +81,14 @@ words: - xshd - avaloniaedit - avares + - Appium + - appium + - NovaWindows + - WinAppDriver + - WebDriver + - webdriver + - novawindows + - atspi ignorePaths: - '**/.git/**' - '**/node_modules/**' diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2d83545..70f4e2c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -180,6 +180,9 @@ jobs: --property:Version=${{ inputs.version }} - name: Test + # IntegrationTests' Appium-driven tests are excluded here (Category!=Integration) because no Appium + # server is running in this cross-platform matrix job; they run for real only in the dedicated + # appium-windows-integration-tests job below, on windows-latest, where an Appium server is started. run: > dotnet test --no-build @@ -188,6 +191,7 @@ jobs: --collect "XPlat Code Coverage;Format=opencover" --logger "trx;LogFilePrefix=${{ matrix.os }}" --results-directory artifacts + --filter "Category!=Integration" - name: End Sonar Scanner env: @@ -347,6 +351,124 @@ jobs: name: package-msi path: package/*.msi + # Builds and publishes the Desktop application, then drives it end-to-end through a locally + # started Appium server and its NovaWindows driver (the maintained successor to the deprecated + # WinAppDriver), exercising test/DemaConsulting.SysML2Workbench.IntegrationTests' real Windows-path + # tests. This is intentionally windows-latest-only for now: Avalonia's AutomationPeer also exposes + # controls to macOS's NSAccessibility (Appium's Mac2 driver) and Linux's AT-SPI2 (X11 backend only; + # Wayland is unconfirmed), and test/DemaConsulting.SysML2Workbench.IntegrationTests/AppFixture.cs + # already contains structurally correct OS-branching code for both, but neither has a provisioned + # CI runner/driver install yet - see .agent-logs/planning-appium-integration-tests-7f3a1c2e.md for + # the scope decision. This job is independent of (does not `need`) the build job above, so it does + # not block or duplicate that job's cross-platform packaging; it publishes its own copy of the + # Desktop app instead of depending on build's artifact, keeping its job graph simple and + # self-contained in the same style as the rest of this workflow. + appium-windows-integration-tests: + name: Appium Windows Integration Tests + needs: quality-checks + runs-on: windows-latest + permissions: + contents: read + + steps: + # === INSTALL DEPENDENCIES === + # This section installs all required dependencies and tools for the Appium/NovaWindows session. + # Downstream projects: Add any additional dependency installations here. + + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Setup dotnet + uses: actions/setup-dotnet@v6 + with: + dotnet-version: 9.x + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: 24.x + + - name: Install Appium and the NovaWindows driver + run: | + npm install -g appium + appium driver install --source=npm appium-novawindows-driver + + # === BUILD AND PUBLISH THE DESKTOP APPLICATION === + # This section builds the solution and publishes the self-contained Desktop executable that the + # Appium session below launches. + # Downstream projects: Add any additional build or publish steps here. + + - name: Restore Dependencies + run: > + dotnet restore + + - name: Build + run: > + dotnet build + --no-restore + --configuration Release + --property:Version=${{ inputs.version }} + + - name: Publish self-contained build (win-x64) + run: > + dotnet publish + src/DemaConsulting.SysML2Workbench.Desktop/DemaConsulting.SysML2Workbench.Desktop.csproj + --configuration Release + --runtime win-x64 + --self-contained true + --property:Version=${{ inputs.version }} + --property:PublishSingleFile=true + --output publish/win-x64 + + # === START APPIUM AND RUN THE INTEGRATION TESTS === + # This section starts a local Appium server, waits for it to be ready, then runs the + # IntegrationTests project against the published Desktop application. + # Downstream projects: Add any additional Appium setup or test steps here. + + - name: Start Appium server + shell: pwsh + run: | + Start-Process -FilePath "appium" -ArgumentList "--base-path / --allow-insecure chromedriver_autodownload" -WindowStyle Hidden + $ready = $false + for ($i = 0; $i -lt 30; $i++) { + try { + $response = Invoke-WebRequest -Uri "http://127.0.0.1:4723/status" -UseBasicParsing -TimeoutSec 2 + if ($response.StatusCode -eq 200) { + $ready = $true + break + } + } catch { + Start-Sleep -Seconds 2 + } + } + if (-not $ready) { + throw "Appium server did not become ready within the expected time." + } + + - name: Run Appium IntegrationTests + env: + SYSML2WORKBENCH_APP_PATH: ${{ github.workspace }}\publish\win-x64\DemaConsulting.SysML2Workbench.Desktop.exe + run: > + dotnet test + test/DemaConsulting.SysML2Workbench.IntegrationTests/DemaConsulting.SysML2Workbench.IntegrationTests.csproj + --configuration Release + --property:Version=${{ inputs.version }} + --logger "trx;LogFilePrefix=appium-windows" + --results-directory artifacts + + # === UPLOAD ARTIFACTS === + # This section uploads the Appium test results for use by downstream jobs. + # Downstream projects: Add any additional artifact uploads here. + + - name: Upload Appium test results + if: always() + uses: actions/upload-artifact@v7 + with: + name: artifacts-appium-windows-integration-tests + path: artifacts/ + # Runs CodeQL security and quality analysis, gathering results to include # in the code quality report. codeql: diff --git a/.reviewmark.yaml b/.reviewmark.yaml index 7b55e23..e6c8581 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -310,6 +310,9 @@ reviews: - src/**/AppShellSubsystem/SourceTextDocumentView.axaml.cs - test/**/AppShellSubsystem/MainWindowShellTests.cs - test/**/AppShellSubsystem/SourceTextDocumentViewModelTests.cs + - test/**/AppShellSubsystem/MainWindowShellUiTests.cs + - test/DemaConsulting.SysML2Workbench.UiTests/GlobalUsings.cs + - test/DemaConsulting.SysML2Workbench.UiTests/TestAppBuilder.cs - id: SysML2Workbench-AppShellSubsystem-WorkspacePanel title: Review that SysML2Workbench AppShellSubsystem WorkspacePanel Implementation is Correct @@ -326,6 +329,7 @@ reviews: - src/**/AppShellSubsystem/WorkspacePanelToolView.axaml - src/**/AppShellSubsystem/WorkspacePanelToolView.axaml.cs - test/**/AppShellSubsystem/WorkspacePanelToolViewModelTests.cs + - test/**/AppShellSubsystem/WorkspacePanelUiTests.cs - id: SysML2Workbench-AppShellSubsystem-AboutDialog title: Review that SysML2Workbench AppShellSubsystem AboutDialog Implementation is Correct @@ -462,3 +466,10 @@ reviews: - docs/design/ots/avaloniaedit.md - docs/verification/ots/avaloniaedit.md - test/OtsSoftwareTests/AvaloniaEditTests.cs + - id: OTS-Appium + title: Review that Appium Provides Required Functionality + paths: + - docs/reqstream/ots/appium.yaml + - docs/design/ots/appium.md + - docs/verification/ots/appium.md + - test/DemaConsulting.SysML2Workbench.IntegrationTests/** diff --git a/README.md b/README.md index b4dd9fc..bbab849 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,12 @@ building a custom view. (Windows/Linux/macOS entry point). - `test/DemaConsulting.SysML2Workbench.Tests/` - unit and subsystem-level tests mirroring `src/`. +- `test/DemaConsulting.SysML2Workbench.UiTests/` - headless, in-process + Avalonia UI tests (view/view-model interaction, no real window). +- `test/DemaConsulting.SysML2Workbench.IntegrationTests/` - Appium-driven + end-to-end tests against the compiled Desktop application (Windows-only + in CI today; requires a running Appium server - see "Building and + Testing" below). - `test/OtsSoftwareTests/` - integration tests for the off-the-shelf (OTS) dependencies (SysML2Tools, Rendering, Avalonia, xUnit). - `docs/` - requirements (`docs/reqstream/`), design (`docs/design/`), @@ -56,3 +62,13 @@ pwsh ./build.ps1 # restore, build, and run all tests pwsh ./fix.ps1 # auto-fix formatting pwsh ./lint.ps1 # lint and compliance checks ``` + +`build.ps1` and CI's cross-platform build job both run `dotnet test --filter +"Category!=Integration"`, so `test/DemaConsulting.SysML2Workbench.IntegrationTests`' +Appium-driven tests are excluded from the default local/CI test run. That +tier only runs for real in CI's dedicated `appium-windows-integration-tests` +job (`windows-latest`), which publishes the Desktop application, starts a +local Appium server with the NovaWindows driver, and runs +`dotnet test test/DemaConsulting.SysML2Workbench.IntegrationTests/...` +against it. Running it locally requires a published Desktop build, a +running Appium server, and the NovaWindows driver installed. diff --git a/SysML2Workbench.slnx b/SysML2Workbench.slnx index 931d50a..f7208bb 100644 --- a/SysML2Workbench.slnx +++ b/SysML2Workbench.slnx @@ -5,6 +5,8 @@ + + diff --git a/build.ps1 b/build.ps1 index e47e93c..0c76b85 100644 --- a/build.ps1 +++ b/build.ps1 @@ -14,7 +14,11 @@ dotnet build --no-restore --configuration Release if ($LASTEXITCODE -ne 0) { $buildError = $true } Write-Host "Running tests..." -dotnet test --no-build --configuration Release --logger trx --results-directory artifacts/tests +# IntegrationTests' Appium-driven tests are excluded (Category!=Integration) because this script does +# not start an Appium server; that tier only runs in CI's dedicated appium-windows-integration-tests +# job (.github/workflows/build.yaml), which does. See docs/design/introduction.md for the full +# three-(plus-OTS)-tier test strategy. +dotnet test --no-build --configuration Release --logger trx --results-directory artifacts/tests --filter "Category!=Integration" if ($LASTEXITCODE -ne 0) { $buildError = $true } # [PROJECT-SPECIFIC] Add additional build steps here (e.g., packaging, publishing). diff --git a/docs/design/introduction.md b/docs/design/introduction.md index 0d82f6e..2b91ce7 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -33,11 +33,16 @@ OTS items: - **Avalonia**: integration and usage design (UI framework). - **AvaloniaEdit**: integration and usage design (read-only syntax-highlighted text editor control). - **xUnit**: integration and usage design (test framework). +- **Appium**: integration and usage design (end-to-end desktop UI automation + driver for the compiled application, Windows-only in CI today). Out of scope: no Shared Packages exist in this repository. Design documents -are not produced for test projects or build pipeline CI configuration, and -the internal design of OTS items is excluded — only their integration and -usage within SysML2Workbench is documented. +are not produced for test projects or build pipeline CI configuration (this +means no per-project design doc for `test/DemaConsulting.SysML2Workbench.Tests`, +`UiTests`, `IntegrationTests`, or `OtsSoftwareTests` themselves - the test +*strategy* they implement is still described below), and the internal design +of OTS items is excluded — only their integration and usage within +SysML2Workbench is documented. ## Software Structure @@ -81,6 +86,40 @@ thin bootstrap/entry-point project with no independent design of its own. - **QueryDialog** (Unit) — modal query dialog (Browse + Element Query tabs) - Desktop (platform head / entry point project; not a separately documented unit) +## Test Strategy + +The repository runs four distinct test tiers, each with a different scope and +dependency boundary: + +- **`test/DemaConsulting.SysML2Workbench.Tests`** — unit and subsystem-level + xUnit v3 tests mirroring `src/`, with no UI framework dependency. +- **`test/DemaConsulting.SysML2Workbench.UiTests`** — headless, in-process + Avalonia tests (`Avalonia.Headless.XUnit`) exercising this repository's own + view/view-model interaction logic (menu command wiring, dialog open/close, + panel state) without a visible window. +- **`test/DemaConsulting.SysML2Workbench.IntegrationTests`** — Appium-driven, + black-box, system-level tests that launch the real, compiled + `DemaConsulting.SysML2Workbench.Desktop` executable and drive it through + its actual accessibility tree, the same way a user would. This tier has no + `ProjectReference` to the local UI project (see `docs/design/ots/appium.md`). +- **`test/OtsSoftwareTests`** — a sibling, not a duplicate, of the above: it + qualifies the OTS dependencies themselves (Avalonia, Dock, AvaloniaEdit, + SysML2Tools, Rendering) against their own OTS requirements, using the same + headless-Avalonia mechanism as `UiTests` but for a different purpose. + +Only the Windows/NovaWindows path of `IntegrationTests` runs automatically in +CI today (`.github/workflows/build.yaml`'s `appium-windows-integration-tests` +job, `windows-latest`). Avalonia 12.1.0 also exposes controls to macOS's +NSAccessibility (Appium's Mac2 driver) and Linux's AT-SPI2 (X11 backend only; +Wayland is unconfirmed), and `AppFixture`'s OS-branching code for both is +structurally present and correct, but neither has a provisioned CI runner or +driver install yet - see `docs/design/ots/appium.md` for the integration +pattern and `.agent-logs/planning-appium-integration-tests-7f3a1c2e.md` for +the scope decision. Every other `dotnet test` invocation in this repository +(`build.ps1` and the cross-platform `build` job) excludes `IntegrationTests`' +tests carrying the `Integration` trait via `--filter "Category!=Integration"`, so adding +`IntegrationTests` to `SysML2Workbench.slnx` does not break those runs. + ## Folder Layout - **src/** - source files and projects @@ -88,6 +127,9 @@ thin bootstrap/entry-point project with no independent design of its own. - **DemaConsulting.SysML2Workbench.Desktop/** - desktop platform head (Windows/Linux/macOS entry point) - **test/** - test projects - **DemaConsulting.SysML2Workbench.Tests/** - unit and subsystem-level tests mirroring `src/` + - **DemaConsulting.SysML2Workbench.UiTests/** - headless, in-process Avalonia UI tests + - **DemaConsulting.SysML2Workbench.IntegrationTests/** - Appium-driven end-to-end tests against the compiled Desktop application + - **OtsSoftwareTests/** - integration tests qualifying the OTS dependencies themselves ## Companion Artifact Structure diff --git a/docs/design/ots/appium.md b/docs/design/ots/appium.md new file mode 100644 index 0000000..e3a176c --- /dev/null +++ b/docs/design/ots/appium.md @@ -0,0 +1,53 @@ +## Appium + +SysML2Workbench uses Appium's WebDriver client, together with Appium's +NovaWindows driver, to drive the compiled desktop application end-to-end +through its real accessibility tree as a system-level UI automation test tier. + +### Purpose + +Appium was chosen because it exercises the actual compiled +`DemaConsulting.SysML2Workbench.Desktop` application in a real window, driven +the same way a user would interact with it, complementing the in-process +`test/DemaConsulting.SysML2Workbench.UiTests` headless tier and the +`test/DemaConsulting.SysML2Workbench.Tests` unit/subsystem tier. Avalonia +12.1.0's `AutomationPeer` exposes controls to UIA (Windows), NSAccessibility +(macOS, via Appium's Mac2 driver), and AT-SPI2 (Linux, via Avalonia's X11 +backend only - Wayland support is unconfirmed), so Appium can, in principle, +drive the same application on all three desktop platforms through a common +`AutomationProperties.AutomationId`-based control lookup. + +### Features Used + +- **`Appium.WebDriver`'s `WindowsDriver`** — connects to a local Appium server + running the NovaWindows driver (the maintained successor to the deprecated + WinAppDriver) and launches the published Desktop executable as the driven + application. +- **`AutomationProperties.AutomationId`** — added to `MainWindowView.axaml`'s + menu items and dock control, and to the interactive controls of the About + dialog, Workspace panel, and Predefined Views panel, giving + `MobileBy.AccessibilityId` lookups a stable, Appium-reliable target + independent of `Name`/`x:Name`. +- **`MobileBy.Name`/`MobileBy.AccessibilityId`** — locate top-level menus and + automation-id-tagged controls in the real accessibility tree. + +### Integration Pattern + +`test/DemaConsulting.SysML2Workbench.IntegrationTests` has no `ProjectReference` +to the local UI project: it drives the compiled application externally as a +black-box system-level tier, per `testing-principles.md`'s hierarchy-boundary +rule. `AppFixture` follows Avalonia's documented Appium `AppFixture` pattern, +branching by `OperatingSystem.IsWindows()`/`IsMacOS()`/`IsLinux()`. Only the +Windows/NovaWindows branch is fully implemented and exercised by real tests +today; the macOS/Mac2 and Linux/AT-SPI2 branches are structurally correct +(matching the same shape) but intentionally throw rather than attempt an +session with no driver provisioned, since no macOS or Linux CI runner installs the +corresponding Appium driver yet. `.github/workflows/build.yaml`'s +`appium-windows-integration-tests` job is the only CI job that runs this +tier: it publishes the Desktop application, installs Appium and the +NovaWindows driver via npm, starts the Appium server, and runs +`dotnet test` against `IntegrationTests`. Every other `dotnet test` invocation +in this repository (the cross-platform `build` job's `Test` step and +`build.ps1`) excludes this tier with `--filter "Category!=Integration"`, +since `IntegrationTests`' tests carry `[Trait("Category", "Integration")]` +and require a running Appium server that those invocations do not start. diff --git a/docs/reqstream/ots/appium.yaml b/docs/reqstream/ots/appium.yaml new file mode 100644 index 0000000..1694b84 --- /dev/null +++ b/docs/reqstream/ots/appium.yaml @@ -0,0 +1,20 @@ +--- +sections: + - title: 'OTS Software Requirements' + sections: + - title: 'Appium Requirements' + requirements: + - id: 'Appium-DriveDesktopApplicationEndToEnd' + title: 'The SysML2Workbench repository shall use Appium to drive the compiled Desktop application end-to-end through its real accessibility tree on Windows.' + justification: | + A system-level UI automation tier is needed that exercises the actual compiled application in a real window, complementing the headless and unit test tiers, and Windows is the only platform with a provisioned CI Appium driver today. + tests: + - 'DesktopApp_Launch_ShowsMainWindowWithExpectedTitle' + + - id: 'Appium-LocateControlsByAutomationId' + title: 'The SysML2Workbench repository shall expose interactive controls to Appium via AutomationProperties.AutomationId for reliable, name-independent lookup.' + justification: | + Appium's accessibility-tree-based lookups need a stable identifier that does not depend on a control''s displayed Name/x:Name, so tests remain reliable as UI text changes. + tests: + - 'DesktopApp_FileMenu_AddFileSourceMenuItem_IsDiscoverableAndClickable' + - 'DesktopApp_HelpMenu_AboutMenuItem_OpensAndClosesAboutDialog' diff --git a/docs/sysml2/model/ots.sysml b/docs/sysml2/model/ots.sysml index e6dfdd2..2cf6b99 100644 --- a/docs/sysml2/model/ots.sysml +++ b/docs/sysml2/model/ots.sysml @@ -49,5 +49,12 @@ package SysML2WorkbenchArchitecture { comment verificationRef /* Verification: docs/verification/ots/avaloniaedit.md */ comment reqRef /* Requirements: docs/reqstream/ots/avaloniaedit.yaml */ } + part def Appium { + doc /* Appium.WebDriver NuGet dependency, together with Appium's NovaWindows driver, used to drive the compiled Desktop application end-to-end through its real accessibility tree from test/DemaConsulting.SysML2Workbench.IntegrationTests. */ + + comment designRef /* Design: docs/design/ots/appium.md */ + comment verificationRef /* Verification: docs/verification/ots/appium.md */ + comment reqRef /* Requirements: docs/reqstream/ots/appium.yaml */ + } } } diff --git a/docs/verification/ots/appium.md b/docs/verification/ots/appium.md new file mode 100644 index 0000000..946da6c --- /dev/null +++ b/docs/verification/ots/appium.md @@ -0,0 +1,36 @@ +## Appium + +### Verification Approach + +Integration tests in `test/DemaConsulting.SysML2Workbench.IntegrationTests/MainWindowShellIntegrationTests.cs` +qualify the Windows/NovaWindows Appium session by launching the real, +published `DemaConsulting.SysML2Workbench.Desktop` executable through +`AppFixture` and driving it through its actual accessibility tree, rather +than a mocked or headless UI harness, because the end-to-end platform +integration itself is what this tier is qualifying. These tests only run for +real in `.github/workflows/build.yaml`'s `appium-windows-integration-tests` +job, where an Appium server and the NovaWindows driver are actually running; +elsewhere they are excluded via `--filter "Category!=Integration"` and, on +non-Windows platforms, individually reported as skipped by +`SkippableOnNonWindowsFactAttribute` rather than failing for lack of a +provisioned session. + +### Test Scenarios + +**DesktopApp_Launch_ShowsMainWindowWithExpectedTitle**: Confirms the Appium +session's `Title` reports "SysML2Workbench" immediately after launch, proving +the session is genuinely driving the compiled application's real main +window rather than a stub. + +**DesktopApp_FileMenu_AddFileSourceMenuItem_IsDiscoverableAndClickable**: +Opens the File menu (`MobileBy.Name("File")`) and locates the "Open File..." +item by its `AddFileSourceMenuItem` automation id +(`MobileBy.AccessibilityId`), proving Avalonia's UIA automation peer exposes +the `AutomationProperties.AutomationId` values added to `MainWindowView.axaml` +through the real accessibility tree that Appium's NovaWindows driver reads. + +**DesktopApp_HelpMenu_AboutMenuItem_OpensAndClosesAboutDialog**: Opens the +Help menu, clicks "About" (`AboutMenuItem`), confirms the modal About +dialog's `AboutDialogOkButton` becomes visible, then dismisses it - proving +a full menu-click-to-modal-dialog round trip works end-to-end through the +real windowed application. diff --git a/requirements.yaml b/requirements.yaml index 5936723..12c37ce 100644 --- a/requirements.yaml +++ b/requirements.yaml @@ -33,3 +33,4 @@ includes: - docs/reqstream/ots/avalonia.yaml - docs/reqstream/ots/xunit.yaml - docs/reqstream/ots/avaloniaedit.yaml + - docs/reqstream/ots/appium.yaml diff --git a/src/DemaConsulting.SysML2Workbench/AppShellSubsystem/AboutDialogView.axaml b/src/DemaConsulting.SysML2Workbench/AppShellSubsystem/AboutDialogView.axaml index 004e03d..1d23440 100644 --- a/src/DemaConsulting.SysML2Workbench/AppShellSubsystem/AboutDialogView.axaml +++ b/src/DemaConsulting.SysML2Workbench/AppShellSubsystem/AboutDialogView.axaml @@ -12,7 +12,7 @@ -