From 9d99d57a9bdb3eb58c5b79c60fa82585764fb800 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Thu, 23 Jul 2026 01:52:30 -0400 Subject: [PATCH] Add Appium smoke tests for six untested top-level menu items Extend MainWindowShellIntegrationTests with low-risk discoverability/enabled coverage for menu items that already carry AutomationProperties.AutomationId but had no Appium test yet: - File > AddFolderSourceMenuItem - View > WorkspacePanelMenuItem - View > PredefinedViewsMenuItem - View > DiagnosticsMenuItem - View > ViewBuilderDialogMenuItem - Query > QueryDialogMenuItem Each test opens the parent menu, asserts the item is displayed and enabled, then closes the menu via Escape without clicking - clicking would toggle dock panels or open dialogs with no automation-id-based close path, which would leave the shared AppFixture session in an inconsistent state between tests. Extracted a private AssertMenuItemIsDiscoverableAndEnabled helper and refactored the existing AddFileSourceMenuItem test to use it. Updated docs/reqstream/ots/appium.yaml and docs/verification/ots/appium.md to keep the Appium-LocateControlsByAutomationId requirement's test list and verification narrative in sync with the six new tests. Validated: dotnet build (0 errors); build.ps1 -IntegrationTest (9/9 passing against a live NovaWindows Appium session); build.ps1 -Test (283 passing). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/reqstream/ots/appium.yaml | 6 ++ docs/verification/ots/appium.md | 14 +++ .../MainWindowShellIntegrationTests.cs | 94 +++++++++++++++++-- 3 files changed, 107 insertions(+), 7 deletions(-) diff --git a/docs/reqstream/ots/appium.yaml b/docs/reqstream/ots/appium.yaml index 336a782..46b959d 100644 --- a/docs/reqstream/ots/appium.yaml +++ b/docs/reqstream/ots/appium.yaml @@ -17,4 +17,10 @@ sections: 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_IsDiscoverableAndEnabled' + - 'DesktopApp_FileMenu_AddFolderSourceMenuItem_IsDiscoverableAndEnabled' + - 'DesktopApp_ViewMenu_WorkspacePanelMenuItem_IsDiscoverableAndEnabled' + - 'DesktopApp_ViewMenu_PredefinedViewsMenuItem_IsDiscoverableAndEnabled' + - 'DesktopApp_ViewMenu_DiagnosticsMenuItem_IsDiscoverableAndEnabled' + - 'DesktopApp_ViewMenu_ViewBuilderDialogMenuItem_IsDiscoverableAndEnabled' + - 'DesktopApp_QueryMenu_QueryDialogMenuItem_IsDiscoverableAndEnabled' - 'DesktopApp_HelpMenu_AboutMenuItem_OpensAndClosesAboutDialog' diff --git a/docs/verification/ots/appium.md b/docs/verification/ots/appium.md index 6bd493f..473f723 100644 --- a/docs/verification/ots/appium.md +++ b/docs/verification/ots/appium.md @@ -32,6 +32,20 @@ through the real accessibility tree that Appium's NovaWindows driver reads. The item is not actually clicked, since doing so would open the OS-native "Open File" dialog, which lives outside Avalonia's own accessibility tree. +**DesktopApp_FileMenu_AddFolderSourceMenuItem_IsDiscoverableAndEnabled**, +**DesktopApp_ViewMenu_WorkspacePanelMenuItem_IsDiscoverableAndEnabled**, +**DesktopApp_ViewMenu_PredefinedViewsMenuItem_IsDiscoverableAndEnabled**, +**DesktopApp_ViewMenu_DiagnosticsMenuItem_IsDiscoverableAndEnabled**, +**DesktopApp_ViewMenu_ViewBuilderDialogMenuItem_IsDiscoverableAndEnabled**, +and **DesktopApp_QueryMenu_QueryDialogMenuItem_IsDiscoverableAndEnabled**: +Each opens its respective top-level menu (`File`/`View`/`Query`) and locates +one child menu item by automation id, asserting it is both displayed and +enabled, then closes the menu via Escape without clicking the item. These +extend automation-id coverage breadth-first across every subsystem's +top-level entry point (workspace panel, predefined views, diagnostics, +custom view builder, query dialog) without needing to click through to a +dialog or native OS surface that this tier cannot yet reliably tear down. + **DesktopApp_HelpMenu_AboutMenuItem_OpensAndClosesAboutDialog**: Opens the Help menu, clicks "About" (`AboutMenuItem`), confirms the modal About dialog's `AboutDialogOkButton` becomes visible, then dismisses it - proving diff --git a/test/DemaConsulting.SysML2Workbench.IntegrationTests/MainWindowShellIntegrationTests.cs b/test/DemaConsulting.SysML2Workbench.IntegrationTests/MainWindowShellIntegrationTests.cs index 791afc2..894335f 100644 --- a/test/DemaConsulting.SysML2Workbench.IntegrationTests/MainWindowShellIntegrationTests.cs +++ b/test/DemaConsulting.SysML2Workbench.IntegrationTests/MainWindowShellIntegrationTests.cs @@ -53,20 +53,100 @@ public void DesktopApp_Launch_ShowsMainWindowWithExpectedTitle() /// [Fact] public void DesktopApp_FileMenu_AddFileSourceMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("File", "AddFileSourceMenuItem"); + } + + /// + /// Validates that the File menu's "Open Folder..." item, found by the AddFolderSourceMenuItem + /// automation id, is discoverable and enabled. Not clicked for the same reason as + /// : it opens the + /// OS-native "Open Folder" dialog. + /// + [Fact] + public void DesktopApp_FileMenu_AddFolderSourceMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("File", "AddFolderSourceMenuItem"); + } + + /// + /// Validates that the View menu's "Workspace" panel-toggle item, found by the + /// WorkspacePanelMenuItem automation id, is discoverable and enabled. Not clicked, since toggling + /// the docked panel closed would leave the shared session in a different + /// layout state for whichever test runs next. + /// + [Fact] + public void DesktopApp_ViewMenu_WorkspacePanelMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("View", "WorkspacePanelMenuItem"); + } + + /// + /// Validates that the View menu's "Predefined Views" panel-toggle item, found by the + /// PredefinedViewsMenuItem automation id, is discoverable and enabled. + /// + [Fact] + public void DesktopApp_ViewMenu_PredefinedViewsMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("View", "PredefinedViewsMenuItem"); + } + + /// + /// Validates that the View menu's "Diagnostics" panel-toggle item, found by the + /// DiagnosticsMenuItem automation id, is discoverable and enabled. + /// + [Fact] + public void DesktopApp_ViewMenu_DiagnosticsMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("View", "DiagnosticsMenuItem"); + } + + /// + /// Validates that the View menu's "Custom View Builder..." item, found by the + /// ViewBuilderDialogMenuItem automation id, is discoverable and enabled. Not clicked, since the + /// opened dialog's controls do not yet carry automation ids that would let this fixture close it + /// deterministically. + /// + [Fact] + public void DesktopApp_ViewMenu_ViewBuilderDialogMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("View", "ViewBuilderDialogMenuItem"); + } + + /// + /// Validates that the Query menu's "Run Query..." item, found by the QueryDialogMenuItem + /// automation id, is discoverable and enabled. Not clicked, for the same reason as + /// . + /// + [Fact] + public void DesktopApp_QueryMenu_QueryDialogMenuItem_IsDiscoverableAndEnabled() + { + AssertMenuItemIsDiscoverableAndEnabled("Query", "QueryDialogMenuItem"); + } + + /// + /// Opens the named top-level menu, locates the child item by automation id, asserts it is displayed and + /// enabled, then closes the menu via Escape without clicking the item itself - proving the item is + /// reachable through the real accessibility tree without triggering whatever side effect (dialog, panel + /// toggle) clicking it would cause. + /// + /// The top-level menu's display name (e.g. "File", "View", "Query"). + /// The child menu item's AutomationProperties.AutomationId value. + private void AssertMenuItemIsDiscoverableAndEnabled(string topLevelMenuName, string automationId) { // Arrange - var fileMenu = _session.FindElement(MobileBy.Name("File")); - fileMenu.Click(); + var topLevelMenu = _session.FindElement(MobileBy.Name(topLevelMenuName)); + topLevelMenu.Click(); // Act - var addFileMenuItem = _session.FindElement(MobileBy.AccessibilityId("AddFileSourceMenuItem")); + var menuItem = _session.FindElement(MobileBy.AccessibilityId(automationId)); // Assert - Assert.True(addFileMenuItem.Displayed); - Assert.True(addFileMenuItem.Enabled); + Assert.True(menuItem.Displayed); + Assert.True(menuItem.Enabled); - // Close the menu without picking a file so this test leaves no dialog open behind it. - addFileMenuItem.SendKeys(OpenQA.Selenium.Keys.Escape); + // Close the menu without picking the item so this test leaves no side effect behind it. + menuItem.SendKeys(OpenQA.Selenium.Keys.Escape); } ///