Path: blob/trunk/py/test/selenium/webdriver/common/interactions_tests.py
1865 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"""212For W3C, ensures that the correct number of pauses are given to the other213input device.214"""215pages.load("javascriptPage.html")216keyup = driver.find_element(By.ID, "keyUp")217keydown = driver.find_element(By.ID, "keyDown")218ActionChains(driver).click(keyup).send_keys("foobar").click(keydown).perform()219220assert "foobar" == keyup.get_attribute("value")221222223def test_can_reset_interactions(driver):224actions = ActionChains(driver)225actions.click()226actions.key_down("A")227assert all(len(device.actions) > 0 for device in actions.w3c_actions.devices if device.type != interaction.WHEEL)228229actions.reset_actions()230231assert all(len(device.actions) == 0 for device in actions.w3c_actions.devices)232233234def test_can_pause(driver, pages):235from time import time236237pages.load("javascriptPage.html")238239pause_time = 2240toClick = driver.find_element(By.ID, "clickField")241toDoubleClick = driver.find_element(By.ID, "doubleClickField")242243pause = ActionChains(driver).click(toClick).pause(pause_time).click(toDoubleClick)244245start = time()246pause.perform()247end = time()248249assert pause_time < end - start250assert "Clicked" == toClick.get_attribute("value")251assert "Clicked" == toDoubleClick.get_attribute("value")252253254@pytest.mark.xfail_firefox255@pytest.mark.xfail_remote256@pytest.mark.xfail_safari257def test_can_scroll_to_element(driver, pages):258pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")259iframe = driver.find_element(By.TAG_NAME, "iframe")260261assert not _in_viewport(driver, iframe)262263ActionChains(driver).scroll_to_element(iframe).perform()264265assert _in_viewport(driver, iframe)266267268@pytest.mark.xfail_firefox269@pytest.mark.xfail_remote270@pytest.mark.xfail_safari271def test_can_scroll_from_element_by_amount(driver, pages):272pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")273iframe = driver.find_element(By.TAG_NAME, "iframe")274scroll_origin = ScrollOrigin.from_element(iframe)275276ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()277278driver.switch_to.frame(iframe)279checkbox = driver.find_element(By.NAME, "scroll_checkbox")280assert _in_viewport(driver, checkbox)281282283@pytest.mark.xfail_firefox284@pytest.mark.xfail_remote285@pytest.mark.xfail_safari286def test_can_scroll_from_element_with_offset_by_amount(driver, pages):287pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")288footer = driver.find_element(By.TAG_NAME, "footer")289scroll_origin = ScrollOrigin.from_element(footer, 0, -50)290291ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()292293iframe = driver.find_element(By.TAG_NAME, "iframe")294driver.switch_to.frame(iframe)295checkbox = driver.find_element(By.NAME, "scroll_checkbox")296assert _in_viewport(driver, checkbox)297298299def test_errors_when_element_offset_not_in_viewport(driver, pages):300pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")301footer = driver.find_element(By.TAG_NAME, "footer")302scroll_origin = ScrollOrigin.from_element(footer, 0, 50)303304with pytest.raises(MoveTargetOutOfBoundsException):305ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()306307308@pytest.mark.xfail_firefox309@pytest.mark.xfail_remote310def test_can_scroll_from_viewport_by_amount(driver, pages):311pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")312footer = driver.find_element(By.TAG_NAME, "footer")313delta_y = footer.rect["y"]314315ActionChains(driver).scroll_by_amount(0, delta_y).pause(0.2).perform()316317assert _in_viewport(driver, footer)318319320@pytest.mark.xfail_safari321def test_can_scroll_from_viewport_with_offset_by_amount(driver, pages):322pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")323scroll_origin = ScrollOrigin.from_viewport(10, 10)324325ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()326327iframe = driver.find_element(By.TAG_NAME, "iframe")328driver.switch_to.frame(iframe)329checkbox = driver.find_element(By.NAME, "scroll_checkbox")330assert _in_viewport(driver, checkbox)331332333def test_errors_when_origin_offset_not_in_viewport(driver, pages):334pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")335scroll_origin = ScrollOrigin.from_viewport(-10, -10)336337with pytest.raises(MoveTargetOutOfBoundsException):338ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform()339340341def _get_events(driver):342"""Return list of key events recorded in the test_keys_page fixture."""343events = driver.execute_script("return allEvents.events;") or []344# `key` values in `allEvents` may be escaped (see `escapeSurrogateHalf` in345# test_keys_wdspec.html), so this converts them back into unicode literals.346for e in events:347# example: turn "U+d83d" (6 chars) into u"\ud83d" (1 char)348if "key" in e and e["key"].startswith("U+"):349key = e["key"]350hex_suffix = key[key.index("+") + 1 :]351e["key"] = chr(int(hex_suffix, 16))352353# WebKit sets code as 'Unidentified' for unidentified key codes, but354# tests expect ''.355if "code" in e and e["code"] == "Unidentified":356e["code"] = ""357return events358359360def _in_viewport(driver, element):361script = (362"for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"363"e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"364"return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"365"window.pageYOffset&&t+o>window.pageXOffset"366)367return driver.execute_script(script, element)368369370