diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 7909f65..ec1b8f9 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -27,4 +27,4 @@ jobs: shell: powershell run: | $env:PATH = "$(pwd)\Installer\Files;" + $env:PATH - $(& dotnet test Tests; $a=$lastexitcode) | findstr x*; exit $a + $(& dotnet test Tests --filter "FullyQualifiedName!~E2ETests"; $a=$lastexitcode) | findstr x*; exit $a diff --git a/Elwig/Windows/MemberAdminWindow.xaml b/Elwig/Windows/MemberAdminWindow.xaml index 9bca74a..cc5809f 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml +++ b/Elwig/Windows/MemberAdminWindow.xaml @@ -3,6 +3,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Elwig.Windows" + AutomationProperties.AutomationId="MemberAdminWindow" Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150" Loaded="Window_Loaded"> diff --git a/Tests/E2ETests/MainWindowTest.cs b/Tests/E2ETests/MainWindowTest.cs new file mode 100644 index 0000000..7fe54c1 --- /dev/null +++ b/Tests/E2ETests/MainWindowTest.cs @@ -0,0 +1,30 @@ +namespace Tests.E2ETests { + [TestFixture] + public class MainWindowTest : TestBase { + + [OneTimeSetUp] + public void ClassSetUp() { + } + + [SetUp] + public void TestSetUp() { + Setup(); + } + + [OneTimeTearDown] + public void ClassTearDown() { + StopWinappDriver(); + } + + [TearDown] + public void TestTearDown() { + TearDown(); + } + + [Test] + public void StartApplication() { + AppSession.FindElementByName("Mitglieder").Click(); + Thread.Sleep(5000); + } + } +} diff --git a/Tests/E2ETests/MemberAdminWindowTest.cs b/Tests/E2ETests/MemberAdminWindowTest.cs new file mode 100644 index 0000000..88b233d --- /dev/null +++ b/Tests/E2ETests/MemberAdminWindowTest.cs @@ -0,0 +1,150 @@ +using OpenQA.Selenium.Appium.Windows; + +namespace Tests.E2ETests { + public class MemberAdminWindowTest : TestBase { + + public WindowsDriver Session { get; private set; } + + [OneTimeSetUp] + public void ClassSetUp() { + Setup(); + AppSession.FindElementByName("Mitglieder").Click(); + Thread.Sleep(1000); + Session = CreateWindowDriver("MemberAdminWindow"); + } + + [SetUp] + public void TestSetUp() { + } + + [OneTimeTearDown] + public void ClassTearDown() { + if (Session != null) { + Session.Close(); + Session.Quit(); + Session = null; + } + TearDown(); + StopWinappDriver(); + } + + [TearDown] + public void TestTearDown() { + Session.FindElementByAccessibilityId("SearchInput").Clear(); + Thread.Sleep(1000); + } + + [Test, Order(1)] + public void CreateMember() { + Session.FindElementByAccessibilityId("NewMemberButton").Click(); + + var mgnr = Session.FindElementByAccessibilityId("MgNrInput").Text; //TODO: Fixe MGNR verwenden + + 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"); + + Session.FindElementByAccessibilityId("AddressInput").SendKeys("Musterstraße 9"); + Session.FindElementByAccessibilityId("PlzInput").SendKeys("2120"); + ClickComboBoxByCount(Session, "OrtInput", 1); + + Session.FindElementByAccessibilityId("EmailAddress1Input").SendKeys("max.mustermann@aon.at"); + Session.FindElementByAccessibilityId("EmailAddress2Input").SendKeys("erika.mustermann@aon.at"); + + ClickComboBoxByCount(Session, "PhoneNr1TypeInput", 1); + Session.FindElementByAccessibilityId("PhoneNr1Input").SendKeys("+43 1234 5678"); + + ClickComboBoxByCount(Session, "PhoneNr2TypeInput", 2); + Session.FindElementByAccessibilityId("PhoneNr2Input").SendKeys("+43 123 45678901"); + + Session.FindElementByAccessibilityId("IbanInput").SendKeys("AT611904300234573201"); + Session.FindElementByAccessibilityId("BicInput").SendKeys("RLNWATWWWDF"); + + Session.FindElementByAccessibilityId("UstIdNrInput").SendKeys("ATU66192906"); //TODO: Testdaten? + Session.FindElementByAccessibilityId("LfbisNrInput").SendKeys("1251074"); //TODO: Testdaten? + + Session.FindElementByAccessibilityId("BuchführendInput").Click(); + Session.FindElementByAccessibilityId("OrganicInput").Click(); + + Session.FindElementByAccessibilityId("BillingNameInput").SendKeys("Mustermann KG"); + Session.FindElementByAccessibilityId("BillingAddressInput").SendKeys("Betriebsstraße 1"); + Session.FindElementByAccessibilityId("BillingPlzInput").SendKeys("2120"); + ClickComboBoxByCount(Session, "BillingOrtInput", 2); + + Session.FindElementByAccessibilityId("BusinessSharesInput").SendKeys("10"); + ClickComboBoxByText(Session, "BranchInput", "Matzen"); + ClickComboBoxByCount(Session, "DefaultKgInput", 3); + + Session.FindElementByAccessibilityId("VollLieferantInput").Click(); + Session.FindElementByAccessibilityId("FunkionärInput").Click(); + + Session.FindElementByAccessibilityId("CommentInput").SendKeys("Die lieben Mustermänner und Musterfrauen!"); + Session.FindElementByAccessibilityId("ContactEmailInput").Click(); + + Session.FindElementByAccessibilityId("SaveButton").Click(); + + Session.FindElementByAccessibilityId("SearchInput").SendKeys($"{mgnr} Max Mustermann"); + + var memberListow = Session.FindElementByAccessibilityId("MemberList").FindElementByClassName("DataGridRow"); + + Assert.That(memberListow, Is.Not.Null); + 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); + }); + } + + [Test, Order(2)] + public void EditMember() { + Session.FindElementByAccessibilityId("SearchInput").SendKeys("10003 Max Mustermann"); + var memberList = Session.FindElementByAccessibilityId("MemberList"); + Assert.That(memberList, Is.Not.Null); + + var memberListRows = memberList.FindElementsByClassName("DataGridRow"); + Assert.That(memberListRows, Has.Count.EqualTo(1)); + + Session.FindElementByAccessibilityId("EditMemberButton").Click(); + + var businessSharesInput = Session.FindElementByAccessibilityId("BusinessSharesInput"); + Assert.That(businessSharesInput, Is.Not.Null); + + var businessShares = int.Parse(businessSharesInput.Text); + businessSharesInput.Clear(); + businessSharesInput.SendKeys($"{businessShares + 5}"); + + Session.FindElementByAccessibilityId("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"); + 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.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(); + + memberListRows = memberList.FindElementsByClassName("DataGridRow"); + Assert.That(memberListRows, Has.Count.EqualTo(0)); + } + + + } +} diff --git a/Tests/E2ETests/TestBase.cs b/Tests/E2ETests/TestBase.cs new file mode 100644 index 0000000..5259ed2 --- /dev/null +++ b/Tests/E2ETests/TestBase.cs @@ -0,0 +1,110 @@ +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/Tests.csproj b/Tests/Tests.csproj index 741cdca..6861d4f 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -20,6 +20,7 @@ +