| // <copyright file="BasicKeyboardInterfaceTest.cs" company="Selenium Committers"> |
| // Licensed to the Software Freedom Conservancy (SFC) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The SFC licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // </copyright> |
| |
| using NUnit.Framework; |
| using OpenQA.Selenium.Environment; |
| using System; |
| using System.Drawing; |
| using System.Runtime.InteropServices; |
| |
| namespace OpenQA.Selenium.Interactions; |
| |
| [TestFixture] |
| public class BasicKeyboardInterfaceTest : DriverTestFixture |
| { |
| [SetUp] |
| public void Setup() |
| { |
| //new Actions(driver).SendKeys(Keys.Null).Perform(); |
| IActionExecutor actionExecutor = driver as IActionExecutor; |
| if (actionExecutor != null) |
| { |
| actionExecutor.ResetInputState(); |
| } |
| } |
| |
| [TearDown] |
| public void ReleaseModifierKeys() |
| { |
| //new Actions(driver).SendKeys(Keys.Null).Perform(); |
| IActionExecutor actionExecutor = driver as IActionExecutor; |
| if (actionExecutor != null) |
| { |
| actionExecutor.ResetInputState(); |
| } |
| } |
| |
| [Test] |
| public void ShouldSetActiveKeyboard() |
| { |
| Actions actionProvider = new Actions(driver); |
| actionProvider.SetActiveKeyboard("test keyboard"); |
| |
| KeyInputDevice device = actionProvider.GetActiveKeyboard(); |
| |
| Assert.That(device.DeviceName, Is.EqualTo("test keyboard")); |
| } |
| |
| [Test] |
| [IgnoreBrowser(Browser.Remote, "API not implemented in driver")] |
| public void ShouldAllowBasicKeyboardInput() |
| { |
| driver.Url = javascriptPage; |
| |
| IWebElement keyReporter = driver.FindElement(By.Id("keyReporter")); |
| |
| // Scroll the element into view before attempting any actions on it. |
| ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView();", keyReporter); |
| |
| Actions actionProvider = new Actions(driver); |
| IAction sendLowercase = actionProvider.SendKeys(keyReporter, "abc def").Build(); |
| |
| sendLowercase.Perform(); |
| |
| Assert.That(keyReporter.GetAttribute("value"), Is.EqualTo("abc def")); |
| |
| } |
| |
| [Test] |
| [IgnoreBrowser(Browser.Remote, "API not implemented in driver")] |
| public void ShouldAllowSendingKeyDownOnly() |
| { |
| driver.Url = javascriptPage; |
| |
| IWebElement keysEventInput = driver.FindElement(By.Id("theworks")); |
| |
| // Scroll the element into view before attempting any actions on it. |
| ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView();", keysEventInput); |
| |
| Actions actionProvider = new Actions(driver); |
| |
| IAction pressShift = actionProvider.KeyDown(keysEventInput, Keys.Shift).Build(); |
| pressShift.Perform(); |
| |
| IWebElement keyLoggingElement = driver.FindElement(By.Id("result")); |
| string logText = keyLoggingElement.Text; |
| |
| IAction releaseShift = actionProvider.KeyDown(keysEventInput, Keys.Shift).Build(); |
| releaseShift.Perform(); |
| |
| Assert.That(logText, Does.EndWith("keydown")); |
| } |
| |
| [Test] |
| [IgnoreBrowser(Browser.Remote, "API not implemented in driver")] |
| public void ShouldAllowSendingKeyUp() |
| { |
| driver.Url = javascriptPage; |
| IWebElement keysEventInput = driver.FindElement(By.Id("theworks")); |
| |
| // Scroll the element into view before attempting any actions on it. |
| ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView();", keysEventInput); |
| |
| IAction pressShift = new Actions(driver).KeyDown(keysEventInput, Keys.Shift).Build(); |
| pressShift.Perform(); |
| |
| IWebElement keyLoggingElement = driver.FindElement(By.Id("result")); |
| |
| string eventsText = keyLoggingElement.Text; |
| Assert.That(keyLoggingElement.Text, Does.EndWith("keydown")); |
| |
| IAction releaseShift = new Actions(driver).KeyUp(keysEventInput, Keys.Shift).Build(); |
| |
| releaseShift.Perform(); |
| |
| eventsText = keyLoggingElement.Text; |
| Assert.That(keyLoggingElement.Text, Does.EndWith("keyup")); |
| } |
| |
| [Test] |
| [IgnoreBrowser(Browser.IE, "Keypress and Keyup are getting switched")] |
| [IgnoreBrowser(Browser.Remote, "API not implemented in driver")] |
| public void ShouldAllowSendingKeysWithShiftPressed() |
| { |
| driver.Url = javascriptPage; |
| |
| IWebElement keysEventInput = driver.FindElement(By.Id("theworks")); |
| |
| keysEventInput.Click(); |
| |
| IAction pressShift = new Actions(driver).KeyDown(Keys.Shift).Build(); |
| pressShift.Perform(); |
| |
| IAction sendLowercase = new Actions(driver).SendKeys("ab").Build(); |
| sendLowercase.Perform(); |
| |
| IAction releaseShift = new Actions(driver).KeyUp(Keys.Shift).Build(); |
| releaseShift.Perform(); |
| |
| AssertThatFormEventsFiredAreExactly("focus keydown keydown keypress keyup keydown keypress keyup keyup"); |
| |
| Assert.That(keysEventInput.GetAttribute("value"), Is.EqualTo("AB")); |
| } |
| |
| [Test] |
| [IgnoreBrowser(Browser.Remote, "API not implemented in driver")] |
| public void ShouldAllowSendingKeysToActiveElement() |
| { |
| driver.Url = bodyTypingPage; |
| |
| Actions actionProvider = new Actions(driver); |
| IAction someKeys = actionProvider.SendKeys("ab").Build(); |
| someKeys.Perform(); |
| |
| AssertThatBodyEventsFiredAreExactly("keypress keypress"); |
| IWebElement formLoggingElement = driver.FindElement(By.Id("result")); |
| AssertThatFormEventsFiredAreExactly(string.Empty); |
| } |
| |
| [Test] |
| public void ThrowsIllegalArgumentExceptionWithNullKeys() |
| { |
| driver.Url = javascriptPage; |
| Assert.That(() => driver.FindElement(By.Id("keyReporter")).SendKeys(null), Throws.InstanceOf<ArgumentNullException>()); |
| } |
| |
| [Test] |
| public void CanGenerateKeyboardShortcuts() |
| { |
| driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("keyboard_shortcut.html"); |
| |
| IWebElement body = driver.FindElement(By.XPath("//body")); |
| AssertBackgroundColor(body, Color.White); |
| |
| new Actions(driver).KeyDown(Keys.Shift).SendKeys("1").KeyUp(Keys.Shift).Perform(); |
| AssertBackgroundColor(body, Color.Green); |
| |
| new Actions(driver).KeyDown(Keys.Alt).SendKeys("1").KeyUp(Keys.Alt).Perform(); |
| AssertBackgroundColor(body, Color.LightBlue); |
| |
| new Actions(driver) |
| .KeyDown(Keys.Shift).KeyDown(Keys.Alt) |
| .SendKeys("1") |
| .KeyUp(Keys.Shift).KeyUp(Keys.Alt) |
| .Perform(); |
| AssertBackgroundColor(body, Color.Silver); |
| } |
| |
| [Test] |
| public void SelectionSelectBySymbol() |
| { |
| driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("single_text_input.html"); |
| |
| IWebElement input = driver.FindElement(By.Id("textInput")); |
| |
| new Actions(driver).Click(input).SendKeys("abc def").Perform(); |
| |
| WaitFor(() => input.GetAttribute("value") == "abc def", "did not send initial keys"); |
| |
| if (!TestUtilities.IsInternetExplorer(driver)) |
| { |
| // When using drivers other than the IE, the click in |
| // the below action sequence may fall inside the double- |
| // click threshold (the IE driver has guards to prevent |
| // inadvertent double-clicks with multiple actions calls), |
| // so we call the "release actions" end point before |
| // doing the second action. |
| IActionExecutor executor = driver as IActionExecutor; |
| if (executor != null) |
| { |
| executor.ResetInputState(); |
| } |
| } |
| |
| new Actions(driver).Click(input) |
| .KeyDown(Keys.Shift) |
| .SendKeys(Keys.Left) |
| .SendKeys(Keys.Left) |
| .KeyUp(Keys.Shift) |
| .SendKeys(Keys.Delete) |
| .Perform(); |
| |
| Assert.That(input.GetAttribute("value"), Is.EqualTo("abc d")); |
| } |
| |
| [Test] |
| public void SelectionSelectByWord() |
| { |
| string controlModifier = Keys.Control; |
| if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
| { |
| controlModifier = Keys.Alt; |
| } |
| |
| driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("single_text_input.html"); |
| |
| IWebElement input = driver.FindElement(By.Id("textInput")); |
| |
| new Actions(driver).Click(input).SendKeys("abc def").Perform(); |
| |
| WaitFor(() => input.GetAttribute("value") == "abc def", "did not send initial keys"); |
| |
| if (!TestUtilities.IsInternetExplorer(driver)) |
| { |
| // When using drivers other than the IE, the click in |
| // the below action sequence may fall inside the double- |
| // click threshold (the IE driver has guards to prevent |
| // inadvertent double-clicks with multiple actions calls), |
| // so we call the "release actions" end point before |
| // doing the second action. |
| IActionExecutor executor = driver as IActionExecutor; |
| if (executor != null) |
| { |
| executor.ResetInputState(); |
| } |
| } |
| |
| new Actions(driver).Click(input) |
| .KeyDown(Keys.Shift) |
| .KeyDown(controlModifier) |
| .SendKeys(Keys.Left) |
| .KeyUp(controlModifier) |
| .KeyUp(Keys.Shift) |
| .SendKeys(Keys.Delete) |
| .Perform(); |
| |
| WaitFor(() => input.GetAttribute("value") == "abc ", "did not send editing keys"); |
| } |
| |
| [Test] |
| public void SelectionSelectAll() |
| { |
| string controlModifier = Keys.Control; |
| if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
| { |
| controlModifier = Keys.Command; |
| } |
| |
| driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("single_text_input.html"); |
| |
| IWebElement input = driver.FindElement(By.Id("textInput")); |
| |
| new Actions(driver).Click(input).SendKeys("abc def").Perform(); |
| |
| WaitFor(() => input.GetAttribute("value") == "abc def", "did not send initial keys"); |
| |
| new Actions(driver).Click(input) |
| .KeyDown(controlModifier) |
| .SendKeys("a") |
| .KeyUp(controlModifier) |
| .SendKeys(Keys.Delete) |
| .Perform(); |
| |
| Assert.That(input.GetAttribute("value"), Is.EqualTo(string.Empty)); |
| } |
| |
| //------------------------------------------------------------------ |
| // Tests below here are not included in the Java test suite |
| //------------------------------------------------------------------ |
| [Test] |
| [IgnoreBrowser(Browser.Remote, "API not implemented in driver")] |
| public void ShouldAllowSendingKeysWithLeftShiftPressed() |
| { |
| driver.Url = javascriptPage; |
| |
| IWebElement keysEventInput = driver.FindElement(By.Id("theworks")); |
| |
| keysEventInput.Click(); |
| |
| IAction pressShift = new Actions(driver).KeyDown(Keys.LeftShift).Build(); |
| pressShift.Perform(); |
| |
| IAction sendLowercase = new Actions(driver).SendKeys("ab").Build(); |
| sendLowercase.Perform(); |
| |
| IAction releaseShift = new Actions(driver).KeyUp(Keys.LeftShift).Build(); |
| releaseShift.Perform(); |
| |
| AssertThatFormEventsFiredAreExactly("focus keydown keydown keypress keyup keydown keypress keyup keyup"); |
| |
| Assert.That(keysEventInput.GetAttribute("value"), Is.EqualTo("AB")); |
| } |
| |
| private void AssertThatFormEventsFiredAreExactly(string message, string expected) |
| { |
| Assert.That(driver.FindElement(By.Id("result")).Text.Trim(), Is.EqualTo(expected), message); |
| } |
| |
| private void AssertThatFormEventsFiredAreExactly(string expected) |
| { |
| AssertThatFormEventsFiredAreExactly(string.Empty, expected); |
| } |
| |
| private void AssertThatBodyEventsFiredAreExactly(string expected) |
| { |
| Assert.That(driver.FindElement(By.Id("body_result")).Text.Trim(), Is.EqualTo(expected)); |
| } |
| |
| private Func<bool> BackgroundColorToChangeFrom(IWebElement element, Color currentColor) |
| { |
| return () => |
| { |
| string hexValue = string.Format("#{0:x2}{1:x2}{2:x2}", currentColor.R, currentColor.G, currentColor.B); |
| string rgbValue = string.Format("rgb({0}, {1}, {2})", currentColor.R, currentColor.G, currentColor.B); |
| string rgbaValue = string.Format("rgba({0}, {1}, {2}, 1)", currentColor.R, currentColor.G, currentColor.B); |
| string actual = element.GetCssValue("background-color"); |
| return actual != hexValue && actual != rgbValue && actual != rgbaValue; |
| }; |
| } |
| |
| private void AssertBackgroundColor(IWebElement el, Color expected) |
| { |
| string hexValue = string.Format("#{0:x2}{1:x2}{2:x2}", expected.R, expected.G, expected.B); |
| string rgbValue = string.Format("rgb({0}, {1}, {2})", expected.R, expected.G, expected.B); |
| string rgbaValue = string.Format("rgba({0}, {1}, {2}, 1)", expected.R, expected.G, expected.B); |
| string actual = el.GetCssValue("background-color"); |
| Assert.That(actual, Is.EqualTo(hexValue).Or.EqualTo(rgbValue).Or.EqualTo(rgbaValue)); |
| } |
| } |