From 483dacbeffb2934c05fc4c1e37e9a9fc46e6c96c Mon Sep 17 00:00:00 2001 From: Bura Chuhadar Date: Tue, 10 Nov 2020 12:56:39 -0500 Subject: [PATCH] Fixes issue #1409 (#1412) * Fixes issue #1409 Copy pasting into Currency locks the editor. Skipping the validation of full editor lock when backspace or clear button is clicked. * Adding code review feedback. * Adding code review feedback. --- src/CalcViewModel/UnitConverterViewModel.cpp | 4 +- .../UnitConverterOperatorsPanel.cs | 17 +++ .../UnitConverterPage.cs | 68 +++++++++ .../UnitConverterResults.cs | 47 ++++++ .../CurrencyConverterFunctionalTests.cs | 134 ++++++++++++++++++ src/CalculatorUnitTests/UnitConverterTest.cpp | 37 +++++ 6 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 src/CalculatorUITestFramework/UnitConverterOperatorsPanel.cs create mode 100644 src/CalculatorUITestFramework/UnitConverterPage.cs create mode 100644 src/CalculatorUITestFramework/UnitConverterResults.cs create mode 100644 src/CalculatorUITests/CurrencyConverterFunctionalTests.cs diff --git a/src/CalcViewModel/UnitConverterViewModel.cpp b/src/CalcViewModel/UnitConverterViewModel.cpp index c2ad77e4..a159cf7f 100644 --- a/src/CalcViewModel/UnitConverterViewModel.cpp +++ b/src/CalcViewModel/UnitConverterViewModel.cpp @@ -474,7 +474,9 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object ^ parameter) static constexpr UCM::Command OPERANDS[] = { UCM::Command::Zero, UCM::Command::One, UCM::Command::Two, UCM::Command::Three, UCM::Command::Four, UCM::Command::Five, UCM::Command::Six, UCM::Command::Seven, UCM::Command::Eight, UCM::Command::Nine }; - if (m_isInputBlocked) + if (m_isInputBlocked && + command != UCM::Command::Clear && + command != UCM::Command::Backspace) { return; } diff --git a/src/CalculatorUITestFramework/UnitConverterOperatorsPanel.cs b/src/CalculatorUITestFramework/UnitConverterOperatorsPanel.cs new file mode 100644 index 00000000..f2be9bdc --- /dev/null +++ b/src/CalculatorUITestFramework/UnitConverterOperatorsPanel.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CalculatorUITestFramework +{ + public class UnitConverterOperatorsPanel + { + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + public NumberPad NumberPad = new NumberPad(); + public WindowsElement ClearButton => this.session.TryFindElementByAccessibilityId("ClearEntryButtonPos0"); + public WindowsElement BackSpaceButton => this.session.TryFindElementByAccessibilityId("BackSpaceButtonSmall"); + } +} diff --git a/src/CalculatorUITestFramework/UnitConverterPage.cs b/src/CalculatorUITestFramework/UnitConverterPage.cs new file mode 100644 index 00000000..e3984cf9 --- /dev/null +++ b/src/CalculatorUITestFramework/UnitConverterPage.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +using OpenQA.Selenium.Appium.Windows; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CalculatorUITestFramework +{ + public class UnitConverterPage + { + public UnitConverterOperatorsPanel UnitConverterOperators = new UnitConverterOperatorsPanel(); + public NavigationMenu NavigationMenu = new NavigationMenu(); + public UnitConverterResults UnitConverterResults = new UnitConverterResults(); + + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + + /// + /// Clear the Calculator display + /// + public void ClearAll() + { + this.UnitConverterOperators.ClearButton.Click(); + } + + ///// + ///// Ensures that the calculator result text is zero; if not, clears all + ///// + public void EnsureCalculatorResultTextIsZero() + { + if ("0" != this.UnitConverterResults.GetCalculationResult1Text()) + { + this.ClearAll(); + } + } + + /// + /// Navigates the calculator is in currency mode + /// + public void NavigateToUnitConverter() + { + // Ensure that calculator is in Currency Mode + this.NavigationMenu.ChangeCalculatorMode(CalculatorMode.Currency); + this.UnitConverterResults.IsResultsDisplayPresent(); + } + + ///// + ///// Ensures that the calculator is in Currency Mode + ///// + public void EnsureCalculatorIsCurrencyMode() + { + string source = WinAppDriver.Instance.CalculatorSession.PageSource; + if (source.Contains("Header")) + { + string header = CalculatorApp.Header.Text; + if (header == "Currency") + { + return; + } + else + { + this.NavigateToUnitConverter(); + } + } + } + + } +} diff --git a/src/CalculatorUITestFramework/UnitConverterResults.cs b/src/CalculatorUITestFramework/UnitConverterResults.cs new file mode 100644 index 00000000..474fb9bd --- /dev/null +++ b/src/CalculatorUITestFramework/UnitConverterResults.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium.Appium.Windows; +using System; +using OpenQA.Selenium.Interactions; +using System.Text.RegularExpressions; + +namespace CalculatorUITestFramework +{ + public class UnitConverterResults + { + private WindowsDriver session => WinAppDriver.Instance.CalculatorSession; + private WindowsElement CalculationResult1 => this.session.TryFindElementByAccessibilityId("Value1"); + + private WindowsElement CalculationResult2 => this.session.TryFindElementByAccessibilityId("Value2"); + + /// + /// Gets the text from the Value1 control and removes the narrator text that is not displayed in the UI. + /// + /// The string shown in the UI. + public string GetCalculationResult1Text() + { + return Regex.Replace(this.CalculationResult1.Text.Trim(), "[^0-9.]", ""); + } + + /// + /// Verifies that CalculationResult1 and CalculationResult2 are not null + /// + /// The string shown in the UI. + public void IsResultsDisplayPresent() + { + Assert.IsNotNull(this.CalculationResult1); + Assert.IsNotNull(this.CalculationResult2); + } + + /// + /// Gets the text from the Value2 control and removes the narrator text that is not displayed in the UI. + /// + /// The string shown in the UI. + public string GetCalculationResult2Text() + { + return Regex.Replace(this.CalculationResult2.Text.Trim(), "[^0-9.]", ""); + } + + } +} diff --git a/src/CalculatorUITests/CurrencyConverterFunctionalTests.cs b/src/CalculatorUITests/CurrencyConverterFunctionalTests.cs new file mode 100644 index 00000000..fc8d669e --- /dev/null +++ b/src/CalculatorUITests/CurrencyConverterFunctionalTests.cs @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +using CalculatorUITestFramework; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium; +using System; + +namespace CalculatorUITests +{ + [TestClass] + public class CurrencyConverterFunctionalTests + { + private static UnitConverterPage page = new UnitConverterPage(); + + /// + /// Initializes the WinAppDriver web driver session. + /// + /// + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + // Create session to launch a Calculator window + WinAppDriver.Instance.SetupCalculatorSession(context); + } + + /// + /// Closes the app and WinAppDriver web driver session. + /// + [ClassCleanup] + public static void ClassCleanup() + { + // Tear down Calculator session. + WinAppDriver.Instance.TearDownCalculatorSession(); + } + + /// + /// Ensures the calculator is in a cleared state + /// + [TestInitialize] + public void TestInit() + { + CalculatorApp.EnsureCalculatorHasFocus(); + page.EnsureCalculatorIsCurrencyMode(); + page.EnsureCalculatorResultTextIsZero(); + } + + [TestCleanup] + public void TestCleanup() + { + page.ClearAll(); + } + + #region Basic UI Functionality via Mouse Input Tests + /// + /// These automated tests verify clicking each of the buttons in the Calculator UI and getting an expected result + /// Via mouse input, all basic UI functionality is checked + /// + [TestMethod] + [Priority(0)] + public void MouseInput_EnterInputAndCheckTheResult() + { + //Verifies the 2 is entered and clear is functional + page.UnitConverterOperators.NumberPad.Num2Button.Click(); + Assert.AreEqual("2", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 2 button + Assert.AreEqual("2", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 2 button + } + + /// + /// These automated tests verify clicking each of the buttons in the Calculator UI and getting an expected result + /// Via mouse input, all basic UI functionality is checked + /// + [TestMethod] + [Priority(1)] + public void MouseInput_EnterInputWithFullDecimalAndClear() + { + //Verifies the 20.42 is entered and clear is functional + page.UnitConverterOperators.NumberPad.Num2Button.Click(); + Assert.AreEqual("2", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 2 button + Assert.AreEqual("2", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 2 button + page.UnitConverterOperators.NumberPad.Num0Button.Click(); + Assert.AreEqual("20", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 2 button + Assert.AreEqual("20", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 2 button + page.UnitConverterOperators.NumberPad.DecimalButton.Click(); + Assert.AreEqual("20.00", page.UnitConverterResults.GetCalculationResult1Text()); //verifies decimal button + Assert.AreEqual("20", page.UnitConverterResults.GetCalculationResult2Text()); //verifies decimal button + page.UnitConverterOperators.NumberPad.Num4Button.Click(); + Assert.AreEqual("20.40", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 4 button + Assert.AreEqual("20.40", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 4 button + page.UnitConverterOperators.NumberPad.Num3Button.Click(); + Assert.AreEqual("20.43", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 3 button + Assert.AreEqual("20.43", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 3 button + page.UnitConverterOperators.NumberPad.Num3Button.Click(); + page.UnitConverterOperators.ClearButton.Click(); + Assert.AreEqual("0", page.UnitConverterResults.GetCalculationResult1Text()); //verifies Clear button + Assert.AreEqual("0", page.UnitConverterResults.GetCalculationResult2Text()); //verifies Clear button + } + + /// + /// These automated tests verify clicking each of the buttons in the Calculator UI and getting an expected result + /// Via mouse input, all basic UI functionality is checked + /// + [TestMethod] + [Priority(1)] + public void MouseInput_EnterInputWithFullDecimalAndClearWithBackspace() + { + //Verifies the 20.42 is entered and clear is functional + page.UnitConverterOperators.NumberPad.Num2Button.Click(); + Assert.AreEqual("2", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 2 button + Assert.AreEqual("2", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 2 button + page.UnitConverterOperators.NumberPad.Num0Button.Click(); + Assert.AreEqual("20", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 2 button + Assert.AreEqual("20", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 2 button + page.UnitConverterOperators.NumberPad.DecimalButton.Click(); + Assert.AreEqual("20.00", page.UnitConverterResults.GetCalculationResult1Text()); //verifies decimal button + Assert.AreEqual("20", page.UnitConverterResults.GetCalculationResult2Text()); //verifies decimal button + page.UnitConverterOperators.NumberPad.Num4Button.Click(); + Assert.AreEqual("20.40", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 4 button + Assert.AreEqual("20.40", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 4 button + page.UnitConverterOperators.NumberPad.Num3Button.Click(); + Assert.AreEqual("20.43", page.UnitConverterResults.GetCalculationResult1Text()); //verifies 3 button + Assert.AreEqual("20.43", page.UnitConverterResults.GetCalculationResult2Text()); //verifies 3 button + page.UnitConverterOperators.NumberPad.Num3Button.Click(); + page.UnitConverterOperators.BackSpaceButton.Click(); + page.UnitConverterOperators.BackSpaceButton.Click(); + page.UnitConverterOperators.BackSpaceButton.Click(); + page.UnitConverterOperators.BackSpaceButton.Click(); + page.UnitConverterOperators.BackSpaceButton.Click(); + Assert.AreEqual("0", page.UnitConverterResults.GetCalculationResult1Text()); //verifies Backspace button clicks + Assert.AreEqual("0", page.UnitConverterResults.GetCalculationResult2Text()); //verifies Backspace button clicks + } + + #endregion + } +} diff --git a/src/CalculatorUnitTests/UnitConverterTest.cpp b/src/CalculatorUnitTests/UnitConverterTest.cpp index 3c4a8f28..17c6d32b 100644 --- a/src/CalculatorUnitTests/UnitConverterTest.cpp +++ b/src/CalculatorUnitTests/UnitConverterTest.cpp @@ -202,6 +202,8 @@ namespace UnitConverterUnitTests TEST_METHOD(UnitConverterTestQuote); TEST_METHOD(UnitConverterTestUnquote); TEST_METHOD(UnitConverterTestBackspace); + TEST_METHOD(UnitConverterTestBackspaceBasic); + TEST_METHOD(UnitConverterTestClear); TEST_METHOD(UnitConverterTestScientificInputs); TEST_METHOD(UnitConverterTestSupplementaryResultRounding); TEST_METHOD(UnitConverterTestMaxDigitsReached); @@ -291,6 +293,41 @@ namespace UnitConverterUnitTests VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test2), end(test2)))); } + + // Verify a basic copy paste steam. '20.43' with backspace button pressed + void UnitConverterTest::UnitConverterTestBackspaceBasic() + { + s_unitConverter->SendCommand(Command::Two); + s_unitConverter->SendCommand(Command::Zero); + s_unitConverter->SendCommand(Command::Decimal); + s_unitConverter->SendCommand(Command::Four); + s_unitConverter->SendCommand(Command::Three); + s_unitConverter->SendCommand(Command::Backspace); + + VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"20.4"), wstring(L"20.4"))); + s_unitConverter->SendCommand(Command::Backspace); + VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"20."), wstring(L"20"))); + s_unitConverter->SendCommand(Command::Backspace); + VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"20"), wstring(L"20"))); + s_unitConverter->SendCommand(Command::Backspace); + VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"2"), wstring(L"2"))); + s_unitConverter->SendCommand(Command::Backspace); + VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"0"), wstring(L"0"))); + } + + // Verify a basic copy paste steam. '20.43' with backspace button pressed + void UnitConverterTest::UnitConverterTestClear() + { + s_unitConverter->SendCommand(Command::Two); + s_unitConverter->SendCommand(Command::Zero); + s_unitConverter->SendCommand(Command::Decimal); + s_unitConverter->SendCommand(Command::Four); + s_unitConverter->SendCommand(Command::Three); + s_unitConverter->SendCommand(Command::Clear); + + VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"0"), wstring(L"0"))); + } + // Check the getter functions void UnitConverterTest::UnitConverterTestGetters() {