# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. import urllib from marionette_driver.by import By from marionette_driver.errors import ElementNotInteractableException from marionette_driver.keys import Keys from marionette_harness import MarionetteTestCase, skip, skip_if_mobile def inline(doc): return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc)) class TypingTestCase(MarionetteTestCase): def setUp(self): super(TypingTestCase, self).setUp() if self.marionette.session_capabilities["platformName"] == "darwin": self.mod_key = Keys.META else: self.mod_key = Keys.CONTROL class TestTypingChrome(TypingTestCase): def setUp(self): super(TestTypingChrome, self).setUp() self.marionette.set_context("chrome") @skip_if_mobile("Interacting with chrome elements not available for Fennec") def test_cut_and_paste_shortcuts(self): with self.marionette.using_context("content"): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") self.assertEqual("", keyReporter.get_property("value")) keyReporter.send_keys("zyxwvutsr") self.assertEqual("zyxwvutsr", keyReporter.get_property("value")) # select all and cut keyReporter.send_keys(self.mod_key, "a") keyReporter.send_keys(self.mod_key, "x") self.assertEqual("", keyReporter.get_property("value")) url_bar = self.marionette.find_element(By.ID, "urlbar") # Clear contents first url_bar.send_keys(self.mod_key, "a") url_bar.send_keys(Keys.BACK_SPACE) self.assertEqual("", url_bar.get_attribute("value")) url_bar.send_keys(self.mod_key, "v") self.assertEqual("zyxwvutsr", url_bar.get_property("value")) class TestTypingContent(TypingTestCase): def testShouldFireKeyPressEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("a") result = self.marionette.find_element(By.ID, "result") self.assertTrue("press:" in result.text) def testShouldFireKeyDownEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("I") result = self.marionette.find_element(By.ID, "result") self.assertTrue("down" in result.text) def testShouldFireKeyUpEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("a") result = self.marionette.find_element(By.ID, "result") self.assertTrue("up:" in result.text) def testShouldTypeLowerCaseLetters(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("abc def") self.assertEqual("abc def", keyReporter.get_property("value")) def testShouldBeAbleToTypeCapitalLetters(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("ABC DEF") self.assertEqual("ABC DEF", keyReporter.get_property("value")) def testCutAndPasteShortcuts(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") self.assertEqual("", keyReporter.get_property("value")) keyReporter.send_keys("zyxwvutsr") self.assertEqual("zyxwvutsr", keyReporter.get_property("value")) # select all and cut keyReporter.send_keys(self.mod_key, "a") keyReporter.send_keys(self.mod_key, "x") self.assertEqual("", keyReporter.get_property("value")) keyReporter.send_keys(self.mod_key, "v") self.assertEqual("zyxwvutsr", keyReporter.get_property("value")) def testShouldBeAbleToTypeQuoteMarks(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("\"") self.assertEqual("\"", keyReporter.get_property("value")) def testShouldBeAbleToTypeTheAtCharacter(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("@") self.assertEqual("@", keyReporter.get_property("value")) def testShouldBeAbleToMixUpperAndLowerCaseLetters(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys("me@eXample.com") self.assertEqual("me@eXample.com", keyReporter.get_property("value")) def testArrowKeysShouldNotBePrintable(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) keyReporter = self.marionette.find_element(By.ID, "keyReporter") keyReporter.send_keys(Keys.ARROW_LEFT) self.assertEqual("", keyReporter.get_property("value")) def testWillSimulateAKeyUpWhenEnteringTextIntoInputElements(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyUp") element.send_keys("I like cheese") result = self.marionette.find_element(By.ID, "result") self.assertEqual(result.text, "I like cheese") def testWillSimulateAKeyDownWhenEnteringTextIntoInputElements(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyDown") element.send_keys("I like cheese") result = self.marionette.find_element(By.ID, "result") # Because the key down gets the result before the input element is # filled, we're a letter short here self.assertEqual(result.text, "I like chees") def testWillSimulateAKeyPressWhenEnteringTextIntoInputElements(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyPress") element.send_keys("I like cheese") result = self.marionette.find_element(By.ID, "result") # Because the key down gets the result before the input element is # filled, we're a letter short here self.assertEqual(result.text, "I like chees") def testWillSimulateAKeyUpWhenEnteringTextIntoTextAreas(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyUpArea") element.send_keys("I like cheese") result = self.marionette.find_element(By.ID, "result") self.assertEqual("I like cheese", result.text) def testWillSimulateAKeyDownWhenEnteringTextIntoTextAreas(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyDownArea") element.send_keys("I like cheese") result = self.marionette.find_element(By.ID, "result") # Because the key down gets the result before the input element is # filled, we're a letter short here self.assertEqual(result.text, "I like chees") def testWillSimulateAKeyPressWhenEnteringTextIntoTextAreas(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyPressArea") element.send_keys("I like cheese") result = self.marionette.find_element(By.ID, "result") # Because the key down gets the result before the input element is # filled, we're a letter short here self.assertEqual(result.text, "I like chees") @skip_if_mobile("Bug 1324752 - Arrow keys cannot be sent in Fennec") def testShouldReportKeyCodeOfArrowKeysUpDownEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) result = self.marionette.find_element(By.ID, "result") element = self.marionette.find_element(By.ID, "keyReporter") element.send_keys(Keys.ARROW_DOWN) self.assertIn("down: 40", result.text.strip()) self.assertIn("up: 40", result.text.strip()) element.send_keys(Keys.ARROW_UP) self.assertIn("down: 38", result.text.strip()) self.assertIn("up: 38", result.text.strip()) element.send_keys(Keys.ARROW_LEFT) self.assertIn("down: 37", result.text.strip()) self.assertIn("up: 37", result.text.strip()) element.send_keys(Keys.ARROW_RIGHT) self.assertIn("down: 39", result.text.strip()) self.assertIn("up: 39", result.text.strip()) # And leave no rubbish/printable keys in the "keyReporter" self.assertEqual("", element.get_property("value")) @skip("Reenable in Bug 1068728") def testNumericShiftKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) result = self.marionette.find_element(By.ID, "result") element = self.marionette.find_element(By.ID, "keyReporter") numericShiftsEtc = "~!@#$%^&*()_+{}:i\"<>?|END~" element.send_keys(numericShiftsEtc) self.assertEqual(numericShiftsEtc, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) def testLowerCaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyReporter") lowerAlphas = "abcdefghijklmnopqrstuvwxyz" element.send_keys(lowerAlphas) self.assertEqual(lowerAlphas, element.get_property("value")) @skip("Reenable in Bug 1068735") def testUppercaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) result = self.marionette.find_element(By.ID, "result") element = self.marionette.find_element(By.ID, "keyReporter") upperAlphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" element.send_keys(upperAlphas) self.assertEqual(upperAlphas, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) @skip("Reenable in Bug 1068726") def testAllPrintableKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) result = self.marionette.find_element(By.ID, "result") element = self.marionette.find_element(By.ID, "keyReporter") allPrintable = "!\"#$%&'()*+,-./0123456789:<=>?@ ABCDEFGHIJKLMNOPQRSTUVWXYZ [\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" element.send_keys(allPrintable) self.assertTrue(allPrintable, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) @skip("Reenable in Bug 1068733") def testSpecialSpaceKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyReporter") element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij") self.assertEqual("abcd fgh ij", element.get_property("value")) def testShouldTypeAnInteger(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) element = self.marionette.find_element(By.ID, "keyReporter") element.send_keys(1234) self.assertEqual("1234", element.get_property("value")) def testShouldSendKeysToElementsWithoutTheValueAttribute(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) # If we don't get an error below we are good self.marionette.find_element(By.TAG_NAME, "body").send_keys("foo") def test_not_interactable_if_hidden(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) not_displayed = self.marionette.find_element(By.ID, "notDisplayed") self.assertRaises(ElementNotInteractableException, not_displayed.send_keys, "foo") def test_appends_to_input_text(self): self.marionette.navigate(inline("")) el = self.marionette.find_element(By.TAG_NAME, "input") el.send_keys("foo") el.send_keys("bar") self.assertEqual("foobar", el.get_property("value")) def test_appends_to_textarea(self): self.marionette.navigate(inline("")) textarea = self.marionette.find_element(By.TAG_NAME, "textarea") textarea.send_keys("foo") textarea.send_keys("bar") self.assertEqual("foobar", textarea.get_property("value"))