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();
+ }
+ }
+}