diff --git a/src/Calculator.sln b/src/Calculator.sln index 21180f40..bf9290a4 100644 --- a/src/Calculator.sln +++ b/src/Calculator.sln @@ -23,19 +23,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalculatorUITestFramework", EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU Release|ARM = Release|ARM Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.ActiveCfg = Debug|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Build.0 = Debug|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Deploy.0 = Debug|ARM @@ -48,7 +45,6 @@ Global {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x86.ActiveCfg = Debug|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x86.Build.0 = Debug|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x86.Deploy.0 = Debug|Win32 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|Any CPU.ActiveCfg = Release|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM.ActiveCfg = Release|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM.Build.0 = Release|ARM {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM.Deploy.0 = Release|ARM @@ -61,7 +57,6 @@ Global {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.ActiveCfg = Release|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Build.0 = Release|Win32 {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Deploy.0 = Release|Win32 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|Any CPU.ActiveCfg = Debug|Win32 {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.ActiveCfg = Debug|ARM {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.Build.0 = Debug|ARM {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -70,7 +65,6 @@ Global {311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.Build.0 = Debug|x64 {311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.ActiveCfg = Debug|Win32 {311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.Build.0 = Debug|Win32 - {311E866D-8B93-4609-A691-265941FEE101}.Release|Any CPU.ActiveCfg = Release|Win32 {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.ActiveCfg = Release|ARM {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.Build.0 = Release|ARM {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -79,7 +73,6 @@ Global {311E866D-8B93-4609-A691-265941FEE101}.Release|x64.Build.0 = Release|x64 {311E866D-8B93-4609-A691-265941FEE101}.Release|x86.ActiveCfg = Release|Win32 {311E866D-8B93-4609-A691-265941FEE101}.Release|x86.Build.0 = Release|Win32 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|Any CPU.ActiveCfg = Debug|Win32 {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.ActiveCfg = Debug|ARM {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.Build.0 = Debug|ARM {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -88,7 +81,6 @@ Global {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x64.Build.0 = Debug|x64 {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x86.ActiveCfg = Debug|Win32 {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x86.Build.0 = Debug|Win32 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|Any CPU.ActiveCfg = Release|Win32 {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM.ActiveCfg = Release|ARM {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM.Build.0 = Release|ARM {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -97,7 +89,6 @@ Global {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x64.Build.0 = Release|x64 {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x86.ActiveCfg = Release|Win32 {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x86.Build.0 = Release|Win32 - {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|Any CPU.ActiveCfg = Debug|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|ARM.ActiveCfg = Debug|ARM {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|ARM64.ActiveCfg = Debug|ARM64 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|x64.ActiveCfg = Debug|x64 @@ -106,7 +97,6 @@ Global {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|x86.ActiveCfg = Debug|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|x86.Build.0 = Debug|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Debug|x86.Deploy.0 = Debug|Win32 - {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|Any CPU.ActiveCfg = Release|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|ARM.ActiveCfg = Release|ARM {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|ARM64.ActiveCfg = Release|ARM64 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x64.ActiveCfg = Release|x64 @@ -115,46 +105,6 @@ Global {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.ActiveCfg = Release|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.Build.0 = Release|Win32 {D3BAED2C-4B07-4E1D-8807-9D6499450349}.Release|x86.Deploy.0 = Release|Win32 - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM.ActiveCfg = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM.Build.0 = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|ARM64.Build.0 = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x64.ActiveCfg = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x64.Build.0 = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x86.ActiveCfg = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|x86.Build.0 = Debug|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|Any CPU.Build.0 = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM.ActiveCfg = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM.Build.0 = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM64.ActiveCfg = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|ARM64.Build.0 = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x64.ActiveCfg = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x64.Build.0 = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x86.ActiveCfg = Release|Any CPU - {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|x86.Build.0 = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|ARM.ActiveCfg = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|ARM.Build.0 = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|ARM64.Build.0 = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|x64.ActiveCfg = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|x64.Build.0 = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|x86.ActiveCfg = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Debug|x86.Build.0 = Debug|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|Any CPU.Build.0 = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|ARM.ActiveCfg = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|ARM.Build.0 = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|ARM64.ActiveCfg = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|ARM64.Build.0 = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|x64.ActiveCfg = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|x64.Build.0 = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|x86.ActiveCfg = Release|Any CPU - {96454213-94AF-457D-9DF9-B14F80E7770F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/CalculatorUITestFramework/ApplicationBase.cs b/src/CalculatorUITestFramework/ApplicationBase.cs deleted file mode 100644 index 2c9e21eb..00000000 --- a/src/CalculatorUITestFramework/ApplicationBase.cs +++ /dev/null @@ -1,205 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.VisualStudio.TestTools.UnitTesting.Logging; -using OpenQA.Selenium; -using OpenQA.Selenium.Appium; -using OpenQA.Selenium.Appium.Windows; -using OpenQA.Selenium.Interactions; -using OpenQA.Selenium.Remote; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; - -namespace CalculatorUITestFramework -{ - /// - /// The ApplicationBase class handles setting up the WinAppDriver session and gives access to UI elements that are always present on the UI regardless of calculator mode. - /// - public class ApplicationBase - { - // Note: append /wd/hub to the URL if you're directing the test at Appium - private const string windowsApplicationDriverUrl = "http://127.0.0.1:4723"; - private const string calculatorAppId = "Microsoft.WindowsCalculator.Dev_8wekyb3d8bbwe!App"; - private static Process winAppDriverProcess; - public static NavigationMenu NavigationMenu = new NavigationMenu(); - public static WindowsDriver CalculatorSession { get; private set; } - public static WindowsElement Header - { - get - { - try - { - return TryFindElementByAccessibilityId("Header"); - } - catch - { - return TryFindElementByAccessibilityId("ContentPresenter"); - } - } - } - public static WindowsElement CalculatorResult => TryFindElementByAccessibilityId("CalculatorResults"); - - public ApplicationBase() - { - } - - public ApplicationBase(WindowsDriver calculatorSession) - { - CalculatorSession = calculatorSession; - } - - /// - /// Initalizes the WinAppDriver CalculatorSession, starts the session and launches the app. - /// - /// The test context passed into VSTest. - public static void ApplicationSetup(TestContext context) - { - // Launches the WinAppDriver.exe in a new Process. - winAppDriverProcess = new Process(); - winAppDriverProcess.StartInfo.FileName = @"c:\Program Files (x86)\Windows Application Driver\winappdriver.exe"; - winAppDriverProcess.Start(); - winAppDriverProcess.WaitForExit(); - - // Launch Calculator application if it is not yet launched - if (CalculatorSession == null) - { - // Create a new WinAppDriver session to bring up an instance of the Calculator application - // Note: Multiple calculator windows (instances) share the same process Id - var options = new AppiumOptions(); - options.AddAdditionalCapability("app", calculatorAppId); - options.AddAdditionalCapability("deviceName", "WindowsPC"); - CalculatorSession = new WindowsDriver(new Uri(windowsApplicationDriverUrl), options); - CalculatorSession.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); - Assert.IsNotNull(CalculatorSession); - } - } - - public static void TearDown() - { - // Close the application and delete the session - if (CalculatorSession != null) - { - CalculatorSession.Quit(); - CalculatorSession = null; - } - - // Close the WinAppDriver process. - if (winAppDriverProcess != null) - { - winAppDriverProcess.Close(); - } - } - - /// - /// Closes the Calculator app. - /// - public static void CloseApp() - { - CalculatorSession.CloseApp(); - } - - /// - /// Wraps the WindowsDriver.FindElementByAccessibilityId and adds retry logic for when the element cannot be found due to WinAppDriver losing the window. - /// If FindElementByAccessibilityId fails for a different reason log the error and return null. - /// - public static WindowsElement TryFindElementByAccessibilityId(string id) - { - try - { - return CalculatorSession.FindElementByAccessibilityId(id); - } - catch (WebDriverException ex) - { - if (ex.Message.Contains("Currently selected window has been closed")) - { - SwitchToCurrentWindowHandle(); - return CalculatorSession.FindElementByAccessibilityId(id); - } - else - { - Logger.LogMessage(String.Format("FindElementByAccessibilityId failed due to {0} at {1}", ex.Message, ex.StackTrace)); - return null; - } - } - } - - /// - /// Wraps the WindowsDriver.FindElementByClassName and adds retry logic for when the element cannot be found due to WinAppDriver losing the window. - /// If FindElementByClassName fails for a different reason log the error and return null. - /// - public static WindowsElement TryFindElementByClassName(string name) - { - try - { - return CalculatorSession.FindElementByClassName(name); - } - catch (WebDriverException ex) - { - if (ex.Message.Contains("Currently selected window has been closed")) - { - SwitchToCurrentWindowHandle(); - return CalculatorSession.FindElementByClassName(name); - } - else - { - Logger.LogMessage(String.Format("FindElementByAccessibilityId failed due to {0} at {1}", ex.Message, ex.StackTrace)); - return null; - } - } - } - - /// - /// Gets the window handles for the current CalculatorSession and switches to the first one. - /// - public static void SwitchToCurrentWindowHandle() - { - // Identify the current window handle. You can check through inspect.exe which window this is. - var currentWindowHandle = CalculatorSession.CurrentWindowHandle; - // Return all window handles associated with this process/application. - // At this point hopefully you have one to pick from. Otherwise you can - // simply iterate through them to identify the one you want. - var allWindowHandles = CalculatorSession.WindowHandles; - // Assuming you only have only one window entry in allWindowHandles and it is in fact the correct one, - // switch the session to that window as follows. You can repeat this logic with any top window with the same - // process id (any entry of allWindowHandles) - CalculatorSession.SwitchTo().Window(allWindowHandles[0]); - } - - /// - /// Sends keyboard key presses to the calculator app. - /// - /// - public static void SendKeys(string keysToSend) - { - Header.SendKeys(keysToSend); - } - } - - public static class WindowsElementExtensions - { - /// - /// Waits for an element to be displayed until the timeout is reached. - /// - /// WindowsElement in the Calculator application. - /// Timeout in ms. - public static void WaitForDisplayed(this WindowsElement element, int timeout = 2000) - { - Stopwatch timer = new Stopwatch(); - timer.Reset(); - timer.Start(); - while (timer.ElapsedMilliseconds < timeout) - { - if (element.Displayed) - { - timer.Stop(); - return; - } - Logger.LogMessage("Waiting for 10ms in WaitForDisplayed"); - Thread.Sleep(10); - } - timer.Stop(); - Assert.Fail(String.Format("{0} was not displayed in {1} ms", element, timeout)); - } - } - -} diff --git a/src/CalculatorUITestFramework/HistoryPanel.cs b/src/CalculatorUITestFramework/HistoryPanel.cs index 72474f88..bb69037e 100644 --- a/src/CalculatorUITestFramework/HistoryPanel.cs +++ b/src/CalculatorUITestFramework/HistoryPanel.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting.Logging; +using OpenQA.Selenium; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Windows; using System; @@ -11,11 +12,13 @@ using System.Threading.Tasks; namespace CalculatorUITestFramework { - public class HistoryPanel : ApplicationBase + public class HistoryPanel { - public WindowsElement HistoryLabel => TryFindElementByAccessibilityId("HistoryLabel"); - public WindowsElement HistoryListView => TryFindElementByAccessibilityId("HistoryListView"); - public WindowsElement ClearHistoryButton => TryFindElementByAccessibilityId("ClearHistory"); + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + public WindowsElement HistoryLabel => session.TryFindElementByAccessibilityId("HistoryLabel"); + public WindowsElement HistoryListView => session.TryFindElementByAccessibilityId("HistoryListView"); + public WindowsElement ClearHistoryButton => session.TryFindElementByAccessibilityId("ClearHistory"); + public WindowsElement HistoryEmptyLabel => session.TryFindElementByAccessibilityId("HistoryEmpty"); /// /// Opens the History Pane by clicking the History pivot label. @@ -42,10 +45,21 @@ namespace CalculatorUITestFramework public void ClearHistory() { OpenHistoryPanel(); - if (ClearHistoryButton != null) + + try { ClearHistoryButton.Click(); } + catch(WebDriverException ex) + { + if (ex.Message.Contains("element could not be located")) + { + Assert.IsNotNull(HistoryEmptyLabel); + return; + } + + throw; + } } } } diff --git a/src/CalculatorUITestFramework/MemoryPanel.cs b/src/CalculatorUITestFramework/MemoryPanel.cs index ee65b805..1f71eacf 100644 --- a/src/CalculatorUITestFramework/MemoryPanel.cs +++ b/src/CalculatorUITestFramework/MemoryPanel.cs @@ -10,16 +10,18 @@ using System.Threading.Tasks; namespace CalculatorUITestFramework { - public class MemoryPanel : ApplicationBase + public class MemoryPanel { - public WindowsElement MemoryClear => TryFindElementByAccessibilityId("ClearMemoryButton"); - public WindowsElement MemRecall => TryFindElementByAccessibilityId("MemRecall"); - public WindowsElement MemPlus => TryFindElementByAccessibilityId("MemPlus"); - public WindowsElement MemMinus => TryFindElementByAccessibilityId("MemMinus"); - public WindowsElement MemButton => TryFindElementByAccessibilityId("memButton"); - public WindowsElement MemoryPane => TryFindElementByAccessibilityId("MemoryPanel"); - public WindowsElement MemoryLabel => TryFindElementByAccessibilityId("MemoryLabel"); - public WindowsElement MemoryListView => TryFindElementByAccessibilityId("MemoryListView"); + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + public WindowsElement MemoryClear => session.TryFindElementByAccessibilityId("ClearMemoryButton"); + public WindowsElement MemRecall => session.TryFindElementByAccessibilityId("MemRecall"); + public WindowsElement MemPlus => session.TryFindElementByAccessibilityId("MemPlus"); + public WindowsElement MemMinus => session.TryFindElementByAccessibilityId("MemMinus"); + public WindowsElement MemButton => session.TryFindElementByAccessibilityId("memButton"); + public WindowsElement MemoryPane => session.TryFindElementByAccessibilityId("MemoryPanel"); + public WindowsElement MemoryLabel => session.TryFindElementByAccessibilityId("MemoryLabel"); + public WindowsElement MemoryListView => session.TryFindElementByAccessibilityId("MemoryListView"); + public WindowsElement MemoryPaneEmptyLabel => session.TryFindElementByAccessibilityId("MemoryPaneEmpty"); /// /// Opens the Memory Pane by clicking the Memory pivot label. diff --git a/src/CalculatorUITestFramework/NavigationMenu.cs b/src/CalculatorUITestFramework/NavigationMenu.cs index 8e7d1815..4e5d99d7 100644 --- a/src/CalculatorUITestFramework/NavigationMenu.cs +++ b/src/CalculatorUITestFramework/NavigationMenu.cs @@ -26,16 +26,18 @@ namespace CalculatorUITestFramework Pressure, Angle } - public class NavigationMenu : ApplicationBase + public class NavigationMenu { - public static WindowsElement NavigationMenuButton => TryFindElementByAccessibilityId("TogglePaneButton"); - public static WindowsElement NavigationMenuPane => TryFindElementByClassName("SplitViewPane"); + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + + public WindowsElement NavigationMenuButton => session.TryFindElementByAccessibilityId("TogglePaneButton"); + public WindowsElement NavigationMenuPane => session.TryFindElementByClassName("SplitViewPane"); /// /// Changes the mode using the navigation menu in the UI /// /// The mode to be changed to - public static void ChangeCalculatorMode(CalculatorMode mode) + public void ChangeCalculatorMode(CalculatorMode mode) { string modeAccessibilityId; switch (mode) @@ -96,10 +98,10 @@ namespace CalculatorUITestFramework break; } - + var source = session.PageSource; NavigationMenuButton.Click(); NavigationMenuPane.WaitForDisplayed(); - TryFindElementByAccessibilityId(modeAccessibilityId).Click(); + session.TryFindElementByAccessibilityId(modeAccessibilityId).Click(); } } } diff --git a/src/CalculatorUITestFramework/NumerPad.cs b/src/CalculatorUITestFramework/NumerPad.cs index 2e0ea526..7fd47f65 100644 --- a/src/CalculatorUITestFramework/NumerPad.cs +++ b/src/CalculatorUITestFramework/NumerPad.cs @@ -3,20 +3,21 @@ using OpenQA.Selenium.Appium.Windows; namespace CalculatorUITestFramework { - public class NumerPad : ApplicationBase + public class NumerPad { - public WindowsElement Num0Button => TryFindElementByAccessibilityId("num0Button"); - public WindowsElement Num1Button => TryFindElementByAccessibilityId("num1Button"); - public WindowsElement Num2Button => TryFindElementByAccessibilityId("num2Button"); - public WindowsElement Num3Button => TryFindElementByAccessibilityId("num3Button"); - public WindowsElement Num4Button => TryFindElementByAccessibilityId("num4Button"); - public WindowsElement Num5Button => TryFindElementByAccessibilityId("num5Button"); - public WindowsElement Num6Button => TryFindElementByAccessibilityId("num6Button"); - public WindowsElement Num7Button => TryFindElementByAccessibilityId("num7Button"); - public WindowsElement Num8Button => TryFindElementByAccessibilityId("num8Button"); - public WindowsElement Num9Button => TryFindElementByAccessibilityId("num9Button"); - public WindowsElement DecimalButton => TryFindElementByAccessibilityId("decimalSeparatorButton"); - public WindowsElement NegateButton => TryFindElementByAccessibilityId("negateButton"); + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + public WindowsElement Num0Button => session.TryFindElementByAccessibilityId("num0Button"); + public WindowsElement Num1Button => session.TryFindElementByAccessibilityId("num1Button"); + public WindowsElement Num2Button => session.TryFindElementByAccessibilityId("num2Button"); + public WindowsElement Num3Button => session.TryFindElementByAccessibilityId("num3Button"); + public WindowsElement Num4Button => session.TryFindElementByAccessibilityId("num4Button"); + public WindowsElement Num5Button => session.TryFindElementByAccessibilityId("num5Button"); + public WindowsElement Num6Button => session.TryFindElementByAccessibilityId("num6Button"); + public WindowsElement Num7Button => session.TryFindElementByAccessibilityId("num7Button"); + public WindowsElement Num8Button => session.TryFindElementByAccessibilityId("num8Button"); + public WindowsElement Num9Button => session.TryFindElementByAccessibilityId("num9Button"); + public WindowsElement DecimalButton => session.TryFindElementByAccessibilityId("decimalSeparatorButton"); + public WindowsElement NegateButton => session.TryFindElementByAccessibilityId("negateButton"); /// /// Translates a number into the Calculator button clicks. diff --git a/src/CalculatorUITestFramework/StandardCalculatorPage.cs b/src/CalculatorUITestFramework/StandardCalculatorPage.cs index 4e543380..508b3b44 100644 --- a/src/CalculatorUITestFramework/StandardCalculatorPage.cs +++ b/src/CalculatorUITestFramework/StandardCalculatorPage.cs @@ -12,44 +12,61 @@ namespace CalculatorUITestFramework /// /// This class contains the UI automation objects and helper methods available when the Calculator is in Standard Mode. /// - public class StandardCalculatorPage : ApplicationBase + public class StandardCalculatorPage { - public static StandardOperatorsPanel StandardOperators = new StandardOperatorsPanel(); - public static MemoryPanel MemoryPanel = new MemoryPanel(); - public static HistoryPanel HistoryPanel = new HistoryPanel(); + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + public StandardOperatorsPanel StandardOperators = new StandardOperatorsPanel(); + public MemoryPanel MemoryPanel = new MemoryPanel(); + public HistoryPanel HistoryPanel = new HistoryPanel(); + public NavigationMenu NavigationMenu = new NavigationMenu(); + public WindowsElement Header + { + get + { + try + { + return session.TryFindElementByAccessibilityId("Header"); + } + catch + { + return session.TryFindElementByAccessibilityId("ContentPresenter"); + } + } + } + public WindowsElement CalculatorResult => session.TryFindElementByAccessibilityId("CalculatorResults"); - public static void StandardCalculatorSetup(TestContext context) + public void StandardCalculatorSetup(TestContext context) { // Create session to launch a Calculator window - ApplicationSetup(context); - // Identify calculator mode by locating the header - + WinAppDriver.Instance.SetupCalculatorSession(context); // Ensure that calculator is in standard mode NavigationMenu.ChangeCalculatorMode(CalculatorMode.StandardCalculator); - var source = CalculatorSession.PageSource; Assert.IsNotNull(CalculatorResult); } + public void StandardCalculatorTearDown() + { + // Tear down Calculator session. + WinAppDriver.Instance.TearDownCalculatorSession(); + } + /// /// Clear the Calculatory display, Memory Panel and optionally the History Panel /// /// Bool specifying if the History Panel should be cleared; true by default. - public static void ClearAll(bool clearHistory = true) + public void ClearAll() { StandardOperators.ClearButton.Click(); MemoryPanel.MemoryClear.Click(); - if (clearHistory) - { - HistoryPanel.ClearHistory(); - } + HistoryPanel.ClearHistory(); } /// /// Gets the text from the display control and removes the narrator text that is not displayed in the UI. /// /// The string shown in the UI. - public static string GetCalculatorResultText() + public string GetCalculatorResultText() { return CalculatorResult.Text.Replace("Display is", string.Empty).Trim(); } diff --git a/src/CalculatorUITestFramework/StandardOperatorsPanel.cs b/src/CalculatorUITestFramework/StandardOperatorsPanel.cs index c0db5522..bc61bed2 100644 --- a/src/CalculatorUITestFramework/StandardOperatorsPanel.cs +++ b/src/CalculatorUITestFramework/StandardOperatorsPanel.cs @@ -10,23 +10,24 @@ namespace CalculatorUITestFramework /// /// UI elements and helper methods to perform common mathematical standard operations. /// - public class StandardOperatorsPanel : ApplicationBase + public class StandardOperatorsPanel { + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; public NumerPad NumberPad = new NumerPad(); - public WindowsElement PercentButton => TryFindElementByAccessibilityId("percentButton"); - public WindowsElement SquareRootButton => TryFindElementByAccessibilityId("squareRootButton"); - public WindowsElement XPower2Button => TryFindElementByAccessibilityId("xpower2Button"); - public WindowsElement XPower3Button => TryFindElementByAccessibilityId("xpower3Button"); - public WindowsElement InvertButton => TryFindElementByAccessibilityId("invertButton"); - public WindowsElement DivideButton => TryFindElementByAccessibilityId("divideButton"); - public WindowsElement MultiplyButton => TryFindElementByAccessibilityId("multiplyButton"); - public WindowsElement MinusButton => TryFindElementByAccessibilityId("minusButton"); - public WindowsElement PlusButton => TryFindElementByAccessibilityId("plusButton"); - public WindowsElement EqualButton => TryFindElementByAccessibilityId("equalButton"); - public WindowsElement ClearEntryButton => TryFindElementByAccessibilityId("clearEntryButton"); - public WindowsElement ClearButton => TryFindElementByAccessibilityId("clearButton"); - public WindowsElement BackSpaceButton => TryFindElementByAccessibilityId("backSpaceButton"); + public WindowsElement PercentButton => session.TryFindElementByAccessibilityId("percentButton"); + public WindowsElement SquareRootButton => session.TryFindElementByAccessibilityId("squareRootButton"); + public WindowsElement XPower2Button => session.TryFindElementByAccessibilityId("xpower2Button"); + public WindowsElement XPower3Button => session.TryFindElementByAccessibilityId("xpower3Button"); + public WindowsElement InvertButton => session.TryFindElementByAccessibilityId("invertButton"); + public WindowsElement DivideButton => session.TryFindElementByAccessibilityId("divideButton"); + public WindowsElement MultiplyButton => session.TryFindElementByAccessibilityId("multiplyButton"); + public WindowsElement MinusButton => session.TryFindElementByAccessibilityId("minusButton"); + public WindowsElement PlusButton => session.TryFindElementByAccessibilityId("plusButton"); + public WindowsElement EqualButton => session.TryFindElementByAccessibilityId("equalButton"); + public WindowsElement ClearEntryButton => session.TryFindElementByAccessibilityId("clearEntryButton"); + public WindowsElement ClearButton => session.TryFindElementByAccessibilityId("clearButton"); + public WindowsElement BackSpaceButton => session.TryFindElementByAccessibilityId("backSpaceButton"); /// /// Uses the Calculator UI to add a list of numbers. @@ -139,7 +140,6 @@ namespace CalculatorUITestFramework public void Cube(double number) { NumberPad.TranslateNumberToButtonClicks(number); - var source = CalculatorSession.PageSource; XPower3Button.Click(); } diff --git a/src/CalculatorUITestFramework/WinAppDriver.cs b/src/CalculatorUITestFramework/WinAppDriver.cs new file mode 100644 index 00000000..ce2dddb2 --- /dev/null +++ b/src/CalculatorUITestFramework/WinAppDriver.cs @@ -0,0 +1,65 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium; +using OpenQA.Selenium.Appium; +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CalculatorUITestFramework +{ + public sealed class WinAppDriver + { + // Note: append /wd/hub to the URL if you're directing the test at Appium + private const string windowsApplicationDriverUrl = "http://127.0.0.1:4723"; + private const string calculatorAppId = "Microsoft.WindowsCalculator.Dev_8wekyb3d8bbwe!App"; + private static WinAppDriver instance = null; + public static WinAppDriver Instance + { + get + { + if (instance == null) + { + instance = new WinAppDriver(); + } + return instance; + } + + } + + public WindowsDriver CalculatorSession { get; private set; } + + + private WinAppDriver() + { + } + + public void SetupCalculatorSession(TestContext context) + { + // Launch Calculator application if it is not yet launched + if (CalculatorSession == null) + { + // Create a new WinAppDriver session to bring up an instance of the Calculator application + // Note: Multiple calculator windows (instances) share the same process Id + var options = new AppiumOptions(); + options.AddAdditionalCapability("app", calculatorAppId); + options.AddAdditionalCapability("deviceName", "WindowsPC"); + CalculatorSession = new WindowsDriver(new Uri(windowsApplicationDriverUrl), options); + CalculatorSession.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); + Assert.IsNotNull(CalculatorSession); + } + } + + public void TearDownCalculatorSession() + { + // Close the application and delete the session + if (CalculatorSession != null) + { + CalculatorSession.Quit(); + CalculatorSession = null; + } + } + + + } +} diff --git a/src/CalculatorUITestFramework/WindowsDriverExtensions.cs b/src/CalculatorUITestFramework/WindowsDriverExtensions.cs new file mode 100644 index 00000000..77056d91 --- /dev/null +++ b/src/CalculatorUITestFramework/WindowsDriverExtensions.cs @@ -0,0 +1,72 @@ +using OpenQA.Selenium; +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CalculatorUITestFramework +{ + public static class WindowsDriverExtensions + { + /// + /// Wraps the WindowsDriver.FindElementByAccessibilityId and adds retry logic for when the element cannot be found due to WinAppDriver losing the window. + /// If FindElementByAccessibilityId fails for a different reason log the error and return null. + /// + public static WindowsElement TryFindElementByAccessibilityId(this WindowsDriver driver, string id) + { + try + { + return driver.FindElementByAccessibilityId(id); + } + catch (WebDriverException ex) + { + if (ex.Message.Contains("Currently selected window has been closed")) + { + driver.SwitchToCurrentWindowHandle(); + return driver.FindElementByAccessibilityId(id); + } + + throw; + } + } + + /// + /// Wraps the WindowsDriver.FindElementByClassName and adds retry logic for when the element cannot be found due to WinAppDriver losing the window. + /// If FindElementByClassName fails for a different reason log the error and return null. + /// + public static WindowsElement TryFindElementByClassName(this WindowsDriver driver, string name) + { + try + { + return driver.FindElementByClassName(name); + } + catch (WebDriverException ex) + { + if (ex.Message.Contains("Currently selected window has been closed")) + { + driver.SwitchToCurrentWindowHandle(); + return driver.FindElementByClassName(name); + } + + throw; + } + } + + /// + /// Gets the window handles for the current CalculatorSession and switches to the first one. + /// + public static void SwitchToCurrentWindowHandle(this WindowsDriver driver) + { + // Identify the current window handle. You can check through inspect.exe which window this is. + var currentWindowHandle = driver.CurrentWindowHandle; + // Return all window handles associated with this process/application. + // At this point hopefully you have one to pick from. Otherwise you can + // simply iterate through them to identify the one you want. + var allWindowHandles = driver.WindowHandles; + // Assuming you only have only one window entry in allWindowHandles and it is in fact the correct one, + // switch the session to that window as follows. You can repeat this logic with any top window with the same + // process id (any entry of allWindowHandles) + driver.SwitchTo().Window(allWindowHandles[0]); + } + } +} diff --git a/src/CalculatorUITestFramework/WindowsElementExtensions.cs b/src/CalculatorUITestFramework/WindowsElementExtensions.cs new file mode 100644 index 00000000..e49c9f6d --- /dev/null +++ b/src/CalculatorUITestFramework/WindowsElementExtensions.cs @@ -0,0 +1,48 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting.Logging; +using OpenQA.Selenium; +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; + +namespace CalculatorUITestFramework +{ + public static class WindowsElementExtensions + { + /// + /// Waits for an element to be displayed until the timeout is reached. + /// + /// WindowsElement in the Calculator application. + /// Timeout in ms. + public static void WaitForDisplayed(this WindowsElement element, int timeout = 2000) + { + Stopwatch timer = new Stopwatch(); + timer.Reset(); + timer.Start(); + while (timer.ElapsedMilliseconds < timeout) + { + if (element.Displayed) + { + timer.Stop(); + return; + } + Logger.LogMessage("Waiting for 10ms in WaitForDisplayed"); + Thread.Sleep(10); + } + timer.Stop(); + Assert.Fail(String.Format("{0} was not displayed in {1} ms", element, timeout)); + } + + /// + /// Sends keyboard key presses to the calculator app. + /// + /// + public static void SendKeys(this WindowsElement element, string keysToSend) + { + element.SendKeys(keysToSend); + } + } +} diff --git a/src/CalculatorUITests/StandardModeFunctionalTests.cs b/src/CalculatorUITests/StandardModeFunctionalTests.cs index 8e9fc5e7..c2b2fc01 100644 --- a/src/CalculatorUITests/StandardModeFunctionalTests.cs +++ b/src/CalculatorUITests/StandardModeFunctionalTests.cs @@ -12,7 +12,7 @@ namespace CalculatorUITests [TestClass] public class StandardModeFunctionalTests { - private StandardOperatorsPanel standardOperators => StandardCalculatorPage.StandardOperators; + private static StandardCalculatorPage page = new StandardCalculatorPage(); /// /// Initializes the WinAppDriver web driver session. @@ -21,7 +21,8 @@ namespace CalculatorUITests [ClassInitialize] public static void ClassInitialize(TestContext context) { - StandardCalculatorPage.StandardCalculatorSetup(context); + + page.StandardCalculatorSetup(context); } /// @@ -30,7 +31,7 @@ namespace CalculatorUITests [ClassCleanup] public static void ClassCleanup() { - StandardCalculatorPage.TearDown(); + page.StandardCalculatorTearDown(); } /// @@ -39,80 +40,139 @@ namespace CalculatorUITests [TestInitialize] public void TestInit() { - StandardCalculatorPage.ClearAll(false); - Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + if ("0" != page.GetCalculatorResultText()) + { + page.ClearAll(); + } } [TestCleanup] public void TestCleanup() { - StandardCalculatorPage.ClearAll(); + page.ClearAll(); } + #region Smoke Tests + [TestMethod] + public void SmokeTest_Add() + { + // Find the buttons by their names and click them in sequence to peform 1 + 7 = 8 + page.StandardOperators.Add(new List() { 3.5, 0.25 }); + Assert.AreEqual("3.75", page.GetCalculatorResultText()); + } + + [TestMethod] + public void SmokeTest_Add_KeyboardInput() + { + page.Header.SendKeys("3+3="); + Assert.AreEqual("6", page.GetCalculatorResultText()); + } + + [TestMethod] + public void SmokeTest_Subtract() + { + // Find the buttons by their names and click them in sequence to peform 1 + 7 = 8 + page.StandardOperators.Subtract(new List() { 4.3, 2.6 }); + Assert.AreEqual("1.7", page.GetCalculatorResultText()); + } + + [TestMethod] + public void SmokeTest_History() + { + page.StandardOperators.Add(new List() { -3, -2.6 }); + page.StandardOperators.Subtract(new List() { 2, 3 }); + page.StandardOperators.Multiply(new List() { 1, 3 }); + var historyItems = page.HistoryPanel.GetAllHistoryListViewItems(); + Assert.IsTrue(historyItems[0].Text.Equals("1 × 3 = 3", StringComparison.InvariantCultureIgnoreCase)); + Assert.IsTrue(historyItems[1].Text.Equals("2 Minus ( 3 = Minus (1", StringComparison.InvariantCultureIgnoreCase)); + Assert.IsTrue(historyItems[2].Text.Equals("-3 + -2.6 = Minus (5.6", StringComparison.InvariantCultureIgnoreCase)); + + } + + [TestMethod] + public void SmokeTest_Memory() + { + page.StandardOperators.Add(new List() { 3, 0 }); + page.MemoryPanel.MemButton.Click(); + page.StandardOperators.Divide(new List() { 2, 3 }); + page.MemoryPanel.MemButton.Click(); + page.StandardOperators.Multiply(new List() { 7, 9 }); + page.MemoryPanel.MemButton.Click(); + var memoryItems = page.MemoryPanel.GetAllMemoryListViewItems(); + + Assert.IsTrue(memoryItems[0].Text.Equals("63", StringComparison.InvariantCultureIgnoreCase)); + Assert.IsTrue(memoryItems[1].Text.Equals("0.6666666666666667‬", StringComparison.InvariantCultureIgnoreCase)); + Assert.IsTrue(memoryItems[2].Text.Equals("3", StringComparison.InvariantCultureIgnoreCase)); + return; + + } + + #endregion + #region Basic Arthimetic Tests [TestMethod] - public void BVT_Reciprocal() + public void Operator_Reciprocal() { - standardOperators.Reciprocal(4); - Assert.AreEqual("0.25", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.Reciprocal(4); + Assert.AreEqual("0.25", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_Squared() + public void Operator_Squared() { - standardOperators.Square(-15.5); - Assert.AreEqual("240.25", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.Square(-15.5); + Assert.AreEqual("240.25", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_SquareRoot() + public void Operator_SquareRoot() { - standardOperators.SquareRoot(144); - Assert.AreEqual("12", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.SquareRoot(144); + Assert.AreEqual("12", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_Cubed() + public void Operator_Cubed() { - standardOperators.Cube(-3); - Assert.AreEqual("-27", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.Cube(-3); + Assert.AreEqual("-27", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_Percent() + public void Operator_Percent() { - standardOperators.NumberPad.TranslateNumberToButtonClicks(600); - standardOperators.MultiplyButton.Click(); - standardOperators.NumberPad.TranslateNumberToButtonClicks(15); - standardOperators.PercentButton.Click(); - standardOperators.EqualButton.Click(); - Assert.AreEqual("90", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(600); + page.StandardOperators.MultiplyButton.Click(); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(15); + page.StandardOperators.PercentButton.Click(); + page.StandardOperators.EqualButton.Click(); + Assert.AreEqual("90", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_Delete() + public void Operator_Delete() { - standardOperators.NumberPad.TranslateNumberToButtonClicks(-12345); - standardOperators.BackSpaceButton.Click(); - Assert.AreEqual("-1,234", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(-12345); + page.StandardOperators.BackSpaceButton.Click(); + Assert.AreEqual("-1,234", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_ClearAll() + public void Operator_ClearAll() { - standardOperators.Add(new List() { 12345, 6789 }); - standardOperators.ClearButton.Click(); - Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.Add(new List() { 12345, 6789 }); + page.StandardOperators.ClearButton.Click(); + Assert.AreEqual("0", page.GetCalculatorResultText()); } [TestMethod] - public void BVT_ClearEntry() + public void Operator_ClearEntry() { - standardOperators.NumberPad.TranslateNumberToButtonClicks(-12345); - standardOperators.MinusButton.Click(); - standardOperators.NumberPad.TranslateNumberToButtonClicks(5678); - standardOperators.ClearEntryButton.Click(); - Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(-12345); + page.StandardOperators.MinusButton.Click(); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(5678); + page.StandardOperators.ClearEntryButton.Click(); + Assert.AreEqual("0", page.GetCalculatorResultText()); } #endregion @@ -120,93 +180,57 @@ namespace CalculatorUITests [TestMethod] public void KeyboardInput_Subtract() { - StandardCalculatorPage.SendKeys("70090-890987="); - Assert.AreEqual("-820,897", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("70090-890987="); + Assert.AreEqual("-820,897", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_Multiply() { - StandardCalculatorPage.SendKeys("-15*3="); - Assert.AreEqual("-45", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("-15*3="); + Assert.AreEqual("-45", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_Divide() { - StandardCalculatorPage.SendKeys("26/13="); - Assert.AreEqual("2", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("26/13="); + Assert.AreEqual("2", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_Reciprocal() { - StandardCalculatorPage.SendKeys("10r"); - Assert.AreEqual("0.1", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("10r"); + Assert.AreEqual("0.1", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_Squared() { - StandardCalculatorPage.SendKeys("3q"); - Assert.AreEqual("9", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("3q"); + Assert.AreEqual("9", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_SquareRoot() { - StandardCalculatorPage.SendKeys("100@"); - Assert.AreEqual("10", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("100@"); + Assert.AreEqual("10", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_Cubed() { - StandardCalculatorPage.SendKeys("3#"); - Assert.AreEqual("27", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("3#"); + Assert.AreEqual("27", page.GetCalculatorResultText()); } [TestMethod] public void KeyboardInput_Percent() { - StandardCalculatorPage.SendKeys("34+7%="); - Assert.AreEqual("36.38", StandardCalculatorPage.GetCalculatorResultText()); - } - - [Ignore] - [TestMethod] - public void KeyboardInput_Delete() - { - // Sending the Backspace key is not working yet. - - //StandardCalculatorPage.SendKeys("34+700"); - //Assert.AreEqual("700", StandardCalculatorPage.GetCalculatorResultText()); - //StandardCalculatorPage.SendKeys(Keys.Backspace); - //Assert.AreEqual("70", StandardCalculatorPage.GetCalculatorResultText()); - } - - [Ignore] - [TestMethod] - public void KeyboardInput_ClearAll() - { - // Sending the Escape key is not working yet. - - //StandardCalculatorPage.SendKeys("3+3="); - //Assert.AreEqual("6", StandardCalculatorPage.GetCalculatorResultText()); - //StandardCalculatorPage.SendKeys(Keys.Escape); - //Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); - } - - [Ignore] - [TestMethod] - public void KeyboardInput_ClearEntry() - { - //Sending the Delete key is not working yet. - - //StandardCalculatorPage.SendKeys("3+3"); - //Assert.AreEqual("3", StandardCalculatorPage.GetCalculatorResultText()); - //StandardCalculatorPage.SendKeys(Keys.Delete); - //Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + page.Header.SendKeys("34+7%="); + Assert.AreEqual("36.38", page.GetCalculatorResultText()); } #endregion @@ -215,54 +239,45 @@ namespace CalculatorUITests [TestMethod] public void Memory_AddTest() { - standardOperators.Divide(new List() { 12, 3 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - standardOperators.NumberPad.TranslateNumberToButtonClicks(15); - StandardCalculatorPage.MemoryPanel.MemPlus.Click(); - var memoryItems = StandardCalculatorPage.MemoryPanel.GetAllMemoryListViewItems(); + page.StandardOperators.Divide(new List() { 12, 3 }); + page.MemoryPanel.MemButton.Click(); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(15); + page.MemoryPanel.MemPlus.Click(); + var memoryItems = page.MemoryPanel.GetAllMemoryListViewItems(); Assert.IsTrue(memoryItems[0].Text.Equals("19", StringComparison.InvariantCultureIgnoreCase)); } [TestMethod] public void Memory_SubtractTest() { - standardOperators.Divide(new List() { 12, 3 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - standardOperators.NumberPad.TranslateNumberToButtonClicks(3.3); - StandardCalculatorPage.MemoryPanel.MemMinus.Click(); - var memoryItems = StandardCalculatorPage.MemoryPanel.GetAllMemoryListViewItems(); + page.StandardOperators.Divide(new List() { 12, 3 }); + page.MemoryPanel.MemButton.Click(); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(3.3); + page.MemoryPanel.MemMinus.Click(); + var memoryItems = page.MemoryPanel.GetAllMemoryListViewItems(); Assert.IsTrue(memoryItems[0].Text.Equals("0.7", StringComparison.InvariantCultureIgnoreCase)); } [TestMethod] public void Memory_RecallTest() { - standardOperators.Divide(new List() { 12, 3 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - standardOperators.NumberPad.TranslateNumberToButtonClicks(3.3); - StandardCalculatorPage.MemoryPanel.MemRecall.Click(); - var memoryItems = StandardCalculatorPage.MemoryPanel.GetAllMemoryListViewItems(); + page.StandardOperators.Divide(new List() { 12, 3 }); + page.MemoryPanel.MemButton.Click(); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(3.3); + page.MemoryPanel.MemRecall.Click(); + var memoryItems = page.MemoryPanel.GetAllMemoryListViewItems(); Assert.IsTrue(memoryItems[0].Text.Equals("4", StringComparison.InvariantCultureIgnoreCase)); } [TestMethod] public void Memory_ClearTest() { - standardOperators.Divide(new List() { 12, 3 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - standardOperators.NumberPad.TranslateNumberToButtonClicks(3.3); - StandardCalculatorPage.MemoryPanel.MemoryClear.Click(); - try - { - StandardCalculatorPage.MemoryPanel.GetAllMemoryListViewItems(); - } - catch (NullReferenceException ex) - { - if (!ex.StackTrace.Contains("MemoryPanel.GetAllMemoryListViewItems()")) - { - throw; - } - } + page.StandardOperators.Divide(new List() { 12, 3 }); + page.MemoryPanel.MemButton.Click(); + page.StandardOperators.NumberPad.TranslateNumberToButtonClicks(3.3); + page.MemoryPanel.MemoryClear.Click(); + page.MemoryPanel.OpenMemoryPanel(); + Assert.IsNotNull(page.MemoryPanel.MemoryPaneEmptyLabel); } #endregion } diff --git a/src/CalculatorUITests/StandardModeSmokeTests.cs b/src/CalculatorUITests/StandardModeSmokeTests.cs deleted file mode 100644 index 239a9dba..00000000 --- a/src/CalculatorUITests/StandardModeSmokeTests.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; -using System; -using CalculatorUITestFramework; - -namespace CalculatorUITests -{ - [TestClass] - public class StandardModeSmokeTests - { - private StandardOperatorsPanel standardOperators => StandardCalculatorPage.StandardOperators; - - [TestMethod] - public void SmokeTest_Add() - { - // Find the buttons by their names and click them in sequence to peform 1 + 7 = 8 - standardOperators.Add(new List() { 3.5, 0.25 }); - Assert.AreEqual("3.75", StandardCalculatorPage.GetCalculatorResultText()); - } - - [TestMethod] - public void SmokeTest_Add_KeyboardInput() - { - StandardCalculatorPage.SendKeys("3+3="); - Assert.AreEqual("6", StandardCalculatorPage.GetCalculatorResultText()); - } - - [TestMethod] - public void SmokeTest_Subtract() - { - // Find the buttons by their names and click them in sequence to peform 1 + 7 = 8 - standardOperators.Subtract(new List() { 4.3, 2.6 }); - Assert.AreEqual("1.7", StandardCalculatorPage.GetCalculatorResultText()); - } - - [TestMethod] - public void SmokeTest_History() - { - standardOperators.Add(new List() { -3, -2.6 }); - standardOperators.Subtract(new List() { 2, 3 }); - standardOperators.Multiply(new List() { 1, 3 }); - var historyItems = StandardCalculatorPage.HistoryPanel.GetAllHistoryListViewItems(); - Assert.IsTrue(historyItems[0].Text.Equals("1 × 3 = 3", StringComparison.InvariantCultureIgnoreCase)); - Assert.IsTrue(historyItems[1].Text.Equals("2 Minus ( 3 = Minus (1", StringComparison.InvariantCultureIgnoreCase)); - Assert.IsTrue(historyItems[2].Text.Equals("-3 + -2.6 = Minus (5.6", StringComparison.InvariantCultureIgnoreCase)); - - } - - [TestMethod] - public void SmokeTest_Memory() - { - standardOperators.Add(new List() { 3, 0 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - standardOperators.Divide(new List() { 2, 3 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - standardOperators.Multiply(new List() { 7, 9 }); - StandardCalculatorPage.MemoryPanel.MemButton.Click(); - var memoryItems = StandardCalculatorPage.MemoryPanel.GetAllMemoryListViewItems(); - - Assert.IsTrue(memoryItems[0].Text.Equals("63", StringComparison.InvariantCultureIgnoreCase)); - Assert.IsTrue(memoryItems[1].Text.Equals("0.6666666666666667‬", StringComparison.InvariantCultureIgnoreCase)); - Assert.IsTrue(memoryItems[2].Text.Equals("3", StringComparison.InvariantCultureIgnoreCase)); - return; - - } - - [ClassInitialize] - public static void ClassInitialize(TestContext context) - { - StandardCalculatorPage.StandardCalculatorSetup(context); - } - - [ClassCleanup] - public static void ClassCleanup() - { - StandardCalculatorPage.TearDown(); - } - - [TestInitialize] - public void TestInit() - { - StandardCalculatorPage.ClearAll(false); - Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); - } - - [TestCleanup] - public void TestCleanup() - { - StandardCalculatorPage.ClearAll(); - } - } -}