diff --git a/Elwig/Dialogs/DeleteMemberDialog.xaml b/Elwig/Dialogs/DeleteMemberDialog.xaml index 885f39d..adf202e 100644 --- a/Elwig/Dialogs/DeleteMemberDialog.xaml +++ b/Elwig/Dialogs/DeleteMemberDialog.xaml @@ -1,4 +1,5 @@  diff --git a/Tests/E2ETests/AppSession.cs b/Tests/E2ETests/AppSession.cs new file mode 100644 index 0000000..5bbc622 --- /dev/null +++ b/Tests/E2ETests/AppSession.cs @@ -0,0 +1,47 @@ +using OpenQA.Selenium.Appium.Windows; +using OpenQA.Selenium.Appium; + +namespace Tests.E2ETests { + public class AppSession : IDisposable { + + private const int WaitForAppLaunch = 3; + private readonly string WinAppDriverUrl; + public readonly WindowsDriver App; + public readonly WindowsDriver Desktop; + + public AppSession(string appPath, string winAppDriverUrl) { + WinAppDriverUrl = winAppDriverUrl; + var appiumOptions = new AppiumOptions(); + appiumOptions.AddAdditionalCapability("app", appPath); + appiumOptions.AddAdditionalCapability("deviceName", "WindowsPC"); + appiumOptions.AddAdditionalCapability("ms:waitForAppLaunch", WaitForAppLaunch); + App = new WindowsDriver(new Uri(WinAppDriverUrl), appiumOptions); + Assert.That(App, Is.Not.Null); + Assert.That(App.SessionId, Is.Not.Null); + App.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5); + var desktopOptions = new AppiumOptions(); + desktopOptions.AddAdditionalCapability("app", "Root"); + desktopOptions.AddAdditionalCapability("deviceName", "WindowsPC"); + Desktop = new WindowsDriver(new Uri(WinAppDriverUrl), desktopOptions); + } + + public WindowsDriver CreateWindowDriver(string windowName) { + var window = Desktop.FindElementByAccessibilityId(windowName); + var windowHandle = int.Parse(window.GetAttribute("NativeWindowHandle")).ToString("x"); // Convert to Hex + var appiumOptions = new AppiumOptions(); + appiumOptions.AddAdditionalCapability("appTopLevelWindow", windowHandle); + return new WindowsDriver(new Uri(WinAppDriverUrl), appiumOptions); + } + + public void Dispose() { + GC.SuppressFinalize(this); + App.Close(); + try { + Desktop.FindElementByName("Ja").Click(); + } catch { } + App.Dispose(); + Desktop.Close(); + Desktop.Dispose(); + } + } +} diff --git a/Tests/E2ETests/MainWindowTest.cs b/Tests/E2ETests/MainWindowTest.cs index 7fe54c1..ea0b23b 100644 --- a/Tests/E2ETests/MainWindowTest.cs +++ b/Tests/E2ETests/MainWindowTest.cs @@ -1,30 +1,50 @@ namespace Tests.E2ETests { [TestFixture] - public class MainWindowTest : TestBase { + public class MainWindowTest { + + private AppSession Session; [OneTimeSetUp] - public void ClassSetUp() { - } - - [SetUp] - public void TestSetUp() { - Setup(); + public void Setup() { + Session = new(Utils.ApplicationPath, WinAppDriver.WinAppDriverUrl); } [OneTimeTearDown] - public void ClassTearDown() { - StopWinappDriver(); - } - - [TearDown] - public void TestTearDown() { - TearDown(); + public void Teardown() { + Session.Dispose(); } [Test] - public void StartApplication() { - AppSession.FindElementByName("Mitglieder").Click(); - Thread.Sleep(5000); + public void Test_Open_MemberAdminWindow() { + Assert.DoesNotThrow(() => { + Session.App.FindElementByName("Mitglieder").Click(); + Thread.Sleep(1500); + var window = Session.CreateWindowDriver("MemberAdminWindow"); + Assert.That(window.Title, Is.EqualTo("Mitglieder - Elwig")); + window.Close(); + }); + } + + [Test] + public void Test_Open_DeliveryAdminWindow() { + Assert.DoesNotThrow(() => { + Session.App.FindElementByName("Lieferungen").Click(); + Thread.Sleep(1500); + var window = Session.CreateWindowDriver("DeliveryAdminWindow"); + Assert.That(window.Title, Is.EqualTo("Lieferungen - Elwig")); + window.Close(); + }); + } + + [Test] + public void Test_Open_BaseDataWindow() { + Assert.DoesNotThrow(() => { + Session.App.FindElementByName("Stammdaten").Click(); + Thread.Sleep(1500); + var window = Session.CreateWindowDriver("BaseDataWindow"); + Assert.That(window.Title, Is.EqualTo("Stammdaten - Elwig")); + window.Close(); + }); } } } diff --git a/Tests/E2ETests/MemberAdminWindowTest.cs b/Tests/E2ETests/MemberAdminWindowTest.cs index 88b233d..ec4494c 100644 --- a/Tests/E2ETests/MemberAdminWindowTest.cs +++ b/Tests/E2ETests/MemberAdminWindowTest.cs @@ -1,150 +1,146 @@ using OpenQA.Selenium.Appium.Windows; namespace Tests.E2ETests { - public class MemberAdminWindowTest : TestBase { + [TestFixture] + public class MemberAdminWindowTest { - public WindowsDriver Session { get; private set; } + private AppSession Session; + private WindowsDriver Window; [OneTimeSetUp] - public void ClassSetUp() { - Setup(); - AppSession.FindElementByName("Mitglieder").Click(); + public void WindowSetup() { + Session = new(Utils.ApplicationPath, WinAppDriver.WinAppDriverUrl); + Session.App.FindElementByName("Mitglieder").Click(); Thread.Sleep(1000); - Session = CreateWindowDriver("MemberAdminWindow"); - } - - [SetUp] - public void TestSetUp() { + Window = Session.CreateWindowDriver("MemberAdminWindow"); } [OneTimeTearDown] - public void ClassTearDown() { - if (Session != null) { - Session.Close(); - Session.Quit(); - Session = null; - } - TearDown(); - StopWinappDriver(); + public void WindowTeardown() { + Window.Close(); + Window.Quit(); + Session.Dispose(); } [TearDown] - public void TestTearDown() { - Session.FindElementByAccessibilityId("SearchInput").Clear(); - Thread.Sleep(1000); + public void Teardown() { + Window!.FindById("SearchInput").Clear(); + Thread.Sleep(500); } - [Test, Order(1)] - public void CreateMember() { - Session.FindElementByAccessibilityId("NewMemberButton").Click(); + [Test] + public void Test_1_CreateMember() { + Window!.FindById("NewMemberButton").Click(); - var mgnr = Session.FindElementByAccessibilityId("MgNrInput").Text; //TODO: Fixe MGNR verwenden + Window.FindById("MgNrInput").Clear(); + Window.FindById("MgNrInput").SendKeys("10003"); - Session.FindElementByAccessibilityId("GivenNameInput").SendKeys("Max"); - Session.FindElementByAccessibilityId("FamilyNameInput").SendKeys("Mustermann"); - Session.FindElementByAccessibilityId("PrefixInput").SendKeys("Ing."); - Session.FindElementByAccessibilityId("SuffixInput").SendKeys("jun."); - Session.FindElementByAccessibilityId("BirthdayInput").SendKeys("1987"); + Window.FindById("GivenNameInput").SendKeys("Max"); + Window.FindById("FamilyNameInput").SendKeys("Mustermann"); + Window.FindById("PrefixInput").SendKeys("Ing."); + Window.FindById("SuffixInput").SendKeys("jun."); + Window.FindById("BirthdayInput").SendKeys("1987"); - Session.FindElementByAccessibilityId("AddressInput").SendKeys("Musterstraße 9"); - Session.FindElementByAccessibilityId("PlzInput").SendKeys("2120"); - ClickComboBoxByCount(Session, "OrtInput", 1); + Window.FindById("AddressInput").SendKeys("Musterstraße 9"); + Window.FindById("PlzInput").SendKeys("2120"); + Window.SelectComboBoxItemByCount("OrtInput", 1); - Session.FindElementByAccessibilityId("EmailAddress1Input").SendKeys("max.mustermann@aon.at"); - Session.FindElementByAccessibilityId("EmailAddress2Input").SendKeys("erika.mustermann@aon.at"); + Window.FindById("EmailAddress1Input").SendKeys("max.mustermann@aon.at"); + Window.FindById("EmailAddress2Input").SendKeys("erika.mustermann@aon.at"); - ClickComboBoxByCount(Session, "PhoneNr1TypeInput", 1); - Session.FindElementByAccessibilityId("PhoneNr1Input").SendKeys("+43 1234 5678"); + Window.SelectComboBoxItemByCount("PhoneNr1TypeInput", 1); + Window.FindById("PhoneNr1Input").SendKeys("012345678"); - ClickComboBoxByCount(Session, "PhoneNr2TypeInput", 2); - Session.FindElementByAccessibilityId("PhoneNr2Input").SendKeys("+43 123 45678901"); + Window.SelectComboBoxItemByCount("PhoneNr2TypeInput", 2); + Window.FindById("PhoneNr2Input").SendKeys("0664123456"); - Session.FindElementByAccessibilityId("IbanInput").SendKeys("AT611904300234573201"); - Session.FindElementByAccessibilityId("BicInput").SendKeys("RLNWATWWWDF"); + Window.FindById("IbanInput").SendKeys("AT611904300234573201"); + Window.FindById("BicInput").SendKeys("RLNWATWWWDF"); - Session.FindElementByAccessibilityId("UstIdNrInput").SendKeys("ATU66192906"); //TODO: Testdaten? - Session.FindElementByAccessibilityId("LfbisNrInput").SendKeys("1251074"); //TODO: Testdaten? + Window.FindById("UstIdNrInput").SendKeys("ATU66192906"); //TODO: Testdaten? + Window.FindById("LfbisNrInput").SendKeys("1251074"); //TODO: Testdaten? - Session.FindElementByAccessibilityId("BuchführendInput").Click(); - Session.FindElementByAccessibilityId("OrganicInput").Click(); + Window.FindById("BuchführendInput").Click(); + Window.FindById("OrganicInput").Click(); - Session.FindElementByAccessibilityId("BillingNameInput").SendKeys("Mustermann KG"); - Session.FindElementByAccessibilityId("BillingAddressInput").SendKeys("Betriebsstraße 1"); - Session.FindElementByAccessibilityId("BillingPlzInput").SendKeys("2120"); - ClickComboBoxByCount(Session, "BillingOrtInput", 2); + Window.FindById("BillingNameInput").SendKeys("Mustermann KG"); + Window.FindById("BillingAddressInput").SendKeys("Betriebsstraße 1"); + Window.FindById("BillingPlzInput").SendKeys("2120"); + Window.SelectComboBoxItemByCount("BillingOrtInput", 2); - Session.FindElementByAccessibilityId("BusinessSharesInput").SendKeys("10"); - ClickComboBoxByText(Session, "BranchInput", "Matzen"); - ClickComboBoxByCount(Session, "DefaultKgInput", 3); + Window.FindById("BusinessSharesInput").SendKeys("10"); + Window.SelectComboBoxItemByText("BranchInput", "Matzen"); + Window.SelectComboBoxItemByCount("DefaultKgInput", 3); - Session.FindElementByAccessibilityId("VollLieferantInput").Click(); - Session.FindElementByAccessibilityId("FunkionärInput").Click(); + Window.FindById("VollLieferantInput").Click(); + Window.FindById("FunkionärInput").Click(); - Session.FindElementByAccessibilityId("CommentInput").SendKeys("Die lieben Mustermänner und Musterfrauen!"); - Session.FindElementByAccessibilityId("ContactEmailInput").Click(); + Window.FindById("CommentInput").SendKeys("Die lieben Mustermänner und Musterfrauen!"); + Window.FindById("ContactEmailInput").Click(); - Session.FindElementByAccessibilityId("SaveButton").Click(); + Window.FindById("SaveButton").Click(); - Session.FindElementByAccessibilityId("SearchInput").SendKeys($"{mgnr} Max Mustermann"); - - var memberListow = Session.FindElementByAccessibilityId("MemberList").FindElementByClassName("DataGridRow"); - - Assert.That(memberListow, Is.Not.Null); + Window.FindById("SearchInput").SendKeys("10003 Max Mustermann"); + Thread.Sleep(500); + var memberListRow = Window.FindById("MemberList").FindElementByClassName("DataGridRow"); Assert.Multiple(() => { - Assert.That(memberListow.FindElementByName($"{mgnr} "), Is.Not.Null); - Assert.That(memberListow.FindElementByName("Max"), Is.Not.Null); - Assert.That(memberListow.FindElementByName("Mustermann"), Is.Not.Null); + Assert.That(memberListRow, Is.Not.Null); + Assert.That(memberListRow.FindElementByName("10003 "), Is.Not.Null); + Assert.That(memberListRow.FindElementByName("Max"), Is.Not.Null); + Assert.That(memberListRow.FindElementByName("Mustermann"), Is.Not.Null); }); } - [Test, Order(2)] - public void EditMember() { - Session.FindElementByAccessibilityId("SearchInput").SendKeys("10003 Max Mustermann"); - var memberList = Session.FindElementByAccessibilityId("MemberList"); + [Test] + public void Test_2_EditMember() { + Window!.FindById("SearchInput").SendKeys("10003 Max Mustermann"); + Thread.Sleep(500); + var memberList = Window.FindById("MemberList"); Assert.That(memberList, Is.Not.Null); var memberListRows = memberList.FindElementsByClassName("DataGridRow"); Assert.That(memberListRows, Has.Count.EqualTo(1)); - Session.FindElementByAccessibilityId("EditMemberButton").Click(); + Window.FindById("EditMemberButton").Click(); - var businessSharesInput = Session.FindElementByAccessibilityId("BusinessSharesInput"); + var businessSharesInput = Window.FindById("BusinessSharesInput"); Assert.That(businessSharesInput, Is.Not.Null); var businessShares = int.Parse(businessSharesInput.Text); businessSharesInput.Clear(); businessSharesInput.SendKeys($"{businessShares + 5}"); - Session.FindElementByAccessibilityId("SaveButton").Click(); + Window.FindById("SaveButton").Click(); var newBusinessShares = int.Parse(businessSharesInput.Text); Assert.That(newBusinessShares, Is.EqualTo(businessShares + 5)); } - [Test, Order(3)] - public void DeleteMember() { - Session.FindElementByAccessibilityId("SearchInput").SendKeys("10003 Max Mustermann"); - var memberList = Session.FindElementByAccessibilityId("MemberList"); + [Test] + public void Test_3_DeleteMember() { + Window!.FindById("SearchInput").SendKeys("10003 Max Mustermann"); + Thread.Sleep(500); + var memberList = Window.FindById("MemberList"); Assert.That(memberList, Is.Not.Null); var memberListRows = memberList.FindElementsByClassName("DataGridRow"); Assert.That(memberListRows, Has.Count.EqualTo(1)); var memberListRow = memberListRows.First(); - Assert.Multiple(() => { + Assert.That(memberListRow, Is.Not.Null); Assert.That(memberListRow.FindElementByName("10003 "), Is.Not.Null); Assert.That(memberListRow.FindElementByName("Max"), Is.Not.Null); Assert.That(memberListRow.FindElementByName("Mustermann"), Is.Not.Null); }); - Session.FindElementByAccessibilityId("DeleteMemberButton").Click(); - DesktopSession.FindElementByName("OK").Click(); + Window.FindById("DeleteMemberButton").Click(); + var dialog = Session.CreateWindowDriver("DeleteMemberDialog"); + dialog.FindById("NameInput").SendKeys("10003 Ing. Max Mustermann jun."); + dialog.FindById("ConfirmButton").Click(); memberListRows = memberList.FindElementsByClassName("DataGridRow"); Assert.That(memberListRows, Has.Count.EqualTo(0)); } - - } } diff --git a/Tests/E2ETests/Setup.cs b/Tests/E2ETests/Setup.cs new file mode 100644 index 0000000..5504789 --- /dev/null +++ b/Tests/E2ETests/Setup.cs @@ -0,0 +1,17 @@ +namespace Tests.E2ETests { + [SetUpFixture] + public static class Setup { + + private static WinAppDriver? Driver; + + [OneTimeSetUp] + public static void SetupWinAppDriver() { + Driver = new(); + } + + [OneTimeTearDown] + public static void TeardownWinAppDriver() { + Driver?.Dispose(); + } + } +} diff --git a/Tests/E2ETests/TestBase.cs b/Tests/E2ETests/TestBase.cs deleted file mode 100644 index 5259ed2..0000000 --- a/Tests/E2ETests/TestBase.cs +++ /dev/null @@ -1,110 +0,0 @@ -using OpenQA.Selenium; -using OpenQA.Selenium.Appium; -using OpenQA.Selenium.Appium.Windows; -using System.Diagnostics; -using System.Windows; - -namespace Tests.E2ETests { - public class TestBase { - - protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723"; - //private const string ApplicationPath = @"..\..\Elwig\bin\Release\net8.0-windows\Elwig.exe"; - private const string ApplicationPath = @"C:\Users\tom\source\repos\elwig\Elwig\bin\Release\net8.0-windows\Elwig.exe"; - private const int WaitForAppLaunch = 3; - private const string WinAppDriverPath = @"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe"; - private static Process winAppDriverProcess; - public WindowsDriver AppSession { get; private set; } - public WindowsDriver DesktopSession { get; private set; } - - - private static void StartWinAppDriver() { - ProcessStartInfo psi = new(WinAppDriverPath) { - UseShellExecute = true, - //Verb = "runas" // run as administrator - }; - //psi.EnvironmentVariables.Add("DX.UITESTINGENABLED", "1"); - winAppDriverProcess = Process.Start(psi); - } - - public void Setup() { - //StartWinAppDriver(); - var appiumOptions = new AppiumOptions(); - appiumOptions.AddAdditionalCapability("app", ApplicationPath); - appiumOptions.AddAdditionalCapability("deviceName", "WindowsPC"); - appiumOptions.AddAdditionalCapability("ms:waitForAppLaunch", WaitForAppLaunch); - AppSession = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), appiumOptions); - Assert.That(AppSession, Is.Not.Null); - Assert.That(AppSession.SessionId, Is.Not.Null); - AppSession.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5); - AppiumOptions desktopOptions = new AppiumOptions(); - desktopOptions.AddAdditionalCapability("app", "Root"); - desktopOptions.AddAdditionalCapability("deviceName", "WindowsPC"); - DesktopSession = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), desktopOptions); - } - - public void TearDown() { - - // Close the AppSession - if (AppSession != null) { - CloseElwig(); - AppSession.Quit(); - AppSession = null; - } - // Close the DesktopSession - if (DesktopSession != null) { - DesktopSession.Close(); - DesktopSession.Quit(); - DesktopSession = null; - } - } - - private void CloseElwig() { - try { - AppSession.Close(); - string currentHandle = AppSession.CurrentWindowHandle; - - DismissOpenWindowsDialog(); - } catch { } - } - - private void DismissOpenWindowsDialog() { - try { - DesktopSession.FindElementByName("Yes").Click(); - } catch { } - } - - protected static void StopWinappDriver() { - // Stop the WinAppDriverProcess - if (winAppDriverProcess != null) { - foreach (var process in Process.GetProcessesByName("WinAppDriver")) { - process.Kill(); - } - } - } - - protected WindowsDriver CreateWindowDriver(string windowName) { - var mainWindow = DesktopSession.FindElementByAccessibilityId(windowName); - var mainWindowHandle = mainWindow.GetAttribute("NativeWindowHandle"); - mainWindowHandle = (int.Parse(mainWindowHandle)).ToString("x"); // Convert to Hex - var appiumOptions = new AppiumOptions(); - appiumOptions.AddAdditionalCapability("appTopLevelWindow", mainWindowHandle); - return new WindowsDriver(new Uri(WindowsApplicationDriverUrl), appiumOptions); - } - - protected void ClickComboBoxByCount(WindowsDriver session, string accessibilityId, int count) { - var element = session.FindElementByAccessibilityId(accessibilityId); - element.Click(); - for (int i = 0; i < count; i++) { - element.SendKeys(Keys.Down); - } - element.SendKeys(Keys.Enter); - } - - protected void ClickComboBoxByText(WindowsDriver session, string accessibilityId, string text) { - var element = session.FindElementByAccessibilityId(accessibilityId); - element.Click(); - element.SendKeys(text); - element.SendKeys(Keys.Enter); - } - } -} diff --git a/Tests/E2ETests/Utils.cs b/Tests/E2ETests/Utils.cs new file mode 100644 index 0000000..5ae127b --- /dev/null +++ b/Tests/E2ETests/Utils.cs @@ -0,0 +1,27 @@ +using OpenQA.Selenium; +using OpenQA.Selenium.Appium.Windows; + +namespace Tests.E2ETests { + public static class Utils { + + public const string ApplicationPath = @"..\..\..\..\Elwig\bin\Debug\net8.0-windows\Elwig.exe"; + + public static WindowsElement FindById(this WindowsDriver session, string accessibilityId) { + return session.FindElementByAccessibilityId(accessibilityId); + } + + public static void SelectComboBoxItemByCount(this WindowsDriver session, string accessibilityId, int count) { + var element = session.FindElementByAccessibilityId(accessibilityId); + element.Click(); + element.SendKeys(string.Concat(Enumerable.Repeat(Keys.Down, count))); + element.SendKeys(Keys.Enter); + } + + public static void SelectComboBoxItemByText(this WindowsDriver session, string accessibilityId, string text) { + var element = session.FindElementByAccessibilityId(accessibilityId); + element.Click(); + element.SendKeys(text); + element.SendKeys(Keys.Enter); + } + } +} diff --git a/Tests/E2ETests/WinAppDriver.cs b/Tests/E2ETests/WinAppDriver.cs new file mode 100644 index 0000000..9a7e57d --- /dev/null +++ b/Tests/E2ETests/WinAppDriver.cs @@ -0,0 +1,27 @@ +using System.Diagnostics; + +namespace Tests.E2ETests { + public class WinAppDriver : IDisposable { + + public const string WinAppDriverUrl = "http://127.0.0.1:4723"; + private const string WinAppDriverPath = @"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe"; + private readonly Process WinAppDriverProcess; + + public WinAppDriver() { + WinAppDriverProcess = Process.Start(new ProcessStartInfo(WinAppDriverPath) { + //UseShellExecute = true, + //Verb = "runas", // run as administrator + RedirectStandardInput = true, + EnvironmentVariables = { + // { "DX.UITESTINGENABLED", "1" }, + } + })!; + } + + public void Dispose() { + GC.SuppressFinalize(this); + WinAppDriverProcess.StandardInput.WriteLine(""); + WinAppDriverProcess.Dispose(); + } + } +}