From 890772c1a518e9eb8e370d94abfa763f76d5d804 Mon Sep 17 00:00:00 2001 From: Stephanie Anderl <46726333+sanderl@users.noreply.github.com> Date: Fri, 10 May 2019 13:43:02 -0700 Subject: [PATCH] Added CalculatorUIFramework and added standard mode tests to CaulatorUITests --- src/Calculator.sln | 38 ++- .../ApplicationBase.cs | 205 +++++++++++++ .../CalculatorUITestFramework.csproj | 14 + src/CalculatorUITestFramework/HistoryPanel.cs | 51 ++++ src/CalculatorUITestFramework/MemoryPanel.cs | 43 +++ .../NavigationMenu.cs | 105 +++++++ src/CalculatorUITestFramework/NumerPad.cs | 77 +++++ .../StandardCalculatorPage.cs | 57 ++++ .../StandardOperatorsPanel.cs | 156 ++++++++++ src/CalculatorUITests/CalculatorSession.cs | 44 --- .../CalculatorUITests.csproj | 6 +- src/CalculatorUITests/ScenarioStandard.cs | 112 -------- .../StandardModeFunctionalTests.cs | 269 ++++++++++++++++++ .../StandardModeSmokeTests.cs | 92 ++++++ 14 files changed, 1111 insertions(+), 158 deletions(-) create mode 100644 src/CalculatorUITestFramework/ApplicationBase.cs create mode 100644 src/CalculatorUITestFramework/CalculatorUITestFramework.csproj create mode 100644 src/CalculatorUITestFramework/HistoryPanel.cs create mode 100644 src/CalculatorUITestFramework/MemoryPanel.cs create mode 100644 src/CalculatorUITestFramework/NavigationMenu.cs create mode 100644 src/CalculatorUITestFramework/NumerPad.cs create mode 100644 src/CalculatorUITestFramework/StandardCalculatorPage.cs create mode 100644 src/CalculatorUITestFramework/StandardOperatorsPanel.cs delete mode 100644 src/CalculatorUITests/CalculatorSession.cs delete mode 100644 src/CalculatorUITests/ScenarioStandard.cs create mode 100644 src/CalculatorUITests/StandardModeFunctionalTests.cs create mode 100644 src/CalculatorUITests/StandardModeSmokeTests.cs diff --git a/src/Calculator.sln b/src/Calculator.sln index 11fe757e..21180f40 100644 --- a/src/Calculator.sln +++ b/src/Calculator.sln @@ -17,20 +17,25 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcViewModel", "CalcViewMo EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorUnitTests", "CalculatorUnitTests\CalculatorUnitTests.vcxproj", "{D3BAED2C-4B07-4E1D-8807-9D6499450349}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorUITests", "CalculatorUITests\CalculatorUITests.csproj", "{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalculatorUITests", "CalculatorUITests\CalculatorUITests.csproj", "{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalculatorUITestFramework", "CalculatorUITestFramework\CalculatorUITestFramework.csproj", "{96454213-94AF-457D-9DF9-B14F80E7770F}" 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 @@ -43,6 +48,7 @@ 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 @@ -55,6 +61,7 @@ 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 @@ -63,6 +70,7 @@ 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 @@ -71,6 +79,7 @@ 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 @@ -79,6 +88,7 @@ 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 @@ -87,6 +97,7 @@ 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 @@ -95,6 +106,7 @@ 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 @@ -103,6 +115,8 @@ 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 @@ -111,6 +125,8 @@ Global {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 @@ -119,6 +135,26 @@ Global {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 new file mode 100644 index 00000000..2c9e21eb --- /dev/null +++ b/src/CalculatorUITestFramework/ApplicationBase.cs @@ -0,0 +1,205 @@ +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/CalculatorUITestFramework.csproj b/src/CalculatorUITestFramework/CalculatorUITestFramework.csproj new file mode 100644 index 00000000..8c096d59 --- /dev/null +++ b/src/CalculatorUITestFramework/CalculatorUITestFramework.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0 + + + + + + + + + + diff --git a/src/CalculatorUITestFramework/HistoryPanel.cs b/src/CalculatorUITestFramework/HistoryPanel.cs new file mode 100644 index 00000000..72474f88 --- /dev/null +++ b/src/CalculatorUITestFramework/HistoryPanel.cs @@ -0,0 +1,51 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting.Logging; +using OpenQA.Selenium.Appium; +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalculatorUITestFramework +{ + public class HistoryPanel : ApplicationBase + { + public WindowsElement HistoryLabel => TryFindElementByAccessibilityId("HistoryLabel"); + public WindowsElement HistoryListView => TryFindElementByAccessibilityId("HistoryListView"); + public WindowsElement ClearHistoryButton => TryFindElementByAccessibilityId("ClearHistory"); + + /// + /// Opens the History Pane by clicking the History pivot label. + /// + public void OpenHistoryPanel() + { + HistoryLabel.Click(); + } + + /// + /// Gets all of the history items listed in the History Pane. + /// + /// A readonly collection of history items. + public ReadOnlyCollection GetAllHistoryListViewItems() + { + OpenHistoryPanel(); + HistoryListView.WaitForDisplayed(); + return HistoryListView.FindElementsByClassName("ListViewItem"); + } + + /// + /// Opens the History Pane and clicks the delete button if it is visible. + /// + public void ClearHistory() + { + OpenHistoryPanel(); + if (ClearHistoryButton != null) + { + ClearHistoryButton.Click(); + } + } + } +} diff --git a/src/CalculatorUITestFramework/MemoryPanel.cs b/src/CalculatorUITestFramework/MemoryPanel.cs new file mode 100644 index 00000000..ee65b805 --- /dev/null +++ b/src/CalculatorUITestFramework/MemoryPanel.cs @@ -0,0 +1,43 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium.Appium; +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalculatorUITestFramework +{ + public class MemoryPanel : ApplicationBase + { + 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"); + + /// + /// Opens the Memory Pane by clicking the Memory pivot label. + /// + public void OpenMemoryPanel() + { + MemoryLabel.Click(); + MemoryPane.WaitForDisplayed(); + } + + /// + /// Gets all of the memory items listed in the Memory Pane. + /// + /// A readonly collection of memory items. + public ReadOnlyCollection GetAllMemoryListViewItems() + { + OpenMemoryPanel(); + return MemoryListView.FindElementsByClassName("ListViewItem"); + } + } +} diff --git a/src/CalculatorUITestFramework/NavigationMenu.cs b/src/CalculatorUITestFramework/NavigationMenu.cs new file mode 100644 index 00000000..8e7d1815 --- /dev/null +++ b/src/CalculatorUITestFramework/NavigationMenu.cs @@ -0,0 +1,105 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Diagnostics; +using System.Threading; + +namespace CalculatorUITestFramework +{ + public enum CalculatorMode + { + StandardCalculator, + ScientificCalculator, + ProgrammerCalculator, + DateCalculator, + Currency, + Volume, + Length, + Weight, + Temperature, + Energy, + Area, + Speed, + Time, + Power, + Data, + Pressure, + Angle + } + public class NavigationMenu : ApplicationBase + { + public static WindowsElement NavigationMenuButton => TryFindElementByAccessibilityId("TogglePaneButton"); + public static WindowsElement NavigationMenuPane => TryFindElementByClassName("SplitViewPane"); + + /// + /// Changes the mode using the navigation menu in the UI + /// + /// The mode to be changed to + public static void ChangeCalculatorMode(CalculatorMode mode) + { + string modeAccessibilityId; + switch (mode) + { + case CalculatorMode.StandardCalculator: + modeAccessibilityId = "Standard"; + break; + case CalculatorMode.ScientificCalculator: + modeAccessibilityId = "Scientific"; + break; + case CalculatorMode.ProgrammerCalculator: + modeAccessibilityId = "Programmer"; + break; + case CalculatorMode.DateCalculator: + modeAccessibilityId = "Date"; + break; + case CalculatorMode.Currency: + modeAccessibilityId = "Currency"; + break; + case CalculatorMode.Volume: + modeAccessibilityId = "Volume"; + break; + case CalculatorMode.Length: + modeAccessibilityId = "Length"; + break; + case CalculatorMode.Weight: + modeAccessibilityId = "Weight"; + break; + case CalculatorMode.Temperature: + modeAccessibilityId = "Temperature"; + break; + case CalculatorMode.Energy: + modeAccessibilityId = "Energy"; + break; + case CalculatorMode.Area: + modeAccessibilityId = "Area"; + break; + case CalculatorMode.Speed: + modeAccessibilityId = "Speed"; + break; + case CalculatorMode.Time: + modeAccessibilityId = "Time"; + break; + case CalculatorMode.Power: + modeAccessibilityId = "Power"; + break; + case CalculatorMode.Data: + modeAccessibilityId = "Data"; + break; + case CalculatorMode.Pressure: + modeAccessibilityId = "Pressure"; + break; + case CalculatorMode.Angle: + modeAccessibilityId = "Angle"; + break; + default: + modeAccessibilityId = string.Empty; + break; + } + + + NavigationMenuButton.Click(); + NavigationMenuPane.WaitForDisplayed(); + TryFindElementByAccessibilityId(modeAccessibilityId).Click(); + } + } +} diff --git a/src/CalculatorUITestFramework/NumerPad.cs b/src/CalculatorUITestFramework/NumerPad.cs new file mode 100644 index 00000000..2e0ea526 --- /dev/null +++ b/src/CalculatorUITestFramework/NumerPad.cs @@ -0,0 +1,77 @@ +using System; +using OpenQA.Selenium.Appium.Windows; + +namespace CalculatorUITestFramework +{ + public class NumerPad : ApplicationBase + { + 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"); + + /// + /// Translates a number into the Calculator button clicks. + /// + /// Number to be entered into the calculator. + public void TranslateNumberToButtonClicks(double number) + { + string numberStr = number.ToString(); + if (numberStr.StartsWith("-")) + { + numberStr = numberStr.Remove(0, 1); + numberStr += '-'; + } + foreach (char digit in numberStr) + { + switch (digit) + { + case '0': + Num0Button.Click(); + break; + case '1': + Num1Button.Click(); + break; + case '2': + Num2Button.Click(); + break; + case '3': + Num3Button.Click(); + break; + case '4': + Num4Button.Click(); + break; + case '5': + Num5Button.Click(); + break; + case '6': + Num6Button.Click(); + break; + case '7': + Num7Button.Click(); + break; + case '8': + Num8Button.Click(); + break; + case '9': + Num9Button.Click(); + break; + case '.': + DecimalButton.Click(); + break; + case '-': + NegateButton.Click(); + break; + } + } + } + } +} diff --git a/src/CalculatorUITestFramework/StandardCalculatorPage.cs b/src/CalculatorUITestFramework/StandardCalculatorPage.cs new file mode 100644 index 00000000..4e543380 --- /dev/null +++ b/src/CalculatorUITestFramework/StandardCalculatorPage.cs @@ -0,0 +1,57 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium.Appium.Windows; +using OpenQA.Selenium.Remote; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +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 static StandardOperatorsPanel StandardOperators = new StandardOperatorsPanel(); + public static MemoryPanel MemoryPanel = new MemoryPanel(); + public static HistoryPanel HistoryPanel = new HistoryPanel(); + + public static void StandardCalculatorSetup(TestContext context) + { + // Create session to launch a Calculator window + ApplicationSetup(context); + // Identify calculator mode by locating the header + + + // Ensure that calculator is in standard mode + NavigationMenu.ChangeCalculatorMode(CalculatorMode.StandardCalculator); + var source = CalculatorSession.PageSource; + Assert.IsNotNull(CalculatorResult); + } + + /// + /// 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) + { + StandardOperators.ClearButton.Click(); + MemoryPanel.MemoryClear.Click(); + if (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() + { + return CalculatorResult.Text.Replace("Display is", string.Empty).Trim(); + } + } +} diff --git a/src/CalculatorUITestFramework/StandardOperatorsPanel.cs b/src/CalculatorUITestFramework/StandardOperatorsPanel.cs new file mode 100644 index 00000000..c0db5522 --- /dev/null +++ b/src/CalculatorUITestFramework/StandardOperatorsPanel.cs @@ -0,0 +1,156 @@ +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalculatorUITestFramework +{ + /// + /// UI elements and helper methods to perform common mathematical standard operations. + /// + public class StandardOperatorsPanel : ApplicationBase + { + 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"); + + /// + /// Uses the Calculator UI to add a list of numbers. + /// + /// List of numbers to be added. + public void Add(List numbers) + { + for (int i = 0; i < numbers.Count; i++) + { + NumberPad.TranslateNumberToButtonClicks(numbers[i]); + + if (i != numbers.Count - 1) + { + PlusButton.Click(); + } + else + { + EqualButton.Click(); + } + } + } + + /// + /// Uses the Calculator UI to subtract a list of numbers. + /// + /// List of numbers to be subtracted. + public void Subtract(List numbers) + { + for (int i = 0; i < numbers.Count; i++) + { + NumberPad.TranslateNumberToButtonClicks(numbers[i]); + + if (i != numbers.Count - 1) + { + MinusButton.Click(); + } + else + { + EqualButton.Click(); + } + } + } + + /// + /// Uses the Calculator UI to multiply a list of numbers. + /// + /// List of numbers to be multiplied. + public void Multiply(List numbers) + { + for (int i = 0; i < numbers.Count; i++) + { + NumberPad.TranslateNumberToButtonClicks(numbers[i]); + + if (i != numbers.Count - 1) + { + MultiplyButton.Click(); + } + else + { + EqualButton.Click(); + } + } + } + + /// + /// Uses the Calculator UI to divide a list of numbers. + /// + /// List of numbers to be divided. + public void Divide(List numbers) + { + for (int i = 0; i < numbers.Count; i++) + { + NumberPad.TranslateNumberToButtonClicks(numbers[i]); + + if (i != numbers.Count - 1) + { + DivideButton.Click(); + } + else + { + EqualButton.Click(); + } + } + } + + /// + /// Uses the Calculator UI to take the reciprocal of a number. + /// + /// Number to take the reciprocal of. + public void Reciprocal(double number) + { + NumberPad.TranslateNumberToButtonClicks(number); + InvertButton.Click(); + } + + /// + /// Uses the Calculator UI to square a number. + /// + /// The number to be squared. + public void Square(double number) + { + NumberPad.TranslateNumberToButtonClicks(number); + XPower2Button.Click(); + } + + /// + /// Uses the Calculator UI to cube a number. + /// + /// The number to be cubed. + public void Cube(double number) + { + NumberPad.TranslateNumberToButtonClicks(number); + var source = CalculatorSession.PageSource; + XPower3Button.Click(); + } + + /// + /// Uses the Calculator UI to take the square root of a number. + /// + /// Number to take the square root of. + public void SquareRoot(double number) + { + NumberPad.TranslateNumberToButtonClicks(number); + SquareRootButton.Click(); + } + } +} diff --git a/src/CalculatorUITests/CalculatorSession.cs b/src/CalculatorUITests/CalculatorSession.cs deleted file mode 100644 index 9e4caa9b..00000000 --- a/src/CalculatorUITests/CalculatorSession.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using OpenQA.Selenium.Appium; -using OpenQA.Selenium.Appium.Windows; -using System; - -namespace CalculatorUITests -{ - public class CalculatorSession - { - // 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"; - protected static WindowsDriver session; - - public static void Setup(TestContext context) - { - // Launch Calculator application if it is not yet launched - if (session == null) - { - // Create a new 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"); - session = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), options); - session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(180); - Assert.IsNotNull(session); - } - } - - public static void TearDown() - { - // Close the application and delete the session - if (session != null) - { - session.Quit(); - session = null; - } - } - } -} diff --git a/src/CalculatorUITests/CalculatorUITests.csproj b/src/CalculatorUITests/CalculatorUITests.csproj index 42ed8672..c117f9fd 100644 --- a/src/CalculatorUITests/CalculatorUITests.csproj +++ b/src/CalculatorUITests/CalculatorUITests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1 @@ -13,6 +13,10 @@ + + + + PreserveNewest diff --git a/src/CalculatorUITests/ScenarioStandard.cs b/src/CalculatorUITests/ScenarioStandard.cs deleted file mode 100644 index 8bc824a3..00000000 --- a/src/CalculatorUITests/ScenarioStandard.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using OpenQA.Selenium.Appium.Windows; -using System.Threading; -using System; - -namespace CalculatorUITests -{ - [TestClass] - public class StandardModeTests : CalculatorSession - { - private static WindowsElement header; - private static WindowsElement calculatorResult; - - [TestMethod] - public void Addition() - { - // Find the buttons by their names and click them in sequence to perform 1 + 7 = 8 - session.FindElementByName("One").Click(); - session.FindElementByName("Plus").Click(); - session.FindElementByName("Seven").Click(); - session.FindElementByName("Equals").Click(); - Assert.AreEqual("8", GetCalculatorResultText()); - } - - [TestMethod] - public void Division() - { - // Find the buttons by their accessibility ids and click them in sequence to perform 88 / 11 = 8 - session.FindElementByAccessibilityId("num8Button").Click(); - session.FindElementByAccessibilityId("num8Button").Click(); - session.FindElementByAccessibilityId("divideButton").Click(); - session.FindElementByAccessibilityId("num1Button").Click(); - session.FindElementByAccessibilityId("num1Button").Click(); - session.FindElementByAccessibilityId("equalButton").Click(); - Assert.AreEqual("8", GetCalculatorResultText()); - } - - [TestMethod] - public void Multiplication() - { - session.FindElementByAccessibilityId("num9Button").Click(); - session.FindElementByAccessibilityId("multiplyButton").Click(); - session.FindElementByAccessibilityId("num9Button").Click(); - session.FindElementByAccessibilityId("equalButton").Click(); - Assert.AreEqual("81", GetCalculatorResultText()); - } - - [TestMethod] - public void Subtraction() - { - // Find the buttons by their accessibility ids using XPath and click them in sequence to perform 9 - 1 = 8 - session.FindElementByAccessibilityId("num9Button").Click(); - session.FindElementByAccessibilityId("minusButton").Click(); - session.FindElementByAccessibilityId("num1Button").Click(); - session.FindElementByAccessibilityId("equalButton").Click(); - Assert.AreEqual("8", GetCalculatorResultText()); - } - - - [ClassInitialize] - public static void ClassInitialize(TestContext context) - { - // Create session to launch a Calculator window - Setup(context); - // Identify calculator mode by locating the header - try - { - header = session.FindElementByAccessibilityId("Header"); - } - catch - { - header = session.FindElementByAccessibilityId("ContentPresenter"); - } - - // Ensure that calculator is in standard mode - if (!header.Text.Equals("Standard", StringComparison.OrdinalIgnoreCase)) - { - session.FindElementByAccessibilityId("TogglePaneButton").Click(); - Thread.Sleep(TimeSpan.FromSeconds(1)); - var splitViewPane = session.FindElementByClassName("SplitViewPane"); - splitViewPane.FindElementByName("Standard Calculator").Click(); - Thread.Sleep(TimeSpan.FromSeconds(1)); - Assert.IsTrue(header.Text.Equals("Standard", StringComparison.OrdinalIgnoreCase)); - } - - // Locate the calculatorResult element - calculatorResult = session.FindElementByAccessibilityId("CalculatorResults"); - Assert.IsNotNull(calculatorResult); - } - - [ClassCleanup] - public static void ClassCleanup() - { - TearDown(); - } - - [TestInitialize] - public void Clear() - { - session.FindElementByName("Clear").Click(); - Assert.AreEqual("0", GetCalculatorResultText()); - } - - private string GetCalculatorResultText() - { - return calculatorResult.Text.Replace("Display is", string.Empty).Trim(); - } - } -} diff --git a/src/CalculatorUITests/StandardModeFunctionalTests.cs b/src/CalculatorUITests/StandardModeFunctionalTests.cs new file mode 100644 index 00000000..8e9fc5e7 --- /dev/null +++ b/src/CalculatorUITests/StandardModeFunctionalTests.cs @@ -0,0 +1,269 @@ +using CalculatorUITestFramework; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium; +using OpenQA.Selenium.Remote; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace CalculatorUITests +{ + [TestClass] + public class StandardModeFunctionalTests + { + private StandardOperatorsPanel standardOperators => StandardCalculatorPage.StandardOperators; + + /// + /// Initializes the WinAppDriver web driver session. + /// + /// + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + StandardCalculatorPage.StandardCalculatorSetup(context); + } + + /// + /// Closes the app and WinAppDriver web driver session. + /// + [ClassCleanup] + public static void ClassCleanup() + { + StandardCalculatorPage.TearDown(); + } + + /// + /// Ensures the calculator is in a cleared state + /// + [TestInitialize] + public void TestInit() + { + StandardCalculatorPage.ClearAll(false); + Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestCleanup] + public void TestCleanup() + { + StandardCalculatorPage.ClearAll(); + } + + #region Basic Arthimetic Tests + [TestMethod] + public void BVT_Reciprocal() + { + standardOperators.Reciprocal(4); + Assert.AreEqual("0.25", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_Squared() + { + standardOperators.Square(-15.5); + Assert.AreEqual("240.25", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_SquareRoot() + { + standardOperators.SquareRoot(144); + Assert.AreEqual("12", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_Cubed() + { + standardOperators.Cube(-3); + Assert.AreEqual("-27", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_Percent() + { + standardOperators.NumberPad.TranslateNumberToButtonClicks(600); + standardOperators.MultiplyButton.Click(); + standardOperators.NumberPad.TranslateNumberToButtonClicks(15); + standardOperators.PercentButton.Click(); + standardOperators.EqualButton.Click(); + Assert.AreEqual("90", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_Delete() + { + standardOperators.NumberPad.TranslateNumberToButtonClicks(-12345); + standardOperators.BackSpaceButton.Click(); + Assert.AreEqual("-1,234", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_ClearAll() + { + standardOperators.Add(new List() { 12345, 6789 }); + standardOperators.ClearButton.Click(); + Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void BVT_ClearEntry() + { + standardOperators.NumberPad.TranslateNumberToButtonClicks(-12345); + standardOperators.MinusButton.Click(); + standardOperators.NumberPad.TranslateNumberToButtonClicks(5678); + standardOperators.ClearEntryButton.Click(); + Assert.AreEqual("0", StandardCalculatorPage.GetCalculatorResultText()); + } + #endregion + + #region Keyboard Input Tests + [TestMethod] + public void KeyboardInput_Subtract() + { + StandardCalculatorPage.SendKeys("70090-890987="); + Assert.AreEqual("-820,897", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void KeyboardInput_Multiply() + { + StandardCalculatorPage.SendKeys("-15*3="); + Assert.AreEqual("-45", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void KeyboardInput_Divide() + { + StandardCalculatorPage.SendKeys("26/13="); + Assert.AreEqual("2", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void KeyboardInput_Reciprocal() + { + StandardCalculatorPage.SendKeys("10r"); + Assert.AreEqual("0.1", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void KeyboardInput_Squared() + { + StandardCalculatorPage.SendKeys("3q"); + Assert.AreEqual("9", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void KeyboardInput_SquareRoot() + { + StandardCalculatorPage.SendKeys("100@"); + Assert.AreEqual("10", StandardCalculatorPage.GetCalculatorResultText()); + } + + [TestMethod] + public void KeyboardInput_Cubed() + { + StandardCalculatorPage.SendKeys("3#"); + Assert.AreEqual("27", StandardCalculatorPage.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()); + } + + #endregion + + #region Memory Tests + [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(); + 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(); + 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(); + 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; + } + } + } + #endregion + } +} diff --git a/src/CalculatorUITests/StandardModeSmokeTests.cs b/src/CalculatorUITests/StandardModeSmokeTests.cs new file mode 100644 index 00000000..239a9dba --- /dev/null +++ b/src/CalculatorUITests/StandardModeSmokeTests.cs @@ -0,0 +1,92 @@ +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(); + } + } +}