Path: blob/trunk/py/test/selenium/webdriver/common/interactions_tests.py
4005 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.wheel_input import ScrollOrigin25from selenium.webdriver.common.by import By26from selenium.webdriver.common.keys import Keys27from selenium.webdriver.support.ui import WebDriverWait282930def perform_drag_and_drop_with_mouse(driver, pages):31"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""32pages.load("draggableLists.html")33dragReporter = driver.find_element(By.ID, "dragging_reports")34toDrag = driver.find_element(By.ID, "rightitem-3")35dragInto = driver.find_element(By.ID, "sortable1")3637holdItem = ActionChains(driver).click_and_hold(toDrag)38moveToSpecificItem = ActionChains(driver).move_to_element(driver.find_element(By.ID, "leftitem-4"))39moveToOtherList = ActionChains(driver).move_to_element(dragInto)40drop = ActionChains(driver).release(dragInto)41assert "Nothing happened." == dragReporter.text4243holdItem.perform()44moveToSpecificItem.perform()45moveToOtherList.perform()46assert "Nothing happened. DragOut" == dragReporter.text4748drop.perform()495051@pytest.mark.xfail_safari52def test_dragging_element_with_mouse_moves_it_to_another_list(driver, pages):53"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""54perform_drag_and_drop_with_mouse(driver, pages)55dragInto = driver.find_element(By.ID, "sortable1")56assert 6 == len(dragInto.find_elements(By.TAG_NAME, "li"))575859@pytest.mark.xfail_safari60def test_dragging_element_with_mouse_fires_events(driver, pages):61"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""62perform_drag_and_drop_with_mouse(driver, pages)63dragReporter = driver.find_element(By.ID, "dragging_reports")64assert "Nothing happened. DragOut DropIn RightItem 3" == dragReporter.text656667def _is_element_available(driver, id):68"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""69try:70driver.find_element(By.ID, id)71return True72except Exception:73return False747576@pytest.mark.xfail_safari77def test_drag_and_drop(driver, pages):78"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""79element_available_timeout = 1580wait = WebDriverWait(driver, element_available_timeout)81pages.load("droppableItems.html")82wait.until(lambda dr: _is_element_available(driver, "draggable"))8384if not _is_element_available(driver, "draggable"):85raise AssertionError("Could not find draggable element after 15 seconds.")8687toDrag = driver.find_element(By.ID, "draggable")88dropInto = driver.find_element(By.ID, "droppable")8990holdDrag = ActionChains(driver).click_and_hold(toDrag)91move = ActionChains(driver).move_to_element(dropInto)92drop = ActionChains(driver).release(dropInto)9394holdDrag.perform()95move.perform()96drop.perform()9798dropInto = driver.find_element(By.ID, "droppable")99text = dropInto.find_element(By.TAG_NAME, "p").text100assert "Dropped!" == text101102103@pytest.mark.xfail_safari104def test_double_click(driver, pages):105"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""106pages.load("javascriptPage.html")107toDoubleClick = driver.find_element(By.ID, "doubleClickField")108109dblClick = ActionChains(driver).double_click(toDoubleClick)110111dblClick.perform()112assert "DoubleClicked" == toDoubleClick.get_attribute("value")113114115def test_context_click(driver, pages):116"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""117pages.load("javascriptPage.html")118toContextClick = driver.find_element(By.ID, "doubleClickField")119120contextClick = ActionChains(driver).context_click(toContextClick)121122contextClick.perform()123assert "ContextClicked" == toContextClick.get_attribute("value")124125126def test_move_and_click(driver, pages):127"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""128pages.load("javascriptPage.html")129toClick = driver.find_element(By.ID, "clickField")130131click = ActionChains(driver).move_to_element(toClick).click()132133click.perform()134assert "Clicked" == toClick.get_attribute("value")135136137def test_cannot_move_to_anull_locator(driver, pages):138"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""139pages.load("javascriptPage.html")140141with pytest.raises(AttributeError):142move = ActionChains(driver).move_to_element(None)143move.perform()144145146@pytest.mark.xfail_safari147def test_clicking_on_form_elements(driver, pages):148"""Copied from org.openqa.selenium.interactions.CombinedInputActionsTest."""149pages.load("formSelectionPage.html")150options = driver.find_elements(By.TAG_NAME, "option")151selectThreeOptions = (152ActionChains(driver).click(options[1]).key_down(Keys.SHIFT).click(options[3]).key_up(Keys.SHIFT)153)154selectThreeOptions.perform()155156showButton = driver.find_element(By.NAME, "showselected")157showButton.click()158159resultElement = driver.find_element(By.ID, "result")160assert "roquefort parmigiano cheddar" == resultElement.text161162163@pytest.mark.xfail_firefox164@pytest.mark.xfail_safari165def test_selecting_multiple_items(driver, pages):166"""Copied from org.openqa.selenium.interactions.CombinedInputActionsTest."""167pages.load("selectableItems.html")168reportingElement = driver.find_element(By.ID, "infodiv")169assert "no info" == reportingElement.text170171listItems = driver.find_elements(By.TAG_NAME, "li")172selectThreeItems = (173ActionChains(driver)174.key_down(Keys.CONTROL)175.click(listItems[1])176.click(listItems[3])177.click(listItems[5])178.key_up(Keys.CONTROL)179)180selectThreeItems.perform()181182assert "#item2 #item4 #item6" == reportingElement.text183184# Now click on another element, make sure that's the only one selected.185actionsBuilder = ActionChains(driver)186actionsBuilder.click(listItems[6]).perform()187assert "#item7" == reportingElement.text188189190@pytest.mark.xfail_safari191def test_sending_keys_to_active_element_with_modifier(driver, pages):192pages.load("formPage.html")193e = driver.find_element(By.ID, "working")194e.click()195196ActionChains(driver).key_down(Keys.SHIFT).send_keys("abc").key_up(Keys.SHIFT).perform()197198assert "ABC" == e.get_attribute("value")199200201def test_sending_keys_to_element(driver, pages):202pages.load("formPage.html")203e = driver.find_element(By.ID, "working")204205ActionChains(driver).send_keys_to_element(e, "abc").perform()206207assert "abc" == e.get_attribute("value")208209210def test_can_send_keys_between_clicks(driver, pages):211"""Ensure W3C sends correct pause count to other input devices."""212pages.load("javascriptPage.html")213keyup = driver.find_element(By.ID, "keyUp")214keydown = driver.find_element(By.ID, "keyDown")215ActionChains(driver).click(keyup).send_keys("foobar").click(keydown).perform()216217assert "foobar" == keyup.get_attribute("value")218219220def test_can_reset_interactions(driver):221actions = ActionChains(driver)222actions.click()223actions.key_down("A")224assert all(len(device.actions) > 0 for device in actions.w3c_actions.devices if device.type != interaction.WHEEL)225226actions.reset_actions()227228assert all(len(device.actions) == 0 for device in actions.w3c_actions.devices)229230231def test_can_pause(driver, pages):232from time import time233234pages.load("javascriptPage.html")235236pause_time = 2237toClick = driver.find_element(By.ID, "clickField")238toDoubleClick = driver.find_element(By.ID, "doubleClickField")239240pause = ActionChains(driver).click(toClick).pause(pause_time).click(toDoubleClick)241242start = time()243pause.perform()244end = time()245246assert pause_time < end - start247assert "Clicked" == toClick.get_attribute("value")248assert "Clicked" == toDoubleClick.get_attribute("value")249250251@pytest.mark.xfail_firefox252@pytest.mark.xfail_remote253@pytest.mark.xfail_safari254def test_can_scroll_to_element(driver, pages):255pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")256iframe = driver.find_element(By.TAG_NAME, "iframe")257258assert not _in_viewport(driver, iframe)259260ActionChains(driver).scroll_to_element(iframe).perform()261262assert _in_viewport(driver, iframe)263264265@pytest.mark.xfail_firefox266@pytest.mark.xfail_remote267@pytest.mark.xfail_safari268def test_can_scroll_from_element_by_amount(driver, pages):269pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")270iframe = driver.find_element(By.TAG_NAME, "iframe")271scroll_origin = ScrollOrigin.from_element(iframe)272273ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()274275driver.switch_to.frame(iframe)276checkbox = driver.find_element(By.NAME, "scroll_checkbox")277assert _in_viewport(driver, checkbox)278279280@pytest.mark.xfail_firefox281@pytest.mark.xfail_remote282@pytest.mark.xfail_safari283def test_can_scroll_from_element_with_offset_by_amount(driver, pages):284pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")285footer = driver.find_element(By.TAG_NAME, "footer")286scroll_origin = ScrollOrigin.from_element(footer, 0, -50)287288ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()289290iframe = driver.find_element(By.TAG_NAME, "iframe")291driver.switch_to.frame(iframe)292checkbox = driver.find_element(By.NAME, "scroll_checkbox")293assert _in_viewport(driver, checkbox)294295296def test_errors_when_element_offset_not_in_viewport(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)300301with pytest.raises(MoveTargetOutOfBoundsException):302ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()303304305@pytest.mark.xfail_firefox306@pytest.mark.xfail_remote307def test_can_scroll_from_viewport_by_amount(driver, pages):308pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")309footer = driver.find_element(By.TAG_NAME, "footer")310delta_y = footer.rect["y"]311312ActionChains(driver).scroll_by_amount(0, delta_y).pause(0.2).perform()313314assert _in_viewport(driver, footer)315316317@pytest.mark.xfail_safari318def test_can_scroll_from_viewport_with_offset_by_amount(driver, pages):319pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")320scroll_origin = ScrollOrigin.from_viewport(10, 10)321322ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()323324iframe = driver.find_element(By.TAG_NAME, "iframe")325driver.switch_to.frame(iframe)326checkbox = driver.find_element(By.NAME, "scroll_checkbox")327assert _in_viewport(driver, checkbox)328329330def test_errors_when_origin_offset_not_in_viewport(driver, pages):331pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")332scroll_origin = ScrollOrigin.from_viewport(-10, -10)333334with pytest.raises(MoveTargetOutOfBoundsException):335ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()336337338def _get_events(driver):339"""Return list of key events recorded in the test_keys_page fixture."""340events = driver.execute_script("return allEvents.events;") or []341# `key` values in `allEvents` may be escaped (see `escapeSurrogateHalf` in342# test_keys_wdspec.html), so this converts them back into unicode literals.343for e in events:344# example: turn "U+d83d" (6 chars) into u"\ud83d" (1 char)345if "key" in e and e["key"].startswith("U+"):346key = e["key"]347hex_suffix = key[key.index("+") + 1 :]348e["key"] = chr(int(hex_suffix, 16))349350# WebKit sets code as 'Unidentified' for unidentified key codes, but351# tests expect ''.352if "code" in e and e["code"] == "Unidentified":353e["code"] = ""354return events355356357def _in_viewport(driver, element):358script = (359"for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"360"e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"361"return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"362"window.pageYOffset&&t+o>window.pageXOffset"363)364return driver.execute_script(script, element)365366367