From 2b5dd053387ccb8e4dac067b52bb5a84f39cfadc Mon Sep 17 00:00:00 2001 From: jbe2277 Date: Sun, 18 Aug 2024 20:13:37 +0200 Subject: [PATCH] UITest/InfoMan: first draft of ShowContactsTest; extend App to support Automation Ids for dynamic menus --- .../BookLibrary.Test/Tests/AddressBookTest.cs | 1 - .../Tests/AddressBookTest.cs | 20 ++++++++++++ .../Tests/GeneralTest.cs | 4 +-- .../Views/ContactLayoutView.cs | 11 +++++++ .../Views/ContactListView.cs | 9 ++++++ .../Views/ContactView.cs | 8 +++++ .../Views/ShellWindow.cs | 24 ++++++++++++-- .../Controllers/ModuleController.cs | 6 ++-- .../Views/ContactLayoutView.xaml | 2 +- .../Views/ContactListView.xaml | 4 +-- .../Views/ContactView.xaml | 2 +- .../Controllers/ModuleController.cs | 16 +++++----- .../Applications/INavigationNode.cs | 3 ++ .../Applications/INavigationService.cs | 3 +- .../Applications/ToolBarCommand.cs | 3 +- .../GlobalSuppressions.cs | 2 +- .../Services/MockNavigationNode.cs | 4 ++- .../Services/MockNavigationService.cs | 4 +-- .../Services/NavigationServiceTest.cs | 23 +++++++------ .../Services/ShellServiceTest.cs | 4 +-- .../ViewModels/ShellViewModelTest.cs | 4 +-- .../Services/NavigationNode.cs | 12 ++++--- .../Services/NavigationService.cs | 4 +-- .../Views/ShellWindow.xaml | 32 +++++++++---------- .../Views/ShellWindow.xaml.cs | 2 ++ 25 files changed, 145 insertions(+), 62 deletions(-) create mode 100644 src/Samples.UITest/InformationManager.Test/Tests/AddressBookTest.cs create mode 100644 src/Samples.UITest/InformationManager.Test/Views/ContactLayoutView.cs create mode 100644 src/Samples.UITest/InformationManager.Test/Views/ContactListView.cs create mode 100644 src/Samples.UITest/InformationManager.Test/Views/ContactView.cs diff --git a/src/Samples.UITest/BookLibrary.Test/Tests/AddressBookTest.cs b/src/Samples.UITest/BookLibrary.Test/Tests/AddressBookTest.cs index 7f27df26..6a4779d8 100644 --- a/src/Samples.UITest/BookLibrary.Test/Tests/AddressBookTest.cs +++ b/src/Samples.UITest/BookLibrary.Test/Tests/AddressBookTest.cs @@ -3,7 +3,6 @@ using Xunit.Abstractions; using Xunit; using UITest.SystemViews; -using FlaUI.Core.Input; namespace UITest.BookLibrary.Tests; diff --git a/src/Samples.UITest/InformationManager.Test/Tests/AddressBookTest.cs b/src/Samples.UITest/InformationManager.Test/Tests/AddressBookTest.cs new file mode 100644 index 00000000..a97e1eba --- /dev/null +++ b/src/Samples.UITest/InformationManager.Test/Tests/AddressBookTest.cs @@ -0,0 +1,20 @@ +using Xunit.Abstractions; +using Xunit; + +namespace UITest.InformationManager.Tests; + +public class AddressBookTest(ITestOutputHelper log) : UITest(log) +{ + [Fact] + public void ShowContactsTest() => Run(() => + { + Launch(); + var window = GetShellWindow(); + window.RootTreeItem.ContactsNode.Click(); + + var contactListView = window.ContactLayoutView.ContactListView; + Assert.Equal(5, contactListView.ContactList.Items.Length); + + window.ExitCommand.Click(); + }); +} diff --git a/src/Samples.UITest/InformationManager.Test/Tests/GeneralTest.cs b/src/Samples.UITest/InformationManager.Test/Tests/GeneralTest.cs index 36e5cc51..5b7db1f3 100644 --- a/src/Samples.UITest/InformationManager.Test/Tests/GeneralTest.cs +++ b/src/Samples.UITest/InformationManager.Test/Tests/GeneralTest.cs @@ -13,7 +13,7 @@ public void AboutTest() => Run(() => { Launch(); var window = GetShellWindow(); - window.AboutButton.Click(); + window.AboutCommand.Click(); var messageBox = window.FirstModalWindow().As(); Assert.Equal("Waf Information Manager", messageBox.Title); @@ -22,6 +22,6 @@ public void AboutTest() => Run(() => Capture.Screen().ToFile(GetScreenshotFile("About")); messageBox.Buttons[0].Click(); - window.ExitButton.Click(); + window.ExitCommand.Click(); }); } diff --git a/src/Samples.UITest/InformationManager.Test/Views/ContactLayoutView.cs b/src/Samples.UITest/InformationManager.Test/Views/ContactLayoutView.cs new file mode 100644 index 00000000..2c706c4c --- /dev/null +++ b/src/Samples.UITest/InformationManager.Test/Views/ContactLayoutView.cs @@ -0,0 +1,11 @@ +using FlaUI.Core.AutomationElements; +using FlaUI.Core; + +namespace UITest.InformationManager.Views; + +public class ContactLayoutView(FrameworkAutomationElementBase element) : AutomationElement(element) +{ + public ContactListView ContactListView => this.Find("ContactListView").As(); + + public ContactView ContactView => this.Find("ContactView").As(); +} diff --git a/src/Samples.UITest/InformationManager.Test/Views/ContactListView.cs b/src/Samples.UITest/InformationManager.Test/Views/ContactListView.cs new file mode 100644 index 00000000..779c60b0 --- /dev/null +++ b/src/Samples.UITest/InformationManager.Test/Views/ContactListView.cs @@ -0,0 +1,9 @@ +using FlaUI.Core.AutomationElements; +using FlaUI.Core; + +namespace UITest.InformationManager.Views; + +public class ContactListView(FrameworkAutomationElementBase element) : AutomationElement(element) +{ + public ListBox ContactList => this.Find("ContactList").AsListBox(); +} diff --git a/src/Samples.UITest/InformationManager.Test/Views/ContactView.cs b/src/Samples.UITest/InformationManager.Test/Views/ContactView.cs new file mode 100644 index 00000000..65b3f9e0 --- /dev/null +++ b/src/Samples.UITest/InformationManager.Test/Views/ContactView.cs @@ -0,0 +1,8 @@ +using FlaUI.Core.AutomationElements; +using FlaUI.Core; + +namespace UITest.InformationManager.Views; + +public class ContactView(FrameworkAutomationElementBase element) : AutomationElement(element) +{ +} diff --git a/src/Samples.UITest/InformationManager.Test/Views/ShellWindow.cs b/src/Samples.UITest/InformationManager.Test/Views/ShellWindow.cs index b0c76754..0fe2c916 100644 --- a/src/Samples.UITest/InformationManager.Test/Views/ShellWindow.cs +++ b/src/Samples.UITest/InformationManager.Test/Views/ShellWindow.cs @@ -5,7 +5,27 @@ namespace UITest.InformationManager.Views; public class ShellWindow(FrameworkAutomationElementBase element) : Window(element) { - public Button AboutButton => this.Find("AboutButton").AsButton(); + public Button NewEmailCommand => this.Find("NewEmailCommand").AsButton(); - public Button ExitButton => this.Find("ExitButton").AsButton(); + public Button DeleteEmailCommand => this.Find("DeleteEmailCommand").AsButton(); + + public Button EmailAccountsCommand => this.Find("EmailAccountsCommand").AsButton(); + + public Button NewContactCommand => this.Find("NewContactCommand").AsButton(); + + public Button DeleteCommand => this.Find("DeleteCommand").AsButton(); + + public Button AboutCommand => this.Find("AboutCommand").AsButton(); + + public Button ExitCommand => this.Find("ExitCommand").AsButton(); + + + public NavigationRootTreeItem RootTreeItem => this.Find("RootTreeItem").As(); + + public ContactLayoutView ContactLayoutView => this.Find("ContactLayoutView").As(); } + +public class NavigationRootTreeItem(FrameworkAutomationElementBase element) : TreeItem(element) +{ + public TreeItem ContactsNode => this.Find("ContactsNode").AsTreeItem(); +} \ No newline at end of file diff --git a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Applications/Controllers/ModuleController.cs b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Applications/Controllers/ModuleController.cs index 10215cde..1fefef3e 100644 --- a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Applications/Controllers/ModuleController.cs +++ b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Applications/Controllers/ModuleController.cs @@ -49,7 +49,7 @@ public void Initialize() } else Root = (AddressBookRoot)serializer.Value.ReadObject(stream)!; } - navigationService.AddNavigationNode("Contacts", ShowAddressBook, CloseAddressBook, 2, 1); + navigationService.AddNavigationNode("ContactsNode", "Contacts", ShowAddressBook, CloseAddressBook, 2, 1); } public void Run() { } @@ -78,8 +78,8 @@ private void ShowAddressBook() activeContactController.Initialize(); activeContactController.Run(); - var uiNewContactCommand = new ToolBarCommand(activeContactController.NewContactCommand, "_New contact", "Creates a new contact."); - var uiDeleteCommand = new ToolBarCommand(activeContactController.DeleteContactCommand, "_Delete", "Deletes the selected contact."); + var uiNewContactCommand = new ToolBarCommand("NewContactCommand", activeContactController.NewContactCommand, "_New contact", "Creates a new contact."); + var uiDeleteCommand = new ToolBarCommand("DeleteCommand", activeContactController.DeleteContactCommand, "_Delete", "Deletes the selected contact."); shellService.AddToolBarCommands([ uiNewContactCommand, uiDeleteCommand ]); } diff --git a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactLayoutView.xaml b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactLayoutView.xaml index 3ef040b5..f21b87dd 100644 --- a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactLayoutView.xaml +++ b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactLayoutView.xaml @@ -4,7 +4,7 @@ xmlns:dd="clr-namespace:Waf.InformationManager.AddressBook.Modules.Presentation.DesignData" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="700" + mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="700" AutomationProperties.AutomationId="ContactLayoutView" d:DataContext="{d:DesignInstance dd:SampleContactLayoutViewModel, IsDesignTimeCreatable=True}"> diff --git a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactListView.xaml b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactListView.xaml index 07730ac4..a2f7f1df 100644 --- a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactListView.xaml +++ b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactListView.xaml @@ -6,7 +6,7 @@ xmlns:dd="clr-namespace:Waf.InformationManager.AddressBook.Modules.Presentation.DesignData" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - mc:Ignorable="d" d:DesignHeight="250" d:DesignWidth="500" + mc:Ignorable="d" d:DesignHeight="250" d:DesignWidth="500" AutomationProperties.AutomationId="ContactListView" d:DataContext="{d:DesignInstance dd:SampleContactListViewModel, IsDesignTimeCreatable=True}"> @@ -18,7 +18,7 @@ + ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled" AutomationProperties.AutomationId="ContactList"> diff --git a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactView.xaml b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactView.xaml index 19411911..f9220afb 100644 --- a/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactView.xaml +++ b/src/System.Waf/Samples/InformationManager/AddressBook.Modules.Presentation/Views/ContactView.xaml @@ -4,7 +4,7 @@ xmlns:dd="clr-namespace:Waf.InformationManager.AddressBook.Modules.Presentation.DesignData" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="300" + mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="300" AutomationProperties.AutomationId="ContactView" d:DataContext="{d:DesignInstance dd:SampleContactViewModel, IsDesignTimeCreatable=True}"> diff --git a/src/System.Waf/Samples/InformationManager/EmailClient.Modules.Applications/Controllers/ModuleController.cs b/src/System.Waf/Samples/InformationManager/EmailClient.Modules.Applications/Controllers/ModuleController.cs index d0ea5014..afe459c4 100644 --- a/src/System.Waf/Samples/InformationManager/EmailClient.Modules.Applications/Controllers/ModuleController.cs +++ b/src/System.Waf/Samples/InformationManager/EmailClient.Modules.Applications/Controllers/ModuleController.cs @@ -62,15 +62,15 @@ public void Initialize() } emailAccountsController.Root = Root; - var node = navigationService.AddNavigationNode("Inbox", ShowInbox, CloseCurrentView, 1, 1); + var node = navigationService.AddNavigationNode("InboxNode", "Inbox", ShowInbox, CloseCurrentView, 1, 1); itemCountSynchronizers.Add(new(node, Root.Inbox)); - node = navigationService.AddNavigationNode("Outbox", ShowOutbox, CloseCurrentView, 1, 2); + node = navigationService.AddNavigationNode("OutboxNode", "Outbox", ShowOutbox, CloseCurrentView, 1, 2); itemCountSynchronizers.Add(new(node, Root.Outbox)); - node = navigationService.AddNavigationNode("Sent", ShowSentEmails, CloseCurrentView, 1, 3); + node = navigationService.AddNavigationNode("SentNode", "Sent", ShowSentEmails, CloseCurrentView, 1, 3); itemCountSynchronizers.Add(new(node, Root.Sent)); - node = navigationService.AddNavigationNode("Drafts", ShowDrafts, CloseCurrentView, 1, 4); + node = navigationService.AddNavigationNode("DraftsNode", "Drafts", ShowDrafts, CloseCurrentView, 1, 4); itemCountSynchronizers.Add(new(node, Root.Drafts)); - node = navigationService.AddNavigationNode("Deleted", ShowDeletedEmails, CloseCurrentView, 1, 5); + node = navigationService.AddNavigationNode("DeletedNode", "Deleted", ShowDeletedEmails, CloseCurrentView, 1, 5); itemCountSynchronizers.Add(new(node, Root.Deleted)); } @@ -88,9 +88,9 @@ private void ShowEmails(EmailFolder emailFolder) activeEmailFolderController.EmailFolder = emailFolder; activeEmailFolderController.Initialize(); activeEmailFolderController.Run(); - var uiNewEmailCommand = new ToolBarCommand(newEmailCommand, "_New email", "Creates a new email."); - var uiDeleteEmailCommand = new ToolBarCommand(activeEmailFolderController.DeleteEmailCommand, "_Delete", "Deletes the selected email."); - var uiEmailAccountsCommand = new ToolBarCommand(emailAccountsController.EmailAccountsCommand, "_Email accounts", "Opens a window that shows the email accounts."); + var uiNewEmailCommand = new ToolBarCommand("NewEmailCommand", newEmailCommand, "_New email", "Creates a new email."); + var uiDeleteEmailCommand = new ToolBarCommand("DeleteEmailCommand", activeEmailFolderController.DeleteEmailCommand, "_Delete", "Deletes the selected email."); + var uiEmailAccountsCommand = new ToolBarCommand("EmailAccountsCommand", emailAccountsController.EmailAccountsCommand, "_Email accounts", "Opens a window that shows the email accounts."); shellService.AddToolBarCommands([ uiNewEmailCommand, uiDeleteEmailCommand, uiEmailAccountsCommand ]); } diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationNode.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationNode.cs index 4b251440..24e332bd 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationNode.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationNode.cs @@ -3,6 +3,9 @@ /// Represents a navigation node. public interface INavigationNode : INotifyPropertyChanged { + /// ID used for UI Automation. + string AutomationId { get; } + /// Gets the name. string Name { get; } diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationService.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationService.cs index 84717586..1808b5aa 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationService.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/INavigationService.cs @@ -4,6 +4,7 @@ public interface INavigationService { /// Adds a navigation node in the navigation view of the shell. + /// ID used for UI Automation. /// The name of the node. /// The show action which is called when the user selects the node. /// The close action which is called when the node is deselected. @@ -11,5 +12,5 @@ public interface INavigationService /// to be in the same group. The navigation list is ordered from lower to higher numbers. /// The order defines the position in the group. The navigation list is ordered from lower to higher numbers. /// The created navigation node. - INavigationNode AddNavigationNode(string name, Action showAction, Action closeAction, double group, double order); + INavigationNode AddNavigationNode(string automationId, string name, Action showAction, Action closeAction, double group, double order); } diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/ToolBarCommand.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/ToolBarCommand.cs index 14387f24..c984e7fa 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/ToolBarCommand.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/Applications/ToolBarCommand.cs @@ -3,7 +3,8 @@ namespace Waf.InformationManager.Infrastructure.Interfaces.Applications; /// Defines a tool bar command +/// ID used for UI Automation. /// The command which is invoked when the user clicks on the tool bar button. /// The text of the tool bar button. /// The tooltip of the tool bar button. -public record ToolBarCommand(ICommand Command, string Text, string? ToolTip = null); +public record ToolBarCommand(string AutomationId, ICommand Command, string Text, string? ToolTip = null); diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/GlobalSuppressions.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/GlobalSuppressions.cs index d3246707..5f282702 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/GlobalSuppressions.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Interfaces/GlobalSuppressions.cs @@ -1 +1 @@ -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "~M:Waf.InformationManager.Infrastructure.Interfaces.Applications.ToolBarCommand.#ctor(System.Windows.Input.ICommand,System.String,System.String)")] + \ No newline at end of file diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationNode.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationNode.cs index 6c9154e1..962d85c9 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationNode.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationNode.cs @@ -3,8 +3,10 @@ namespace Test.InformationManager.Infrastructure.Modules.Applications.Services; -public class MockNavigationNode(string name, Action showAction, Action closeAction, double group, double order) : Model, INavigationNode +public class MockNavigationNode(string automationId, string name, Action showAction, Action closeAction, double group, double order) : Model, INavigationNode { + public string AutomationId { get; } = automationId; + public string Name { get; } = name; public Action ShowAction { get; } = showAction; diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationService.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationService.cs index 5089139a..0d3a2cf4 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationService.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/MockNavigationService.cs @@ -10,9 +10,9 @@ public class MockNavigationService : INavigationService public IReadOnlyList NavigationNodes => navigationNodes; - public INavigationNode AddNavigationNode(string name, Action showAction, Action closeAction, double group, double order) + public INavigationNode AddNavigationNode(string automationId, string name, Action showAction, Action closeAction, double group, double order) { - var node = new MockNavigationNode(name, showAction, closeAction, group, order); + var node = new MockNavigationNode(automationId, name, showAction, closeAction, group, order); navigationNodes.Add(node); return node; } diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/NavigationServiceTest.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/NavigationServiceTest.cs index ea7b20df..4244fe75 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/NavigationServiceTest.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/NavigationServiceTest.cs @@ -11,11 +11,14 @@ public class NavigationServiceTest public void AddNavigationNodesWithWrongParameters() { var navigationService = new NavigationService(); - AssertHelper.ExpectedException(() => navigationService.AddNavigationNode(null!, null!, null!, 0, 0)); - AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("Node 1", null!, null!, 0, 0)); - AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("Node 1", () => { }, null!, 0, 0)); - AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("Node 1", () => { }, () => { }, -1, -1)); - AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("Node 1", () => { }, () => { }, 0, -1)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode(null!, null!, null!, null!, 0, 0)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("", null!, null!, null!, 0, 0)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("N1", null!, null!, null!, 0, 0)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("N1", "", null!, null!, 0, 0)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("N1", "Node 1", null!, null!, 0, 0)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("N1", "Node 1", () => { }, null!, 0, 0)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("N1", "Node 1", () => { }, () => { }, -1, -1)); + AssertHelper.ExpectedException(() => navigationService.AddNavigationNode("N1", "Node 1", () => { }, () => { }, 0, -1)); } [TestMethod] @@ -28,7 +31,7 @@ public void AddNavigationNode() bool closeActionCalled = false; void CloseAction() => closeActionCalled = true; - var node = (NavigationNode)navigationService.AddNavigationNode("Node 1", ShowAction, CloseAction, 3, 7); + var node = (NavigationNode)navigationService.AddNavigationNode("N1", "Node 1", ShowAction, CloseAction, 3, 7); Assert.AreEqual("Node 1", node.Name); Assert.AreEqual(3, node.Group); @@ -65,10 +68,10 @@ public void AddNavigationNodes() static void ShowAction() { } static void CloseAction() { } - var nodeB2 = navigationService.AddNavigationNode("Node B1", ShowAction, CloseAction, 1, 1); - var nodeA1 = navigationService.AddNavigationNode("Node A1", ShowAction, CloseAction, 0, 0); - var nodeA2 = navigationService.AddNavigationNode("Node A2", ShowAction, CloseAction, 0, 1); - var nodeB1 = navigationService.AddNavigationNode("Node B1", ShowAction, CloseAction, 1, 0); + var nodeB2 = navigationService.AddNavigationNode("B2", "Node B2", ShowAction, CloseAction, 1, 1); + var nodeA1 = navigationService.AddNavigationNode("A1", "Node A1", ShowAction, CloseAction, 0, 0); + var nodeA2 = navigationService.AddNavigationNode("A2", "Node A2", ShowAction, CloseAction, 0, 1); + var nodeB1 = navigationService.AddNavigationNode("B1", "Node B1", ShowAction, CloseAction, 1, 0); AssertHelper.SequenceEqual(new[] { nodeA1, nodeA2, nodeB1, nodeB2 }, navigationService.NavigationNodes); Assert.IsFalse(((NavigationNode)nodeA1).IsFirstItemOfNewGroup); diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/ShellServiceTest.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/ShellServiceTest.cs index dc7ffa98..9a593bb7 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/ShellServiceTest.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/Services/ShellServiceTest.cs @@ -36,8 +36,8 @@ public void ToolBarCommandsDelegation() var emptyCommand = new DelegateCommand(() => { }); var newToolBarCommands = new[] { - new ToolBarCommand(emptyCommand, "Command 1"), - new ToolBarCommand(emptyCommand, "Command 2") + new ToolBarCommand("C1", emptyCommand, "Command 1"), + new ToolBarCommand("C2", emptyCommand, "Command 2") }; Assert.IsFalse(mockShellViewModel.ToolBarCommands.Any()); diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/ViewModels/ShellViewModelTest.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/ViewModels/ShellViewModelTest.cs index 93a03457..363a1b3d 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/ViewModels/ShellViewModelTest.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications.Test/ViewModels/ShellViewModelTest.cs @@ -50,8 +50,8 @@ public void ToolBarCommandsDelegation() var emptyCommand = new DelegateCommand(() => { }); var newToolBarCommands = new[] { - new ToolBarCommand(emptyCommand, "Command 1"), - new ToolBarCommand(emptyCommand, "Command 2") + new ToolBarCommand("C1", emptyCommand, "Command 1"), + new ToolBarCommand("C2", emptyCommand, "Command 2") }; Assert.IsFalse(shellView.ToolBarCommands.Any()); diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationNode.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationNode.cs index ed607c12..007bc7fb 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationNode.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationNode.cs @@ -11,11 +11,13 @@ public class NavigationNode : Model, INavigationNode private bool isSelected; private bool isFirstItemOfNewGroup; - public NavigationNode(string name, Action showAction, Action closeAction, double group, double order) + public NavigationNode(string automationId, string name, Action showAction, Action closeAction, double group, double order) { - if (string.IsNullOrEmpty(name)) throw new ArgumentException("name must not be null or empty.", nameof(name)); - if (group < 0) throw new ArgumentException("group must be equal or greater than 0.", nameof(group)); - if (order < 0) throw new ArgumentException("order must be equal or greater than 0.", nameof(order)); + ArgumentException.ThrowIfNullOrEmpty(automationId); + ArgumentException.ThrowIfNullOrEmpty(name); + ArgumentOutOfRangeException.ThrowIfLessThan(group, 0); + ArgumentOutOfRangeException.ThrowIfLessThan(order, 0); + AutomationId = automationId; Name = name; this.showAction = showAction ?? throw new ArgumentNullException(nameof(showAction)); this.closeAction = closeAction ?? throw new ArgumentNullException(nameof(closeAction)); @@ -23,6 +25,8 @@ public NavigationNode(string name, Action showAction, Action closeAction, double Order = order; } + public string AutomationId { get; } + public string Name { get; } public double Group { get; } diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationService.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationService.cs index be17149f..9ed6f800 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationService.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Applications/Services/NavigationService.cs @@ -11,9 +11,9 @@ public class NavigationService : Model, INavigationService public IReadOnlyObservableList NavigationNodes => navigationNodes; - public INavigationNode AddNavigationNode(string name, Action showAction, Action closeAction, double group, double order) + public INavigationNode AddNavigationNode(string automationId, string name, Action showAction, Action closeAction, double group, double order) { - var navigationNode = new NavigationNode(name, showAction, closeAction, group, order); + var navigationNode = new NavigationNode(automationId, name, showAction, closeAction, group, order); // Insert the new navigation node at the right index. var sameGroup = navigationNodes.Where(x => DoubleEquals(x.Group, group, 1E-9)).ToArray(); diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml index 79ae8ece..7235203f 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml @@ -24,25 +24,25 @@ - - + + - - - - - + + Padding="5" AutomationProperties.AutomationId="RootTreeItem"> + + + diff --git a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml.cs b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml.cs index ef5bc153..603e1d11 100644 --- a/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml.cs +++ b/src/System.Waf/Samples/InformationManager/Infrastructure.Modules.Presentation/Views/ShellWindow.xaml.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Waf.Applications; using System.Windows; +using System.Windows.Automation; using System.Windows.Controls; using Waf.InformationManager.Common.Applications.Services; using Waf.InformationManager.Infrastructure.Interfaces.Applications; @@ -57,6 +58,7 @@ public void AddToolBarCommands(IReadOnlyList commands) { var accessText = new AccessText() { Text = command.Text }; var button = new Button() { Content = accessText, Command = command.Command }; + AutomationProperties.SetAutomationId(button, command.AutomationId); if (!string.IsNullOrEmpty(command.ToolTip)) button.ToolTip = command.ToolTip; toolBar.Items.Insert(index, button);