Path: blob/trunk/py/test/selenium/webdriver/common/interactions_with_device_tests.py
4012 views
# Licensed to the Software Freedom Conservancy (SFC) under one1# or more contributor license agreements. See the NOTICE file2# distributed with this work for additional information3# regarding copyright ownership. The SFC licenses this file4# to you under the Apache License, Version 2.0 (the5# "License"); you may not use this file except in compliance6# with the License. You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing,11# software distributed under the License is distributed on an12# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13# KIND, either express or implied. See the License for the14# specific language governing permissions and limitations15# under the License.1617"""Tests for advanced user interactions."""1819import pytest2021from selenium.common.exceptions import MoveTargetOutOfBoundsException22from selenium.webdriver.common.action_chains import ActionChains23from selenium.webdriver.common.actions import interaction24from selenium.webdriver.common.actions.key_input import KeyInput25from selenium.webdriver.common.actions.pointer_input import PointerInput26from selenium.webdriver.common.actions.wheel_input import ScrollOrigin, WheelInput27from selenium.webdriver.common.by import By28from selenium.webdriver.common.keys import Keys29from selenium.webdriver.support.ui import WebDriverWait303132def _is_element_available(driver, id):33"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""34try:35driver.find_element(By.ID, id)36return True37except Exception:38return False394041@pytest.mark.xfail_safari42@pytest.mark.xfail_chrome43def test_drag_and_drop_with_pointer(driver, pages):44"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""45element_available_timeout = 1546wait = WebDriverWait(driver, element_available_timeout)47pages.load("droppableItems.html")48wait.until(lambda dr: _is_element_available(driver, "draggable"))4950if not _is_element_available(driver, "draggable"):51raise AssertionError("Could not find draggable element after 15 seconds.")5253toDrag = driver.find_element(By.ID, "draggable")54dropInto = driver.find_element(By.ID, "droppable")5556mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")5758holdDrag = ActionChains(driver, devices=[mouse]).click_and_hold(toDrag)59move = ActionChains(driver, devices=[mouse]).move_to_element(dropInto)60drop = ActionChains(driver, devices=[mouse]).release(dropInto)6162holdDrag.perform()63move.perform()64drop.perform()6566dropInto = driver.find_element(By.ID, "droppable")67text = dropInto.find_element(By.TAG_NAME, "p").text68assert "Dropped!" == text697071@pytest.mark.xfail_safari72def test_double_click_with_pointer(driver, pages):73"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""74pages.load("javascriptPage.html")75toDoubleClick = driver.find_element(By.ID, "doubleClickField")7677mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")7879dblClick = ActionChains(driver, devices=[mouse]).double_click(toDoubleClick)80dblClick.perform()81assert "DoubleClicked" == toDoubleClick.get_attribute("value")828384def test_context_click_with_pointer(driver, pages):85"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""86pages.load("javascriptPage.html")87toContextClick = driver.find_element(By.ID, "doubleClickField")8889mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")9091contextClick = ActionChains(driver, devices=[mouse]).context_click(toContextClick)92contextClick.perform()93assert "ContextClicked" == toContextClick.get_attribute("value")949596def test_move_and_click_with_pointer(driver, pages):97"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""98pages.load("javascriptPage.html")99toClick = driver.find_element(By.ID, "clickField")100101mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")102103click = ActionChains(driver, devices=[mouse]).move_to_element(toClick).click()104click.perform()105assert "Clicked" == toClick.get_attribute("value")106107108def test_cannot_move_to_anull_locator_with_pointer(driver, pages):109"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""110pages.load("javascriptPage.html")111mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")112113with pytest.raises(AttributeError):114move = ActionChains(driver, devices=[mouse]).move_to_element(None)115move.perform()116117118@pytest.mark.xfail_safari119def test_clicking_on_form_elements_with_pointer(driver, pages):120"""Copied from org.openqa.selenium.interactions.CombinedInputActionsTest."""121pages.load("formSelectionPage.html")122options = driver.find_elements(By.TAG_NAME, "option")123mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")124125selectThreeOptions = (126ActionChains(driver, devices=[mouse])127.click(options[1])128.key_down(Keys.SHIFT)129.click(options[3])130.key_up(Keys.SHIFT)131)132selectThreeOptions.perform()133134showButton = driver.find_element(By.NAME, "showselected")135showButton.click()136137resultElement = driver.find_element(By.ID, "result")138assert "roquefort parmigiano cheddar" == resultElement.text139140141@pytest.mark.xfail_firefox142@pytest.mark.xfail_safari143def test_selecting_multiple_items_with_devices(driver, pages):144"""Copied from org.openqa.selenium.interactions.CombinedInputActionsTest."""145pages.load("selectableItems.html")146reportingElement = driver.find_element(By.ID, "infodiv")147assert "no info" == reportingElement.text148149mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")150key_board = KeyInput("test keyboard")151152listItems = driver.find_elements(By.TAG_NAME, "li")153selectThreeItems = (154ActionChains(driver, devices=[mouse, key_board])155.key_down(Keys.CONTROL)156.click(listItems[1])157.click(listItems[3])158.click(listItems[5])159.key_up(Keys.CONTROL)160)161selectThreeItems.perform()162163assert "#item2 #item4 #item6" == reportingElement.text164165# Now click on another element, make sure that's the only one selected.166actionsBuilder = ActionChains(driver)167actionsBuilder.click(listItems[6]).perform()168assert "#item7" == reportingElement.text169170171@pytest.mark.xfail_safari172def test_sending_keys_to_active_element_with_modifier_with_keyboard(driver, pages):173pages.load("formPage.html")174e = driver.find_element(By.ID, "working")175e.click()176177key_board = KeyInput("test keyboard")178179ActionChains(driver, devices=[key_board]).key_down(Keys.SHIFT).send_keys("abc").key_up(Keys.SHIFT).perform()180181assert "ABC" == e.get_attribute("value")182183184def test_sending_keys_to_element_with_keyboard(driver, pages):185pages.load("formPage.html")186e = driver.find_element(By.ID, "working")187188key_board = KeyInput("test keyboard")189190ActionChains(driver, devices=[key_board]).send_keys_to_element(e, "abc").perform()191192assert "abc" == e.get_attribute("value")193194195def test_can_send_keys_between_clicks_with_keyboard(driver, pages):196"""Ensure W3C sends correct pause count to other input devices."""197pages.load("javascriptPage.html")198keyup = driver.find_element(By.ID, "keyUp")199keydown = driver.find_element(By.ID, "keyDown")200201key_board = KeyInput("test keyboard")202203ActionChains(driver, devices=[key_board]).click(keyup).send_keys("foobar").click(keydown).perform()204205assert "foobar" == keyup.get_attribute("value")206207208def test_can_reset_interactions_with_devices(driver):209mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")210key_board = KeyInput("test keyboard")211actions = ActionChains(driver, devices=[mouse, key_board])212actions.click()213actions.key_down("A")214215assert all(len(device.actions) >= 0 for device in actions.w3c_actions.devices if device.type != interaction.WHEEL)216217actions.reset_actions()218219assert all(len(device.actions) == 0 for device in actions.w3c_actions.devices)220221222def test_can_pause_with_pointer(driver, pages):223from time import time224225pages.load("javascriptPage.html")226227pause_time = 2228toClick = driver.find_element(By.ID, "clickField")229toDoubleClick = driver.find_element(By.ID, "doubleClickField")230231mouse = PointerInput(interaction.POINTER_MOUSE, "test mouse")232233pause = ActionChains(driver, devices=[mouse]).click(toClick).pause(pause_time).click(toDoubleClick)234235start = time()236pause.perform()237end = time()238239assert pause_time < end - start240assert "Clicked" == toClick.get_attribute("value")241assert "Clicked" == toDoubleClick.get_attribute("value")242243244@pytest.mark.xfail_firefox245@pytest.mark.xfail_remote246@pytest.mark.xfail_safari247def test_can_scroll_to_element_with_wheel(driver, pages):248pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")249iframe = driver.find_element(By.TAG_NAME, "iframe")250251assert not _in_viewport(driver, iframe)252253wheel = WheelInput("test wheel")254255ActionChains(driver, devices=[wheel]).scroll_to_element(iframe).perform()256257assert _in_viewport(driver, iframe)258259260@pytest.mark.xfail_firefox261@pytest.mark.xfail_remote262@pytest.mark.xfail_safari263def test_can_scroll_from_element_by_amount_with_wheel(driver, pages):264pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")265iframe = driver.find_element(By.TAG_NAME, "iframe")266scroll_origin = ScrollOrigin.from_element(iframe)267268wheel = WheelInput("test wheel")269270ActionChains(driver, devices=[wheel]).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()271272driver.switch_to.frame(iframe)273checkbox = driver.find_element(By.NAME, "scroll_checkbox")274assert _in_viewport(driver, checkbox)275276277@pytest.mark.xfail_firefox278@pytest.mark.xfail_remote279@pytest.mark.xfail_safari280def test_can_scroll_from_element_with_offset_by_amount_with_wheel(driver, pages):281pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")282footer = driver.find_element(By.TAG_NAME, "footer")283scroll_origin = ScrollOrigin.from_element(footer, 0, -50)284285wheel = WheelInput("test wheel")286287ActionChains(driver, devices=[wheel]).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()288289iframe = driver.find_element(By.TAG_NAME, "iframe")290driver.switch_to.frame(iframe)291checkbox = driver.find_element(By.NAME, "scroll_checkbox")292assert _in_viewport(driver, checkbox)293294295@pytest.mark.xfail_firefox296def test_errors_when_element_offset_not_in_viewport_with_wheel(driver, pages):297pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")298footer = driver.find_element(By.TAG_NAME, "footer")299scroll_origin = ScrollOrigin.from_element(footer, 0, 50)300301wheel = WheelInput("test wheel")302303with pytest.raises(MoveTargetOutOfBoundsException):304ActionChains(driver, devices=[wheel]).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()305306307@pytest.mark.xfail_firefox308@pytest.mark.xfail_remote309def test_can_scroll_from_viewport_by_amount_with_wheel(driver, pages):310pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")311footer = driver.find_element(By.TAG_NAME, "footer")312delta_y = footer.rect["y"]313314wheel = WheelInput("test wheel")315316ActionChains(driver, devices=[wheel]).scroll_by_amount(0, delta_y).pause(0.2).perform()317318assert _in_viewport(driver, footer)319320321@pytest.mark.xfail_firefox322@pytest.mark.xfail_safari323def test_can_scroll_from_viewport_with_offset_by_amount_with_wheel(driver, pages):324pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")325scroll_origin = ScrollOrigin.from_viewport(10, 10)326327wheel = WheelInput("test wheel")328329ActionChains(driver, devices=[wheel]).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()330331iframe = driver.find_element(By.TAG_NAME, "iframe")332driver.switch_to.frame(iframe)333checkbox = driver.find_element(By.NAME, "scroll_checkbox")334assert _in_viewport(driver, checkbox)335336337@pytest.mark.xfail_firefox338def test_errors_when_origin_offset_not_in_viewport_with_wheel(driver, pages):339pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")340scroll_origin = ScrollOrigin.from_viewport(-10, -10)341342wheel = WheelInput("test wheel")343344with pytest.raises(MoveTargetOutOfBoundsException):345ActionChains(driver, devices=[wheel]).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()346347348def _get_events(driver):349"""Return list of key events recorded in the test_keys_page fixture."""350events = driver.execute_script("return allEvents.events;") or []351# `key` values in `allEvents` may be escaped (see `escapeSurrogateHalf` in352# test_keys_wdspec.html), so this converts them back into unicode literals.353for e in events:354# example: turn "U+d83d" (6 chars) into u"\ud83d" (1 char)355if "key" in e and e["key"].startswith("U+"):356key = e["key"]357hex_suffix = key[key.index("+") + 1 :]358e["key"] = chr(int(hex_suffix, 16))359360# WebKit sets code as 'Unidentified' for unidentified key codes, but361# tests expect ''.362if "code" in e and e["code"] == "Unidentified":363e["code"] = ""364return events365366367def _in_viewport(driver, element):368script = (369"for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"370"e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"371"return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"372"window.pageYOffset&&t+o>window.pageXOffset"373)374return driver.execute_script(script, element)375376377