| #!/usr/bin/env python |
| # Copyright 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """End to end tests for ChromeDriver.""" |
| |
| # Note that to run Android tests you must have the following line in |
| # .gclient (in the parent directory of src): target_os = [ 'android' ] |
| # to get the appropriate adb version for ChromeDriver. |
| # TODO (crbug.com/857239): Remove above comment when adb version |
| # is updated in Devil. |
| |
| import base64 |
| import json |
| import math |
| import optparse |
| import os |
| import re |
| import shutil |
| import socket |
| import subprocess |
| import sys |
| import tempfile |
| import threading |
| import time |
| import unittest |
| import urllib |
| import urllib2 |
| import uuid |
| |
| |
| _THIS_DIR = os.path.abspath(os.path.dirname(__file__)) |
| _PARENT_DIR = os.path.join(_THIS_DIR, os.pardir) |
| _CLIENT_DIR = os.path.join(_PARENT_DIR, "client") |
| _SERVER_DIR = os.path.join(_PARENT_DIR, "server") |
| _TEST_DIR = os.path.join(_PARENT_DIR, "test") |
| |
| sys.path.insert(1, _PARENT_DIR) |
| import chrome_paths |
| import util |
| sys.path.remove(_PARENT_DIR) |
| |
| sys.path.insert(1, _CLIENT_DIR) |
| import chromedriver |
| import webelement |
| sys.path.remove(_CLIENT_DIR) |
| |
| sys.path.insert(1, _SERVER_DIR) |
| import server |
| sys.path.remove(_SERVER_DIR) |
| |
| sys.path.insert(1, _TEST_DIR) |
| import unittest_util |
| import webserver |
| sys.path.remove(_TEST_DIR) |
| |
| |
| _TEST_DATA_DIR = os.path.join(chrome_paths.GetTestData(), 'chromedriver') |
| |
| if util.IsLinux(): |
| sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'third_party', |
| 'catapult', 'devil')) |
| from devil.android import device_utils |
| from devil.android import forwarder |
| |
| sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android')) |
| import devil_chromium |
| from pylib import constants |
| |
| |
| _NEGATIVE_FILTER = [ |
| # This test is too flaky on the bots, but seems to run perfectly fine |
| # on developer workstations. |
| 'ChromeDriverTest.testEmulateNetworkConditionsNameSpeed', |
| 'ChromeDriverTest.testEmulateNetworkConditionsSpeed', |
| # crbug.com/469947 |
| 'ChromeDriverTest.testTouchPinch', |
| # TODO: re-enable tests when DevTools supports ScreenOrientation commands. |
| 'ChromeDriverAndroidTest.testScreenOrientation', |
| 'ChromeDriverAndroidTest.testMultipleScreenOrientationChanges', |
| 'ChromeDriverAndroidTest.testDeleteScreenOrientationManual', |
| 'ChromeDriverAndroidTest.testScreenOrientationAcrossMultipleTabs', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=833 |
| 'ChromeDriverTest.testAlertOnNewWindow', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2532 |
| 'ChromeDriverPageLoadTimeoutTest.testRefreshWithPageLoadTimeout', |
| ] |
| |
| |
| _OS_SPECIFIC_FILTER = {} |
| _OS_SPECIFIC_FILTER['win'] = [ |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=299 |
| 'ChromeLogPathCapabilityTest.testChromeLogPath', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1367 |
| 'ChromeExtensionsCapabilityTest.testWaitsForExtensionToLoad', |
| # https://bugs.chromium.org/p/chromium/issues/detail?id=946704 |
| 'ChromeDownloadDirTest.testFileDownloadWithClick', |
| 'ChromeDriverTest.testBackNavigationAfterClickElement', |
| 'ChromeDriverTest.testCanClickInIframes', |
| 'ChromeDriverTest.testClickElementAfterNavigation', |
| 'ChromeDriverTest.testCloseWindow', |
| 'ChromeDriverTest.testCloseWindowUsingJavascript', |
| 'ChromeDriverTest.testGetLogOnClosedWindow', |
| 'ChromeDriverTest.testGetWindowHandles', |
| 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', |
| 'ChromeDriverTest.testSwitchToWindow', |
| ] |
| _OS_SPECIFIC_FILTER['linux'] = [ |
| # https://bugs.chromium.org/p/chromium/issues/detail?id=932073 |
| 'ChromeExtensionsCapabilityTest.testWaitsForExtensionToLoad', |
| ] |
| _OS_SPECIFIC_FILTER['mac'] = [ |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1927 |
| 'MobileEmulationCapabilityTest.testTapElement', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2579 |
| 'ChromeDriverTest.testTakeElementScreenshot', |
| 'ChromeDriverTest.testTakeElementScreenshotInIframe', |
| # https://bugs.chromium.org/p/chromium/issues/detail?id=946023 |
| 'ChromeDriverTest.testWindowFullScreen', |
| ] |
| |
| _DESKTOP_NEGATIVE_FILTER = [ |
| # Desktop doesn't support touch (without --touch-events). |
| 'ChromeDriverTestLegacy.testTouchSingleTapElement', |
| 'ChromeDriverTest.testTouchDownMoveUpElement', |
| 'ChromeDriverTestLegacy.testTouchScrollElement', |
| 'ChromeDriverTestLegacy.testTouchDoubleTapElement', |
| 'ChromeDriverTestLegacy.testTouchLongPressElement', |
| 'ChromeDriverTest.testTouchFlickElement', |
| 'ChromeDriverTest.testTouchPinch', |
| 'ChromeDriverAndroidTest.*', |
| ] |
| |
| _INTEGRATION_NEGATIVE_FILTER = [ |
| # The following test is flaky on Windows and Mac. |
| 'ChromeDownloadDirTest.testDownloadDirectoryOverridesExistingPreferences', |
| # ChromeDriverLogTest tests an internal ChromeDriver feature, not needed |
| # for integration test. |
| 'ChromeDriverLogTest.*', |
| # ChromeDriverPageLoadTimeoutTest is flaky, particularly on Mac. |
| 'ChromeDriverPageLoadTimeoutTest.*', |
| # Some trivial test cases that provide no additional value beyond what are |
| # already tested by other test cases. |
| 'ChromeDriverTest.testGetCurrentWindowHandle', |
| 'ChromeDriverTest.testStartStop', |
| 'ChromeDriverTest.testSendCommand*', |
| # https://crbug.com/867511 |
| 'ChromeDriverTest.testWindowMaximize', |
| # LaunchApp is an obsolete API. |
| 'ChromeExtensionsCapabilityTest.testCanLaunchApp', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2278 |
| # The following test uses the obsolete LaunchApp API, and is thus excluded. |
| # TODO(johnchen@chromium.org): Investigate feasibility of re-writing the |
| # test case without using LaunchApp. |
| 'ChromeExtensionsCapabilityTest.testCanInspectBackgroundPage', |
| # PerfTest takes a long time, requires extra setup, and adds little value |
| # to integration testing. |
| 'PerfTest.*', |
| # HeadlessInvalidCertificateTest is sometimes flaky. |
| 'HeadlessInvalidCertificateTest.*', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2277 |
| # RemoteBrowserTest requires extra setup. TODO(johnchen@chromium.org): |
| # Modify the test so it runs correctly as isolated test. |
| 'RemoteBrowserTest.*', |
| # Flaky: https://crbug.com/899919 |
| 'SessionHandlingTest.testGetSessions', |
| # Flaky due to occasional timeout in starting Chrome |
| 'ZChromeStartRetryCountTest.testChromeStartRetryCount', |
| ] |
| |
| |
| def _GetDesktopNegativeFilter(): |
| filter = _NEGATIVE_FILTER + _DESKTOP_NEGATIVE_FILTER |
| os = util.GetPlatformName() |
| if os in _OS_SPECIFIC_FILTER: |
| filter += _OS_SPECIFIC_FILTER[os] |
| return filter |
| |
| _ANDROID_NEGATIVE_FILTER = {} |
| _ANDROID_NEGATIVE_FILTER['chrome'] = ( |
| _NEGATIVE_FILTER + [ |
| # Android doesn't support switches and extensions. |
| 'ChromeSwitchesCapabilityTest.*', |
| 'ChromeExtensionsCapabilityTest.*', |
| 'MobileEmulationCapabilityTest.*', |
| 'ChromeDownloadDirTest.*', |
| # https://crbug.com/274650 |
| 'ChromeDriverTest.testCloseWindow', |
| # Most window operations don't make sense on Android. |
| 'ChromeDriverTest.testWindowFullScreen', |
| 'ChromeDriverTest.testWindowPosition', |
| 'ChromeDriverTest.testWindowSize', |
| 'ChromeDriverTest.testWindowRect', |
| 'ChromeDriverTest.testWindowMaximize', |
| 'ChromeDriverTest.testWindowMinimize', |
| 'ChromeLogPathCapabilityTest.testChromeLogPath', |
| 'RemoteBrowserTest.*', |
| # Don't enable perf testing on Android yet. |
| 'PerfTest.*', |
| # Android doesn't support multiple sessions on one device. |
| 'SessionHandlingTest.testGetSessions', |
| # Android doesn't use the chrome://print dialog. |
| 'ChromeDriverTest.testCanSwitchToPrintPreviewDialog', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1175 |
| 'ChromeDriverTest.testChromeDriverSendLargeData', |
| # Chrome 44+ for Android doesn't dispatch the dblclick event |
| 'ChromeDriverTest.testMouseDoubleClick', |
| # Page cannot be loaded from file:// URI in Android unless it |
| # is stored in device. |
| 'ChromeDriverTest.testCanClickAlertInIframes', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2081 |
| 'ChromeDriverTest.testCloseWindowUsingJavascript', |
| # Android doesn't support headless mode |
| 'HeadlessInvalidCertificateTest.*', |
| # Tests of the desktop Chrome launch process. |
| 'LaunchDesktopTest.*', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2737 |
| 'ChromeDriverTest.testTakeElementScreenshot', |
| 'ChromeDriverTest.testTakeElementScreenshotInIframe', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2786 |
| 'ChromeDriverTest.testActionsTouchTap', |
| 'ChromeDriverTest.testTouchDownMoveUpElement', |
| 'ChromeDriverTest.testTouchFlickElement', |
| |
| ] |
| ) |
| _ANDROID_NEGATIVE_FILTER['chrome_stable'] = ( |
| _ANDROID_NEGATIVE_FILTER['chrome'] + [ |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2350 |
| 'ChromeDriverTest.testSlowIFrame', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2503 |
| 'ChromeDriverTest.testGetLogOnClosedWindow', |
| 'ChromeDriverTest.testGetWindowHandles', |
| 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', |
| 'ChromeDriverTest.testSwitchToWindow', |
| # Feature not yet supported in this version |
| 'ChromeDriverTest.testGenerateTestReport', |
| ] |
| ) |
| _ANDROID_NEGATIVE_FILTER['chrome_beta'] = ( |
| _ANDROID_NEGATIVE_FILTER['chrome'] + [ |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2503 |
| 'ChromeDriverTest.testGetLogOnClosedWindow', |
| 'ChromeDriverTest.testGetWindowHandles', |
| 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', |
| 'ChromeDriverTest.testSwitchToWindow', |
| # Feature not yet supported in this version |
| 'ChromeDriverTest.testGenerateTestReport', |
| ] |
| ) |
| _ANDROID_NEGATIVE_FILTER['chromium'] = ( |
| _ANDROID_NEGATIVE_FILTER['chrome'] + [] |
| ) |
| _ANDROID_NEGATIVE_FILTER['chromedriver_webview_shell'] = ( |
| _ANDROID_NEGATIVE_FILTER['chrome_stable'] + [ |
| # WebView doesn't support emulating network conditions. |
| 'ChromeDriverTest.testEmulateNetworkConditions', |
| 'ChromeDriverTest.testEmulateNetworkConditionsNameSpeed', |
| 'ChromeDriverTest.testEmulateNetworkConditionsOffline', |
| 'ChromeDriverTest.testEmulateNetworkConditionsSpeed', |
| 'ChromeDriverTest.testEmulateNetworkConditionsName', |
| # WebView shell doesn't support popups or popup blocking. |
| 'ChromeDriverTest.testPopups', |
| 'ChromeDriverTest.testDontGoBackOrGoForward', |
| # ChromeDriver WebView shell doesn't support multiple tabs. |
| 'ChromeDriverTest.testCloseWindowUsingJavascript', |
| 'ChromeDriverTest.testGetWindowHandles', |
| 'ChromeDriverTest.testSwitchToWindow', |
| 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', |
| 'ChromeDriverTest.testGetLogOnClosedWindow', |
| # The WebView shell that we test against (on KitKat) does not perform |
| # cross-process navigations. |
| # TODO(samuong): reenable when it does. |
| 'ChromeDriverPageLoadTimeoutTest.testPageLoadTimeoutCrossDomain', |
| 'ChromeDriverPageLoadTimeoutTest.' |
| 'testHistoryNavigationWithPageLoadTimeout', |
| # Webview shell doesn't support Alerts. |
| 'ChromeDriverTest.testAlert', |
| 'ChromeDriverTest.testAlertOnNewWindow', |
| 'ChromeDesiredCapabilityTest.testUnexpectedAlertBehaviour', |
| 'ChromeDriverTest.testAlertHandlingOnPageUnload', |
| 'ChromeDriverTest.testClickElementAfterNavigation', |
| 'ChromeDriverTest.testGetLogOnWindowWithAlert', |
| 'ChromeDriverTest.testSendTextToAlert', |
| 'ChromeDriverTest.testUnexpectedAlertOpenExceptionMessage', |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2332 |
| 'ChromeDriverTestLegacy.testTouchScrollElement', |
| ] |
| ) |
| |
| |
| class ChromeDriverBaseTest(unittest.TestCase): |
| """Base class for testing chromedriver functionalities.""" |
| |
| def __init__(self, *args, **kwargs): |
| super(ChromeDriverBaseTest, self).__init__(*args, **kwargs) |
| self._drivers = [] |
| |
| def tearDown(self): |
| for driver in self._drivers: |
| try: |
| driver.Quit() |
| except: |
| pass |
| |
| def CreateDriver(self, server_url=None, download_dir=None, **kwargs): |
| if server_url is None: |
| server_url = _CHROMEDRIVER_SERVER_URL |
| |
| android_package = None |
| android_activity = None |
| android_process = None |
| if _ANDROID_PACKAGE_KEY: |
| android_package = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].package |
| if _ANDROID_PACKAGE_KEY == 'chromedriver_webview_shell': |
| android_activity = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].activity |
| android_process = '%s:main' % android_package |
| |
| driver = chromedriver.ChromeDriver(server_url, |
| chrome_binary=_CHROME_BINARY, |
| android_package=android_package, |
| android_activity=android_activity, |
| android_process=android_process, |
| download_dir=download_dir, |
| test_name=self.id(), |
| **kwargs) |
| self._drivers += [driver] |
| return driver |
| |
| def WaitForNewWindow(self, driver, old_handles, check_closed_windows=True): |
| """Wait for at least one new window to show up in 20 seconds. |
| |
| Args: |
| old_handles: Handles to all old windows before the new window is added. |
| check_closed_windows: If True, assert that no windows are closed before |
| the new window is added. |
| |
| Returns: |
| Handle to a new window. None if timeout. |
| """ |
| deadline = time.time() + 20 |
| while time.time() < deadline: |
| handles = driver.GetWindowHandles() |
| if check_closed_windows: |
| self.assertTrue(set(old_handles).issubset(handles)) |
| new_handles = set(handles).difference(set(old_handles)) |
| if len(new_handles) > 0: |
| return new_handles.pop() |
| time.sleep(0.01) |
| return None |
| |
| def WaitForCondition(self, predicate, timeout=5, timestep=0.1): |
| """Wait for a condition to become true. |
| |
| Args: |
| predicate: A function that returns a boolean value. |
| """ |
| deadline = time.time() + timeout |
| while time.time() < deadline: |
| if predicate(): |
| return True |
| time.sleep(timestep) |
| return False |
| |
| |
| class ChromeDriverBaseTestWithWebServer(ChromeDriverBaseTest): |
| |
| @staticmethod |
| def GlobalSetUp(): |
| ChromeDriverBaseTestWithWebServer._http_server = webserver.WebServer( |
| chrome_paths.GetTestData()) |
| |
| @staticmethod |
| def GlobalTearDown(): |
| ChromeDriverBaseTestWithWebServer._http_server.Shutdown() |
| |
| @staticmethod |
| def GetHttpUrlForFile(file_path): |
| return ChromeDriverBaseTestWithWebServer._http_server.GetUrl() + file_path |
| |
| |
| class ChromeDriverTest(ChromeDriverBaseTestWithWebServer): |
| """End to end tests for ChromeDriver.""" |
| |
| @staticmethod |
| def GlobalSetUp(): |
| ChromeDriverBaseTestWithWebServer.GlobalSetUp() |
| ChromeDriverTest._sync_server = webserver.SyncWebServer() |
| if _ANDROID_PACKAGE_KEY: |
| ChromeDriverTest._device = device_utils.DeviceUtils.HealthyDevices()[0] |
| http_host_port = ChromeDriverTest._http_server._server.server_port |
| sync_host_port = ChromeDriverTest._sync_server._server.server_port |
| forwarder.Forwarder.Map( |
| [(http_host_port, http_host_port), (sync_host_port, sync_host_port)], |
| ChromeDriverTest._device) |
| |
| @staticmethod |
| def GlobalTearDown(): |
| if _ANDROID_PACKAGE_KEY: |
| forwarder.Forwarder.UnmapAllDevicePorts(ChromeDriverTest._device) |
| ChromeDriverBaseTestWithWebServer.GlobalTearDown() |
| |
| def setUp(self): |
| self._driver = self.CreateDriver() |
| |
| def testStartStop(self): |
| pass |
| |
| def testLoadUrl(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| |
| def testGetCurrentWindowHandle(self): |
| self._driver.GetCurrentWindowHandle() |
| |
| def testCloseWindow(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| old_handles = self._driver.GetWindowHandles() |
| self._driver.FindElement('css selector', '#link').Click() |
| new_window_handle = self.WaitForNewWindow(self._driver, old_handles) |
| self.assertNotEqual(None, new_window_handle) |
| self._driver.SwitchToWindow(new_window_handle) |
| self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle()) |
| self.assertRaises(chromedriver.NoSuchElement, |
| self._driver.FindElement, 'css selector', '#link') |
| close_returned_handles = self._driver.CloseWindow() |
| self.assertRaises(chromedriver.NoSuchWindow, |
| self._driver.GetCurrentWindowHandle) |
| new_handles = self._driver.GetWindowHandles() |
| self.assertEquals(close_returned_handles, new_handles) |
| for old_handle in old_handles: |
| self.assertTrue(old_handle in new_handles) |
| for handle in new_handles: |
| self._driver.SwitchToWindow(handle) |
| self.assertEquals(handle, self._driver.GetCurrentWindowHandle()) |
| close_handles = self._driver.CloseWindow() |
| # CloseWindow quits the session if on the last window. |
| if handle is not new_handles[-1]: |
| from_get_window_handles = self._driver.GetWindowHandles() |
| self.assertEquals(close_handles, from_get_window_handles) |
| |
| def testCloseWindowUsingJavascript(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| old_handles = self._driver.GetWindowHandles() |
| self._driver.FindElement('css selector', '#link').Click() |
| new_window_handle = self.WaitForNewWindow(self._driver, old_handles) |
| self.assertNotEqual(None, new_window_handle) |
| self._driver.SwitchToWindow(new_window_handle) |
| self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle()) |
| self.assertRaises(chromedriver.NoSuchElement, |
| self._driver.FindElement, 'css selector', '#link') |
| self._driver.ExecuteScript('window.close()') |
| with self.assertRaises(chromedriver.NoSuchWindow): |
| self._driver.GetTitle() |
| |
| def testGetWindowHandles(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| old_handles = self._driver.GetWindowHandles() |
| self._driver.FindElement('css selector', '#link').Click() |
| self.assertNotEqual(None, self.WaitForNewWindow(self._driver, old_handles)) |
| |
| def testGetWindowHandlesInPresenceOfSharedWorker(self): |
| self._driver.Load( |
| self.GetHttpUrlForFile('/chromedriver/shared_worker.html')) |
| old_handles = self._driver.GetWindowHandles() |
| |
| def testSwitchToWindow(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| self.assertEquals( |
| 1, self._driver.ExecuteScript('window.name = "oldWindow"; return 1;')) |
| window1_handle = self._driver.GetCurrentWindowHandle() |
| old_handles = self._driver.GetWindowHandles() |
| self._driver.FindElement('css selector', '#link').Click() |
| new_window_handle = self.WaitForNewWindow(self._driver, old_handles) |
| self.assertNotEqual(None, new_window_handle) |
| self._driver.SwitchToWindow(new_window_handle) |
| self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle()) |
| self.assertRaises(chromedriver.NoSuchElement, |
| self._driver.FindElement, 'css selector', '#link') |
| self._driver.SwitchToWindow('oldWindow') |
| self.assertEquals(window1_handle, self._driver.GetCurrentWindowHandle()) |
| |
| def testEvaluateScript(self): |
| self.assertEquals(1, self._driver.ExecuteScript('return 1')) |
| self.assertEquals(None, self._driver.ExecuteScript('')) |
| |
| def testEvaluateScriptWithArgs(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| script = ('document.body.innerHTML = "<div>b</div><div>c</div>";' |
| 'return {stuff: document.querySelectorAll("div")};') |
| stuff = self._driver.ExecuteScript(script)['stuff'] |
| script = 'return arguments[0].innerHTML + arguments[1].innerHTML' |
| self.assertEquals( |
| 'bc', self._driver.ExecuteScript(script, stuff[0], stuff[1])) |
| |
| def testEvaluateInvalidScript(self): |
| self.assertRaises(chromedriver.ChromeDriverException, |
| self._driver.ExecuteScript, '{{{') |
| |
| def testExecuteAsyncScript(self): |
| self._driver.SetTimeouts({'script': 3000}) |
| self.assertRaises( |
| chromedriver.ScriptTimeout, |
| self._driver.ExecuteAsyncScript, |
| 'var callback = arguments[0];' |
| 'setTimeout(function(){callback(1);}, 10000);') |
| self.assertEquals( |
| 2, |
| self._driver.ExecuteAsyncScript( |
| 'var callback = arguments[0];' |
| 'setTimeout(function(){callback(2);}, 300);')) |
| |
| def testExecuteScriptTimeout(self): |
| self._driver.SetTimeouts({'script': 0}) |
| self.assertRaises( |
| chromedriver.ScriptTimeout, |
| self._driver.ExecuteScript, |
| 'return 2') |
| |
| # Regular script can still run afterwards. |
| self._driver.SetTimeouts({'script': 1000}) |
| self.assertEquals( |
| 4, |
| self._driver.ExecuteScript('return 4')) |
| |
| def testSwitchToFrame(self): |
| self._driver.ExecuteScript( |
| 'var frame = document.createElement("iframe");' |
| 'frame.id="id";' |
| 'frame.name="name";' |
| 'document.body.appendChild(frame);') |
| self.assertTrue(self._driver.ExecuteScript('return window.top == window')) |
| self._driver.SwitchToFrame('id') |
| self.assertTrue(self._driver.ExecuteScript('return window.top != window')) |
| self._driver.SwitchToMainFrame() |
| self.assertTrue(self._driver.ExecuteScript('return window.top == window')) |
| self._driver.SwitchToFrame('name') |
| self.assertTrue(self._driver.ExecuteScript('return window.top != window')) |
| self._driver.SwitchToMainFrame() |
| self.assertTrue(self._driver.ExecuteScript('return window.top == window')) |
| self._driver.SwitchToFrameByIndex(0) |
| self.assertTrue(self._driver.ExecuteScript('return window.top != window')) |
| self._driver.SwitchToMainFrame() |
| self.assertTrue(self._driver.ExecuteScript('return window.top == window')) |
| self._driver.SwitchToFrame(self._driver.FindElement('tag name', 'iframe')) |
| self.assertTrue(self._driver.ExecuteScript('return window.top != window')) |
| |
| def testSwitchToParentFrame(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/nested.html')) |
| self.assertTrue('One' in self._driver.GetPageSource()) |
| self._driver.SwitchToFrameByIndex(0) |
| self.assertTrue('Two' in self._driver.GetPageSource()) |
| self._driver.SwitchToFrameByIndex(0) |
| self.assertTrue('Three' in self._driver.GetPageSource()) |
| self._driver.SwitchToParentFrame() |
| self.assertTrue('Two' in self._driver.GetPageSource()) |
| self._driver.SwitchToParentFrame() |
| self.assertTrue('One' in self._driver.GetPageSource()) |
| |
| def testSwitchToNestedFrame(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/nested_frameset.html')) |
| self._driver.SwitchToFrameByIndex(0) |
| self._driver.FindElement("css selector", "#link") |
| self._driver.SwitchToMainFrame() |
| self._driver.SwitchToFrame('2Frame') |
| self._driver.FindElement("css selector", "#l1") |
| self._driver.SwitchToMainFrame() |
| self._driver.SwitchToFrame('fourth_frame') |
| self.assertTrue('One' in self._driver.GetPageSource()) |
| self._driver.SwitchToMainFrame() |
| self._driver.SwitchToFrameByIndex(4) |
| self._driver.FindElement("css selector", "#aa1") |
| |
| def testExecuteInRemovedFrame(self): |
| self._driver.ExecuteScript( |
| 'var frame = document.createElement("iframe");' |
| 'frame.id="id";' |
| 'frame.name="name";' |
| 'document.body.appendChild(frame);' |
| 'window.addEventListener("message",' |
| ' function(event) { document.body.removeChild(frame); });') |
| self.assertTrue(self._driver.ExecuteScript('return window.top == window')) |
| self._driver.SwitchToFrame('id') |
| self.assertTrue(self._driver.ExecuteScript('return window.top != window')) |
| self._driver.ExecuteScript('parent.postMessage("remove", "*");') |
| self.assertTrue(self._driver.ExecuteScript('return window.top == window')) |
| |
| def testSwitchToStaleFrame(self): |
| self._driver.ExecuteScript( |
| 'var frame = document.createElement("iframe");' |
| 'frame.id="id";' |
| 'frame.name="name";' |
| 'document.body.appendChild(frame);') |
| element = self._driver.FindElement("css selector", "#id") |
| self._driver.SwitchToFrame(element) |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| with self.assertRaises(chromedriver.StaleElementReference): |
| self._driver.SwitchToFrame(element) |
| |
| def testGetTitle(self): |
| script = 'document.title = "title"; return 1;' |
| self.assertEquals(1, self._driver.ExecuteScript(script)) |
| self.assertEquals('title', self._driver.GetTitle()) |
| |
| def testGetPageSource(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| self.assertTrue('Link to empty.html' in self._driver.GetPageSource()) |
| |
| def testFindElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>a</div><div>b</div>";') |
| self.assertTrue( |
| isinstance(self._driver.FindElement('tag name', 'div'), |
| webelement.WebElement)) |
| |
| def testNoSuchElementExceptionMessage(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>a</div><div>b</div>";') |
| self.assertRaisesRegexp(chromedriver.NoSuchElement, |
| 'no such element: Unable ' |
| 'to locate element: {"method":"tag name",' |
| '"selector":"divine"}', |
| self._driver.FindElement, |
| 'tag name', 'divine') |
| |
| def testFindElements(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>a</div><div>b</div>";') |
| divs = self._driver.FindElements('tag name', 'div') |
| self.assertTrue(isinstance(divs, list)) |
| self.assertEquals(2, len(divs)) |
| for div in divs: |
| self.assertTrue(isinstance(div, webelement.WebElement)) |
| |
| def testFindChildElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div><br><br></div><div><a></a></div>";') |
| element = self._driver.FindElement('tag name', 'div') |
| self.assertTrue( |
| isinstance(element.FindElement('tag name', 'br'), |
| webelement.WebElement)) |
| |
| def testFindChildElements(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div><br><br></div><div><br></div>";') |
| element = self._driver.FindElement('tag name', 'div') |
| brs = element.FindElements('tag name', 'br') |
| self.assertTrue(isinstance(brs, list)) |
| self.assertEquals(2, len(brs)) |
| for br in brs: |
| self.assertTrue(isinstance(br, webelement.WebElement)) |
| |
| def testHoverOverElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| div = self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.addEventListener("mouseover", function() {' |
| ' document.body.appendChild(document.createElement("br"));' |
| '});' |
| 'return div;') |
| div.HoverOver() |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testClickElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| div = self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.addEventListener("click", function() {' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| div.Click() |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testClickElementInSubFrame(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/frame_test.html')) |
| frame = self._driver.FindElement('tag name', 'iframe') |
| self._driver.SwitchToFrame(frame) |
| # Test clicking element in the sub frame. |
| self.testClickElement() |
| |
| def testClickElementAfterNavigation(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/link_nav.html')) |
| link = self._driver.FindElement('css selector', '#l1') |
| link.Click() |
| alert_button = self._driver.FindElement('css selector', '#aa1') |
| alert_button.Click() |
| self.assertTrue(self._driver.IsAlertOpen()) |
| |
| def testActionsMouseMove(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("mouseover", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| actions = ({"actions": [{ |
| "type":"pointer", |
| "actions":[{"type": "pointerMove", "x": 10, "y": 10}], |
| "parameters": {"pointerType": "mouse"}, |
| "id": "pointer1"}]}) |
| self._driver.PerformActions(actions) |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testActionsMouseClick(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("click", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| actions = ({"actions": [{ |
| "type":"pointer", |
| "actions":[{"type": "pointerMove", "x": 10, "y": 10}, |
| {"type": "pointerDown", "button": 0}, |
| {"type": "pointerUp", "button": 0}], |
| "parameters": {"pointerType": "mouse"}, |
| "id": "pointer1"}]}) |
| self._driver.PerformActions(actions) |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testActionsMouseDoubleClick(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("dblclick", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| actions = ({"actions": [{ |
| "type":"pointer", |
| "actions":[{"type": "pointerMove", "x": 10, "y": 10}, |
| {"type": "pointerDown", "button": 0}, |
| {"type": "pointerUp", "button": 0}, |
| {"type": "pointerDown", "button": 0}, |
| {"type": "pointerUp", "button": 0}], |
| "parameters": {"pointerType": "mouse"}, |
| "id": "pointer1"}]}) |
| self._driver.PerformActions(actions) |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testActionsTouchTap(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("click", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| actions = ({"actions": [{ |
| "type":"pointer", |
| "actions":[{"type": "pointerMove", "x": 10, "y": 10}, |
| {"type": "pointerDown"}, |
| {"type": "pointerUp"}], |
| "parameters": {"pointerType": "touch"}, |
| "id": "pointer1"}]}) |
| self._driver.PerformActions(actions) |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testActionsMulti(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| ''' |
| document.body.innerHTML |
| = "<div id='div' autofocus style='width:200px; height:200px'>"; |
| window.events = []; |
| const div = document.getElementById('div'); |
| div.addEventListener('click', event => { |
| window.events.push( |
| {x: event.clientX, y: event.clientY}); |
| }); |
| ''') |
| |
| # Move mouse to (50, 50). |
| self._driver.PerformActions({'actions': [ |
| { |
| 'type': 'pointer', |
| 'id': 'mouse', |
| 'actions': [ {'type': 'pointerMove', 'x': 50, 'y': 50} ] |
| } |
| ]}) |
| |
| # Click mouse button. ChromeDriver should remember that mouse is at |
| # (50, 50). |
| self._driver.PerformActions({'actions': [ |
| { |
| 'type': 'pointer', |
| 'id': 'mouse', |
| 'actions': [ |
| {'type': 'pointerDown', "button": 0}, |
| {'type': 'pointerUp', "button": 0} |
| ] |
| } |
| ]}) |
| events = self._driver.ExecuteScript('return window.events') |
| self.assertEquals(1, len(events)) |
| self.assertEquals(50, events[0]['x']) |
| self.assertEquals(50, events[0]['y']) |
| |
| # Clean up action states, move mouse back to (0, 0). |
| self._driver.ReleaseActions() |
| |
| # Move mouse relative by (80, 80) pixels, and then click. |
| self._driver.PerformActions({'actions': [ |
| { |
| 'type': 'pointer', |
| 'id': 'mouse', |
| 'actions': [ |
| {'type': 'pointerMove', 'x': 80, 'y': 80, 'origin': 'pointer'}, |
| {'type': 'pointerDown', "button": 0}, |
| {'type': 'pointerUp', "button": 0} |
| ] |
| } |
| ]}) |
| events = self._driver.ExecuteScript('return window.events') |
| self.assertEquals(2, len(events)) |
| self.assertEquals(80, events[1]['x']) |
| self.assertEquals(80, events[1]['y']) |
| |
| self._driver.ReleaseActions() |
| |
| def testActionsPause(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| ''' |
| document.body.innerHTML |
| = "<input type='text' autofocus style='width:100px; height:100px'>"; |
| window.events = []; |
| const input = document.getElementsByTagName("input")[0]; |
| const listener |
| = e => window.events.push({type: e.type, time: e.timeStamp}); |
| input.addEventListener("keydown", listener); |
| input.addEventListener("keyup", listener); |
| input.addEventListener("mousedown", listener); |
| ''') |
| |
| # Actions on 3 devices, across 6 ticks, with 200 ms pause at ticks 1 to 4. |
| # Tick "key" device "pointer" device "none" device |
| # 0 move |
| # 1 pause 200 ms pointer down pause 100 ms |
| # 2 "a" key down pointer up pause 200 ms |
| # 3 "a" key up pause 200 ms |
| # 4 "b" key down move 200 ms |
| # 5 "b" key up |
| actions = {'actions': [ |
| { |
| 'type': 'key', |
| 'id': 'key', |
| 'actions': [ |
| {'type': 'pause'}, |
| {'type': 'pause', 'duration': 200}, |
| {'type': 'keyDown', 'value': 'a'}, |
| {'type': 'keyUp', 'value': 'a'}, |
| {'type': 'keyDown', 'value': 'b'}, |
| {'type': 'keyUp', 'value': 'b'}, |
| ] |
| }, |
| { |
| 'type': 'pointer', |
| 'id': 'mouse', |
| 'actions': [ |
| {'type': 'pointerMove', 'x': 50, 'y': 50}, |
| {'type': 'pointerDown', 'button': 0}, |
| {'type': 'pointerUp', 'button': 0}, |
| {'type': 'pause', 'duration': 200}, |
| {'type': 'pointerMove', 'duration': 200, 'x': 10, 'y': 10}, |
| ] |
| }, |
| { |
| 'type': 'none', |
| 'id': 'none', |
| 'actions': [ |
| {'type': 'pause'}, |
| {'type': 'pause', 'duration': 100}, |
| {'type': 'pause', 'duration': 200}, |
| ] |
| } |
| ]} |
| |
| self._driver.PerformActions(actions) |
| events = self._driver.ExecuteScript('return window.events') |
| expected_events = ['mousedown', 'keydown', 'keyup', 'keydown', 'keyup'] |
| self.assertEquals(len(expected_events), len(events)) |
| for i in range(len(events)): |
| self.assertEqual(expected_events[i], events[i]['type']) |
| if i > 0: |
| elapsed_time = events[i]['time'] - events[i-1]['time'] |
| self.assertGreaterEqual(elapsed_time, 200) |
| |
| def testReleaseActions(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| ''' |
| document.body.innerHTML |
| = "<input id='target' type='text' style='width:200px; height:200px'>"; |
| window.events = []; |
| const recordKeyEvent = event => { |
| window.events.push( |
| {type: event.type, code: event.code}); |
| }; |
| const recordMouseEvent = event => { |
| window.events.push( |
| {type: event.type, x: event.clientX, y: event.clientY}); |
| }; |
| const target = document.getElementById('target'); |
| target.addEventListener('keydown', recordKeyEvent); |
| target.addEventListener('keyup', recordKeyEvent); |
| target.addEventListener('mousedown', recordMouseEvent); |
| target.addEventListener('mouseup', recordMouseEvent); |
| ''') |
| |
| # Move mouse to (50, 50), press a mouse button, and press a key. |
| self._driver.PerformActions({'actions': [ |
| { |
| 'type': 'pointer', |
| 'id': 'mouse', |
| 'actions': [ |
| {'type': 'pointerMove', 'x': 50, 'y': 50}, |
| {'type': 'pointerDown', "button": 0} |
| ] |
| }, |
| { |
| 'type': 'key', |
| 'id': 'key', |
| 'actions': [ |
| {'type': 'pause'}, |
| {'type': 'pause'}, |
| {'type': 'keyDown', 'value': 'a'} |
| ] |
| } |
| ]}) |
| |
| events = self._driver.ExecuteScript('return window.events') |
| self.assertEquals(2, len(events)) |
| self.assertEquals('mousedown', events[0]['type']) |
| self.assertEquals(50, events[0]['x']) |
| self.assertEquals(50, events[0]['y']) |
| self.assertEquals('keydown', events[1]['type']) |
| self.assertEquals('KeyA', events[1]['code']) |
| |
| self._driver.ReleaseActions() |
| |
| events = self._driver.ExecuteScript('return window.events') |
| self.assertEquals(4, len(events)) |
| self.assertEquals('keyup', events[2]['type']) |
| self.assertEquals('KeyA', events[2]['code']) |
| self.assertEquals('mouseup', events[3]['type']) |
| self.assertEquals(50, events[3]['x']) |
| self.assertEquals(50, events[3]['y']) |
| |
| def testPageLoadStrategyIsNormalByDefault(self): |
| self.assertEquals('normal', |
| self._driver.capabilities['pageLoadStrategy']) |
| |
| def testClearElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| text = self._driver.ExecuteScript( |
| 'document.body.innerHTML = \'<input type="text" value="abc">\';' |
| 'return document.getElementsByTagName("input")[0];') |
| value = self._driver.ExecuteScript('return arguments[0].value;', text) |
| self.assertEquals('abc', value) |
| text.Clear() |
| value = self._driver.ExecuteScript('return arguments[0].value;', text) |
| self.assertEquals('', value) |
| |
| def testSendKeysToInputFileElement(self): |
| file_name = os.path.join(_TEST_DATA_DIR, 'anchor_download_test.png') |
| self._driver.Load(ChromeDriverTest.GetHttpUrlForFile( |
| '/chromedriver/file_input.html')) |
| elem = self._driver.FindElement('css selector', '#id_file') |
| elem.SendKeys(file_name) |
| text = self._driver.ExecuteScript( |
| 'var input = document.getElementById("id_file").value;' |
| 'return input;') |
| self.assertEquals('C:\\fakepath\\anchor_download_test.png', text); |
| if not _ANDROID_PACKAGE_KEY: |
| self.assertRaises(chromedriver.InvalidArgument, |
| elem.SendKeys, "/blah/blah/blah") |
| |
| def testGetElementAttribute(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/attribute_colon_test.html')) |
| elem = self._driver.FindElement("css selector", "*[name='phones']") |
| self.assertEquals('3', elem.GetAttribute('size')) |
| |
| def testGetElementProperty(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/two_inputs.html')) |
| elem = self._driver.FindElement("css selector", "#first") |
| self.assertEquals('text', elem.GetProperty('type')) |
| self.assertEquals('first', elem.GetProperty('id')) |
| |
| def testGetElementSpecialCharAttribute(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/attribute_colon_test.html')) |
| elem = self._driver.FindElement("css selector", "*[name='phones']") |
| self.assertEquals('colonvalue', elem.GetAttribute('ext:qtip')) |
| |
| def testGetCurrentUrl(self): |
| url = self.GetHttpUrlForFile('/chromedriver/frame_test.html') |
| self._driver.Load(url) |
| self.assertEquals(url, self._driver.GetCurrentUrl()) |
| self._driver.SwitchToFrame(self._driver.FindElement('tag name', 'iframe')) |
| self.assertEquals(url, self._driver.GetCurrentUrl()) |
| |
| def testGoBackAndGoForward(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.GoBack() |
| self._driver.GoForward() |
| |
| def testDontGoBackOrGoForward(self): |
| # We need to run this test in a new tab so that it is isolated from previous |
| # test runs. |
| old_windows = self._driver.GetWindowHandles() |
| self._driver.ExecuteScript('window.open("about:blank")') |
| new_window = self.WaitForNewWindow(self._driver, old_windows) |
| self._driver.SwitchToWindow(new_window) |
| self.assertEquals('about:blank', self._driver.GetCurrentUrl()) |
| self._driver.GoBack() |
| self.assertEquals('about:blank', self._driver.GetCurrentUrl()) |
| self._driver.GoForward() |
| self.assertEquals('about:blank', self._driver.GetCurrentUrl()) |
| |
| def testBackNavigationAfterClickElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/link_nav.html')) |
| link = self._driver.FindElement('css selector', '#l1') |
| link.Click() |
| self._driver.GoBack() |
| self.assertNotEqual('data:,', self._driver.GetCurrentUrl()) |
| self.assertEquals(self.GetHttpUrlForFile('/chromedriver/link_nav.html'), |
| self._driver.GetCurrentUrl()) |
| |
| def testAlertHandlingOnPageUnload(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript('window.onbeforeunload=function(){return true}') |
| self._driver.FindElement('tag name', 'body').Click() |
| self._driver.GoBack() |
| self.assertTrue(self._driver.IsAlertOpen()) |
| self._driver.HandleAlert(True) |
| self.assertFalse(self._driver.IsAlertOpen()) |
| |
| def testRefresh(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.Refresh() |
| |
| def testAlert(self): |
| self.assertFalse(self._driver.IsAlertOpen()) |
| self._driver.ExecuteScript('window.confirmed = confirm(\'HI\');') |
| self.assertTrue(self._driver.IsAlertOpen()) |
| self.assertEquals('HI', self._driver.GetAlertMessage()) |
| self._driver.HandleAlert(False) |
| self.assertFalse(self._driver.IsAlertOpen()) |
| self.assertEquals(False, |
| self._driver.ExecuteScript('return window.confirmed')) |
| |
| def testSendTextToAlert(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript('prompt = window.prompt()') |
| self.assertTrue(self._driver.IsAlertOpen()) |
| self._driver.HandleAlert(True, 'TextToPrompt') |
| self.assertEquals('TextToPrompt', |
| self._driver.ExecuteScript('return prompt')) |
| self._driver.ExecuteScript('window.confirmed = confirm(\'HI\');') |
| self.assertRaises(chromedriver.ElementNotInteractable, |
| self._driver.HandleAlert, |
| True, 'textToConfirm') |
| self._driver.HandleAlert(True) #for closing the previous alert. |
| self._driver.ExecuteScript('window.onbeforeunload=function(){return true}') |
| self._driver.FindElement('tag name', 'body').Click() |
| self._driver.Refresh() |
| self.assertTrue(self._driver.IsAlertOpen()) |
| self.assertRaises(chromedriver.UnsupportedOperation, |
| self._driver.HandleAlert, |
| True, 'textToOnBeforeUnload') |
| |
| def testAlertOnNewWindow(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| old_windows = self._driver.GetWindowHandles() |
| self._driver.ExecuteScript("window.open('%s')" % |
| self.GetHttpUrlForFile('/chromedriver/alert_onload.html')) |
| new_window = self.WaitForNewWindow(self._driver, old_windows) |
| self.assertNotEqual(None, new_window) |
| self._driver.SwitchToWindow(new_window) |
| self.assertTrue(self._driver.IsAlertOpen()) |
| self._driver.HandleAlert(False) |
| self.assertFalse(self._driver.IsAlertOpen()) |
| |
| def testShouldHandleNewWindowLoadingProperly(self): |
| """Tests that ChromeDriver determines loading correctly for new windows.""" |
| self._http_server.SetDataForPath( |
| '/newwindow', |
| """ |
| <html> |
| <body> |
| <a href='%s' target='_blank'>new window/tab</a> |
| </body> |
| </html>""" % self._sync_server.GetUrl()) |
| self._driver.Load(self._http_server.GetUrl() + '/newwindow') |
| old_windows = self._driver.GetWindowHandles() |
| self._driver.FindElement('tag name', 'a').Click() |
| new_window = self.WaitForNewWindow(self._driver, old_windows) |
| self.assertNotEqual(None, new_window) |
| |
| self.assertFalse(self._driver.IsLoading()) |
| self._driver.SwitchToWindow(new_window) |
| self.assertTrue(self._driver.IsLoading()) |
| self._sync_server.RespondWithContent('<html>new window</html>') |
| self._driver.ExecuteScript('return 1') # Shouldn't hang. |
| |
| def testPopups(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| old_handles = self._driver.GetWindowHandles() |
| self._driver.ExecuteScript('window.open("about:blank")') |
| new_window_handle = self.WaitForNewWindow(self._driver, old_handles) |
| self.assertNotEqual(None, new_window_handle) |
| |
| def testNoSuchFrame(self): |
| self.assertRaises(chromedriver.NoSuchFrame, |
| self._driver.SwitchToFrame, 'nosuchframe') |
| self.assertRaises(chromedriver.NoSuchFrame, |
| self._driver.SwitchToFrame, |
| self._driver.FindElement('tag name', 'body')) |
| |
| def testWindowPosition(self): |
| rect = self._driver.GetWindowRect() |
| self._driver.SetWindowRect(None, None, rect[2], rect[3]) |
| self.assertEquals(rect, self._driver.GetWindowRect()) |
| |
| # Resize so the window isn't moved offscreen. |
| # See https://bugs.chromium.org/p/chromedriver/issues/detail?id=297. |
| self._driver.SetWindowRect(640, 400, None, None) |
| |
| self._driver.SetWindowRect(None, None, 100, 200) |
| self.assertEquals([640, 400, 100, 200], self._driver.GetWindowRect()) |
| |
| def testWindowSize(self): |
| rect = self._driver.GetWindowRect() |
| self._driver.SetWindowRect(rect[0], rect[1], None, None) |
| self.assertEquals(rect, self._driver.GetWindowRect()) |
| |
| self._driver.SetWindowRect(640, 400, None, None) |
| self.assertEquals([640, 400, rect[2], rect[3]], |
| self._driver.GetWindowRect()) |
| |
| def testWindowRect(self): |
| old_window_rect = self._driver.GetWindowRect() |
| self._driver.SetWindowRect(*old_window_rect) |
| self.assertEquals(self._driver.GetWindowRect(), old_window_rect) |
| |
| target_window_rect = [640, 400, 100, 200] |
| target_window_rect_dict = {'width': 640, 'height': 400, 'x': 100, 'y': 200} |
| returned_window_rect = self._driver.SetWindowRect(*target_window_rect) |
| self.assertEquals(self._driver.GetWindowRect(), target_window_rect) |
| self.assertEquals(returned_window_rect, target_window_rect_dict) |
| |
| def testWindowMaximize(self): |
| old_rect_list = [640, 400, 100, 200] |
| self._driver.SetWindowRect(*old_rect_list) |
| new_rect = self._driver.MaximizeWindow() |
| new_rect_list = [ |
| new_rect['width'], |
| new_rect['height'], |
| new_rect['x'], |
| new_rect['y'] |
| ] |
| self.assertNotEqual(old_rect_list, new_rect_list) |
| |
| self._driver.SetWindowRect(*old_rect_list) |
| self.assertEquals(old_rect_list, self._driver.GetWindowRect()) |
| |
| def testWindowMinimize(self): |
| handle_prefix = "CDwindow-" |
| handle = self._driver.GetCurrentWindowHandle() |
| target = handle[len(handle_prefix):] |
| self._driver.SetWindowRect(640, 400, 100, 200) |
| rect = self._driver.MinimizeWindow() |
| expected_rect = {u'y': 200, u'width': 640, u'height': 400, u'x': 100} |
| |
| #check it returned the correct rect |
| for key in expected_rect.keys(): |
| self.assertEquals(expected_rect[key], rect[key]) |
| |
| # check its minimized |
| res = self._driver.SendCommandAndGetResult('Browser.getWindowForTarget', |
| {'targetId': target}) |
| self.assertEquals('minimized', res['bounds']['windowState']) |
| |
| def testWindowFullScreen(self): |
| old_rect_list = [640, 400, 100, 200] |
| self._driver.SetWindowRect(*old_rect_list) |
| self.assertEquals(self._driver.GetWindowRect(), old_rect_list) |
| new_rect = self._driver.FullScreenWindow() |
| new_rect_list = [ |
| new_rect['width'], |
| new_rect['height'], |
| new_rect['x'], |
| new_rect['y'] |
| ] |
| self.assertNotEqual(old_rect_list, new_rect_list) |
| |
| self._driver.SetWindowRect(*old_rect_list) |
| self.assertEquals(old_rect_list, self._driver.GetWindowRect()) |
| |
| def testConsoleLogSources(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/console_log.html')) |
| logs = self._driver.GetLog('browser') |
| |
| self.assertEqual('javascript', logs[0]['source']) |
| self.assertTrue('TypeError' in logs[0]['message']) |
| |
| self.assertEqual('network', logs[1]['source']) |
| self.assertTrue('nonexistent.png' in logs[1]['message']) |
| self.assertTrue('404' in logs[1]['message']) |
| |
| # Sometimes, we also get an error for a missing favicon. |
| if len(logs) > 2: |
| self.assertEqual('network', logs[2]['source']) |
| self.assertTrue('favicon.ico' in logs[2]['message']) |
| self.assertTrue('404' in logs[2]['message']) |
| self.assertEqual(3, len(logs)) |
| else: |
| self.assertEqual(2, len(logs)) |
| |
| def testPendingConsoleLog(self): |
| new_logs = [""] |
| def GetPendingLogs(driver): |
| response = driver.GetLog('browser') |
| new_logs[0] = [x for x in response if x['source'] == 'console-api'] |
| return new_logs[0] |
| |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/pending_console_log.html')) |
| logs = self._driver.GetLog('browser') |
| self.assertEqual('console-api', logs[0]['source']) |
| self.assertTrue('"InitialError" 2018 "Third"' in logs[0]['message']) |
| |
| self.WaitForCondition(lambda: len(GetPendingLogs(self._driver)) > 0 , 6) |
| self.assertEqual('console-api', new_logs[0][0]['source']) |
| self.assertTrue('"RepeatedError" "Second" "Third"' in |
| new_logs[0][0]['message']) |
| |
| def testGetLogOnClosedWindow(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| old_handles = self._driver.GetWindowHandles() |
| self._driver.FindElement('css selector', '#link').Click() |
| self.WaitForNewWindow(self._driver, old_handles) |
| self._driver.CloseWindow() |
| try: |
| self._driver.GetLog('browser') |
| except chromedriver.ChromeDriverException as e: |
| self.fail('exception while calling GetLog on a closed tab: ' + e.message) |
| |
| def testGetLogOnWindowWithAlert(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript('alert("alert!");') |
| try: |
| self._driver.GetLog('browser') |
| except Exception as e: |
| self.fail(e.message) |
| |
| def testAutoReporting(self): |
| self.assertFalse(self._driver.IsAutoReporting()) |
| self._driver.SetAutoReporting(True) |
| self.assertTrue(self._driver.IsAutoReporting()) |
| url = self.GetHttpUrlForFile('/chromedriver/console_log.html') |
| self.assertRaisesRegexp( |
| chromedriver.UnknownError, |
| ".*Uncaught TypeError: Cannot read property 'y' of undefined.*", |
| self._driver.Load, url) |
| |
| def testDoesntHangOnDebugger(self): |
| self._driver.Load('about:blank') |
| self._driver.ExecuteScript('debugger;') |
| |
| def testChromeDriverSendLargeData(self): |
| script = 'var s = ""; for (var i = 0; i < 10e6; i++) s += "0"; return s;' |
| lots_of_data = self._driver.ExecuteScript(script) |
| self.assertEquals('0'.zfill(int(10e6)), lots_of_data) |
| |
| def testEmulateNetworkConditions(self): |
| # Network conditions must be set before it can be retrieved. |
| self.assertRaises(chromedriver.UnknownError, |
| self._driver.GetNetworkConditions) |
| |
| # DSL: 2Mbps throughput, 5ms RTT |
| latency = 5 |
| throughput = 2048 * 1024 |
| self._driver.SetNetworkConditions(latency, throughput, throughput) |
| |
| network = self._driver.GetNetworkConditions() |
| self.assertEquals(latency, network['latency']); |
| self.assertEquals(throughput, network['download_throughput']); |
| self.assertEquals(throughput, network['upload_throughput']); |
| self.assertEquals(False, network['offline']); |
| |
| # Network Conditions again cannot be retrieved after they've been deleted. |
| self._driver.DeleteNetworkConditions() |
| self.assertRaises(chromedriver.UnknownError, |
| self._driver.GetNetworkConditions) |
| |
| def testEmulateNetworkConditionsName(self): |
| # DSL: 2Mbps throughput, 5ms RTT |
| # latency = 5 |
| # throughput = 2048 * 1024 |
| self._driver.SetNetworkConditionsName('DSL') |
| |
| network = self._driver.GetNetworkConditions() |
| self.assertEquals(5, network['latency']); |
| self.assertEquals(2048*1024, network['download_throughput']); |
| self.assertEquals(2048*1024, network['upload_throughput']); |
| self.assertEquals(False, network['offline']); |
| |
| def testEmulateNetworkConditionsSpeed(self): |
| # Warm up the browser. |
| self._http_server.SetDataForPath( |
| '/', "<html><body>blank</body></html>") |
| self._driver.Load(self._http_server.GetUrl() + '/') |
| |
| # DSL: 2Mbps throughput, 5ms RTT |
| latency = 5 |
| throughput_kbps = 2048 |
| throughput = throughput_kbps * 1024 |
| self._driver.SetNetworkConditions(latency, throughput, throughput) |
| |
| _32_bytes = " 0 1 2 3 4 5 6 7 8 9 A B C D E F" |
| _1_megabyte = _32_bytes * 32768 |
| self._http_server.SetDataForPath( |
| '/1MB', |
| "<html><body>%s</body></html>" % _1_megabyte) |
| start = time.time() |
| self._driver.Load(self._http_server.GetUrl() + '/1MB') |
| finish = time.time() |
| duration = finish - start |
| actual_throughput_kbps = 1024 / duration |
| self.assertLessEqual(actual_throughput_kbps, throughput_kbps * 1.5) |
| self.assertGreaterEqual(actual_throughput_kbps, throughput_kbps / 1.5) |
| |
| def testEmulateNetworkConditionsNameSpeed(self): |
| # Warm up the browser. |
| self._http_server.SetDataForPath( |
| '/', "<html><body>blank</body></html>") |
| self._driver.Load(self._http_server.GetUrl() + '/') |
| |
| # DSL: 2Mbps throughput, 5ms RTT |
| throughput_kbps = 2048 |
| throughput = throughput_kbps * 1024 |
| self._driver.SetNetworkConditionsName('DSL') |
| |
| _32_bytes = " 0 1 2 3 4 5 6 7 8 9 A B C D E F" |
| _1_megabyte = _32_bytes * 32768 |
| self._http_server.SetDataForPath( |
| '/1MB', |
| "<html><body>%s</body></html>" % _1_megabyte) |
| start = time.time() |
| self._driver.Load(self._http_server.GetUrl() + '/1MB') |
| finish = time.time() |
| duration = finish - start |
| actual_throughput_kbps = 1024 / duration |
| self.assertLessEqual(actual_throughput_kbps, throughput_kbps * 1.5) |
| self.assertGreaterEqual(actual_throughput_kbps, throughput_kbps / 1.5) |
| |
| def testEmulateNetworkConditionsOffline(self): |
| # A workaround for crbug.com/177511; when setting offline, the throughputs |
| # must be 0. |
| self._driver.SetNetworkConditions(0, 0, 0, offline=True) |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| # The "X is not available" title is set after the page load event fires, so |
| # we have to explicitly wait for this to change. We can't rely on the |
| # navigation tracker to block the call to Load() above. |
| self.WaitForCondition(lambda: 'is not available' in self._driver.GetTitle()) |
| |
| def testSendCommand(self): |
| """Sends a custom command to the DevTools debugger""" |
| params = {} |
| res = self._driver.SendCommandAndGetResult('CSS.enable', params) |
| self.assertEqual({}, res) |
| |
| def testSendCommandNoParams(self): |
| """Sends a custom command to the DevTools debugger without params""" |
| self.assertRaisesRegexp( |
| chromedriver.InvalidArgument, "params not passed", |
| self._driver.SendCommandAndGetResult, 'CSS.enable', None) |
| |
| def testSendCommandAndGetResult(self): |
| """Sends a custom command to the DevTools debugger and gets the result""" |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| params = {} |
| document = self._driver.SendCommandAndGetResult('DOM.getDocument', params) |
| self.assertTrue('root' in document) |
| |
| def _FindElementInShadowDom(self, css_selectors): |
| """Find an element inside shadow DOM using CSS selectors. |
| The last item in css_selectors identify the element to find. All preceding |
| selectors identify the hierarchy of shadow hosts to traverse in order to |
| reach the target shadow DOM.""" |
| current = None |
| for selector in css_selectors: |
| if current is None: |
| # First CSS selector, start from root DOM. |
| current = self._driver |
| else: |
| # current is a shadow host selected previously. |
| # Enter the corresponding shadow root. |
| current = self._driver.ExecuteScript( |
| 'return arguments[0].shadowRoot', current) |
| current = current.FindElement('css selector', selector) |
| return current |
| |
| def testShadowDomFindElement(self): |
| """Checks that chromedriver can find elements in a shadow DOM.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| self.assertTrue(self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#textBox"])) |
| |
| def testShadowDomFindChildElement(self): |
| """Checks that chromedriver can find child elements from a shadow DOM |
| element.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#childDiv"]) |
| self.assertTrue(elem.FindElement("css selector", "#textBox")) |
| |
| def testShadowDomFindElementFailsFromRoot(self): |
| """Checks that chromedriver can't find elements in a shadow DOM from |
| root.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| # can't find element from the root without /deep/ |
| with self.assertRaises(chromedriver.NoSuchElement): |
| self._driver.FindElement("css selector", "#textBox") |
| |
| def testShadowDomText(self): |
| """Checks that chromedriver can find extract the text from a shadow DOM |
| element.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#heading"]) |
| self.assertEqual("Child", elem.GetText()) |
| |
| def testShadowDomSendKeys(self): |
| """Checks that chromedriver can call SendKeys on a shadow DOM element.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#textBox"]) |
| elem.SendKeys("bar") |
| self.assertEqual("foobar", self._driver.ExecuteScript( |
| 'return arguments[0].value;', elem)) |
| |
| def testShadowDomClear(self): |
| """Checks that chromedriver can call Clear on a shadow DOM element.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#textBox"]) |
| elem.Clear() |
| self.assertEqual("", self._driver.ExecuteScript( |
| 'return arguments[0].value;', elem)) |
| |
| def testShadowDomClick(self): |
| """Checks that chromedriver can call Click on an element in a shadow DOM.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| # Wait for page to stabilize. See https://crbug.com/954553#c7 |
| time.sleep(1) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#button"]) |
| elem.Click() |
| # the button's onClicked handler changes the text box's value |
| self.assertEqual("Button Was Clicked", self._driver.ExecuteScript( |
| 'return arguments[0].value;', |
| self._FindElementInShadowDom(["#innerDiv", "#parentDiv", "#textBox"]))) |
| |
| def testShadowDomHover(self): |
| """Checks that chromedriver can call HoverOver on an element in a |
| shadow DOM.""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| # Wait for page to stabilize. See https://crbug.com/954553#c7 |
| time.sleep(1) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#button"]) |
| elem.HoverOver() |
| # the button's onMouseOver handler changes the text box's value |
| self.assertEqual("Button Was Hovered Over", self._driver.ExecuteScript( |
| 'return arguments[0].value;', |
| self._FindElementInShadowDom(["#innerDiv", "#parentDiv", "#textBox"]))) |
| |
| def testShadowDomStaleReference(self): |
| """Checks that trying to manipulate shadow DOM elements that are detached |
| from the document raises a StaleElementReference exception""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#button"]) |
| self._driver.ExecuteScript( |
| 'document.querySelector("#outerDiv").innerHTML="<div/>";') |
| with self.assertRaises(chromedriver.StaleElementReference): |
| elem.Click() |
| |
| def testTouchDownMoveUpElement(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/touch_action_tests.html')) |
| target = self._driver.FindElement('css selector', '#target') |
| location = target.GetLocation() |
| self._driver.TouchDown(location['x'], location['y']) |
| events = self._driver.FindElement('css selector', '#events') |
| self.assertEquals('events: touchstart', events.GetText()) |
| self._driver.TouchMove(location['x'] + 1, location['y'] + 1) |
| self.assertEquals('events: touchstart touchmove', events.GetText()) |
| self._driver.TouchUp(location['x'] + 1, location['y'] + 1) |
| self.assertEquals('events: touchstart touchmove touchend', events.GetText()) |
| |
| def testGetElementRect(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/absolute_position_element.html')) |
| target = self._driver.FindElement('css selector', '#target') |
| rect = target.GetRect() |
| self.assertEquals(18, rect['x']) |
| self.assertEquals(10, rect['y']) |
| self.assertEquals(200, rect['height']) |
| self.assertEquals(210, rect['width']) |
| |
| def testTouchFlickElement(self): |
| dx = 3 |
| dy = 4 |
| speed = 5 |
| flickTouchEventsPerSecond = 30 |
| moveEvents = int( |
| math.sqrt(dx * dx + dy * dy) * flickTouchEventsPerSecond / speed) |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| div = self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.addEventListener("touchstart", function() {' |
| ' div.innerHTML = "preMove0";' |
| '});' |
| 'div.addEventListener("touchmove", function() {' |
| ' res = div.innerHTML.match(/preMove(\d+)/);' |
| ' if (res != null) {' |
| ' div.innerHTML = "preMove" + (parseInt(res[1], 10) + 1);' |
| ' }' |
| '});' |
| 'div.addEventListener("touchend", function() {' |
| ' if (div.innerHTML == "preMove' + str(moveEvents) + '") {' |
| ' div.innerHTML = "new<br>";' |
| ' }' |
| '});' |
| 'return div;') |
| self._driver.TouchFlick(div, dx, dy, speed) |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testTouchPinch(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/touch_action_tests.html')) |
| width_before_pinch = self._driver.ExecuteScript('return window.innerWidth;') |
| height_before_pinch = self._driver.ExecuteScript( |
| 'return window.innerHeight;') |
| self._driver.TouchPinch(width_before_pinch / 2, |
| height_before_pinch / 2, |
| 2.0) |
| width_after_pinch = self._driver.ExecuteScript('return window.innerWidth;') |
| self.assertAlmostEqual(2.0, float(width_before_pinch) / width_after_pinch) |
| |
| def testSwitchesToTopFrameAfterNavigation(self): |
| self._driver.Load('about:blank') |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/outer.html')) |
| frame = self._driver.FindElement('tag name', 'iframe') |
| self._driver.SwitchToFrame(frame) |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/outer.html')) |
| p = self._driver.FindElement('tag name', 'p') |
| self.assertEquals('Two', p.GetText()) |
| |
| def testSwitchesToTopFrameAfterRefresh(self): |
| self._driver.Load('about:blank') |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/outer.html')) |
| frame = self._driver.FindElement('tag name', 'iframe') |
| self._driver.SwitchToFrame(frame) |
| self._driver.Refresh() |
| p = self._driver.FindElement('tag name', 'p') |
| self.assertEquals('Two', p.GetText()) |
| |
| def testSwitchesToTopFrameAfterGoingBack(self): |
| self._driver.Load('about:blank') |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/outer.html')) |
| frame = self._driver.FindElement('tag name', 'iframe') |
| self._driver.SwitchToFrame(frame) |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/inner.html')) |
| self._driver.GoBack() |
| p = self._driver.FindElement('tag name', 'p') |
| self.assertEquals('Two', p.GetText()) |
| |
| def testCanSwitchToPrintPreviewDialog(self): |
| old_handles = self._driver.GetWindowHandles() |
| print >> sys.stdout, "Test debug: actual len of old_handles: " \ |
| + str(len(old_handles)) |
| self.assertEquals(1, len(old_handles)) |
| self._driver.ExecuteScript('setTimeout(function(){window.print();}, 0);') |
| new_window_handle = self.WaitForNewWindow(self._driver, old_handles) |
| if new_window_handle is None: |
| print >> sys.stdout, "Test debug: new_window_handle is None" |
| else: |
| print >> sys.stdout, "Test debug: new_window_handle is not None" |
| self.assertNotEqual(None, new_window_handle) |
| self._driver.SwitchToWindow(new_window_handle) |
| print >> sys.stdout, "Test debug: actual GetCurrentUrl: " \ |
| + self._driver.GetCurrentUrl() |
| self.assertEquals('chrome://print/', self._driver.GetCurrentUrl()) |
| |
| def testCanClickInIframes(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/nested.html')) |
| a = self._driver.FindElement('tag name', 'a') |
| a.Click() |
| frame_url = self._driver.ExecuteScript('return window.location.href') |
| self.assertTrue(frame_url.endswith('#one')) |
| frame = self._driver.FindElement('tag name', 'iframe') |
| self._driver.SwitchToFrame(frame) |
| a = self._driver.FindElement('tag name', 'a') |
| a.Click() |
| frame_url = self._driver.ExecuteScript('return window.location.href') |
| self.assertTrue(frame_url.endswith('#two')) |
| |
| def testDoesntHangOnFragmentNavigation(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html#x')) |
| |
| def SetCookie(self, request): |
| return {'Set-Cookie': 'x=y; HttpOnly'}, "<!DOCTYPE html><html></html>" |
| |
| def testGetHttpOnlyCookie(self): |
| self._http_server.SetCallbackForPath('/setCookie', self.SetCookie) |
| self._driver.Load(self.GetHttpUrlForFile('/setCookie')) |
| self._driver.AddCookie({'name': 'a', 'value': 'b'}) |
| cookies = self._driver.GetCookies() |
| self.assertEquals(2, len(cookies)) |
| for cookie in cookies: |
| self.assertIn('name', cookie) |
| if cookie['name'] == 'a': |
| self.assertFalse(cookie['httpOnly']) |
| elif cookie['name'] == 'x': |
| self.assertTrue(cookie['httpOnly']) |
| else: |
| self.fail('unexpected cookie: %s' % json.dumps(cookie)) |
| |
| def testCookiePath(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/long_url/empty.html')) |
| self._driver.AddCookie({'name': 'a', 'value': 'b'}) |
| self._driver.AddCookie({ |
| 'name': 'x', 'value': 'y', 'path': '/chromedriver/long_url'}) |
| cookies = self._driver.GetCookies() |
| self.assertEquals(2, len(cookies)) |
| for cookie in cookies: |
| self.assertIn('path', cookie) |
| if cookie['name'] == 'a': |
| self.assertEquals('/' , cookie['path']) |
| if cookie['name'] == 'x': |
| self.assertEquals('/chromedriver/long_url' , cookie['path']) |
| |
| def testGetNamedCookie(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/empty.html')) |
| self._driver.AddCookie({'name': 'a', 'value': 'b'}) |
| named_cookie = self._driver.GetNamedCookie('a') |
| self.assertEquals('a' , named_cookie['name']) |
| self.assertEquals('b' , named_cookie['value']) |
| self.assertRaisesRegexp( |
| chromedriver.NoSuchCookie, "no such cookie", |
| self._driver.GetNamedCookie, 'foo') |
| |
| def testDeleteCookie(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/empty.html')) |
| self._driver.AddCookie({'name': 'a', 'value': 'b'}) |
| self._driver.AddCookie({'name': 'x', 'value': 'y'}) |
| self._driver.AddCookie({'name': 'p', 'value': 'q'}) |
| cookies = self._driver.GetCookies() |
| self.assertEquals(3, len(cookies)) |
| self._driver.DeleteCookie('a') |
| self.assertEquals(2, len(self._driver.GetCookies())) |
| self._driver.DeleteAllCookies() |
| self.assertEquals(0, len(self._driver.GetCookies())) |
| |
| def testGetUrlOnInvalidUrl(self): |
| # Make sure we don't return 'chrome-error://chromewebdata/' (see |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1272). RFC 6761 |
| # requires domain registrars to keep 'invalid.' unregistered (see |
| # https://tools.ietf.org/html/rfc6761#section-6.4). |
| self._driver.Load('http://invalid./') |
| self.assertEquals('http://invalid./', self._driver.GetCurrentUrl()) |
| |
| def testCanClickAlertInIframes(self): |
| # This test requires that the page be loaded from a file:// URI, rather than |
| # the test HTTP server. |
| path = os.path.join(chrome_paths.GetTestData(), 'chromedriver', |
| 'page_with_frame.html') |
| url = 'file://' + urllib.pathname2url(path) |
| self._driver.Load(url) |
| frame = self._driver.FindElement('css selector', '#frm') |
| self._driver.SwitchToFrame(frame) |
| a = self._driver.FindElement('css selector', '#btn') |
| a.Click() |
| self.WaitForCondition(lambda: self._driver.IsAlertOpen()) |
| self._driver.HandleAlert(True) |
| |
| def testThrowErrorWithExecuteScript(self): |
| self.assertRaisesRegexp( |
| chromedriver.JavaScriptError, "some error", |
| self._driver.ExecuteScript, 'throw new Error("some error")') |
| |
| def testDoesntCrashWhenScriptLogsUndefinedValue(self): |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1547 |
| self._driver.ExecuteScript('var b; console.log(b);') |
| |
| def testDoesntThrowWhenPageLogsUndefinedValue(self): |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1547 |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/log_undefined_value.html')) |
| |
| def testCanSetCheckboxWithSpaceKey(self): |
| self._driver.Load('about:blank') |
| self._driver.ExecuteScript( |
| "document.body.innerHTML = '<input type=\"checkbox\">';") |
| checkbox = self._driver.FindElement('tag name', 'input') |
| self.assertFalse( |
| self._driver.ExecuteScript('return arguments[0].checked', checkbox)) |
| checkbox.SendKeys(' ') |
| self.assertTrue( |
| self._driver.ExecuteScript('return arguments[0].checked', checkbox)) |
| |
| def testElementReference(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/element_ref.html')) |
| element = self._driver.FindElement('css selector', '#link') |
| self._driver.FindElements('tag name', 'br') |
| w3c_id_length = 36 |
| if (self._driver.w3c_compliant): |
| self.assertEquals(len(element._id), w3c_id_length) |
| |
| def testFindElementWhenElementIsOverridden(self): |
| self._driver.Load('about:blank') |
| self._driver.ExecuteScript( |
| 'document.body.appendChild(document.createElement("a"));') |
| self._driver.ExecuteScript('window.Element = {}') |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'a'))) |
| |
| def testExecuteScriptWhenObjectPrototypeIsModified(self): |
| # Some JavaScript libraries (e.g. MooTools) do things like this. For context |
| # see https://bugs.chromium.org/p/chromedriver/issues/detail?id=1521 |
| self._driver.Load('about:blank') |
| self._driver.ExecuteScript('Object.prototype.$family = undefined;') |
| self.assertEquals(1, self._driver.ExecuteScript('return 1;')) |
| |
| def testWebWorkerFrames(self): |
| """Verify web worker frames are handled correctly. |
| |
| Regression test for bug |
| https://bugs.chromium.org/p/chromedriver/issues/detail?id=2340. |
| The bug was triggered by opening a page with web worker, and then opening a |
| page on a different site. We simulate a different site by using 'localhost' |
| as the host name (default is '127.0.0.1'). |
| """ |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/web_worker.html')) |
| self._driver.Load(self._http_server.GetUrl('localhost') |
| + '/chromedriver/empty.html') |
| |
| def testSlowIFrame(self): |
| """Verify ChromeDriver waits for slow frames to load. |
| |
| Regression test for bugs |
| https://bugs.chromium.org/p/chromedriver/issues/detail?id=2198 and |
| https://bugs.chromium.org/p/chromedriver/issues/detail?id=2350. |
| """ |
| def waitAndRespond(): |
| # Send iframe contents slowly |
| time.sleep(2) |
| self._sync_server.RespondWithContent('<html>IFrame contents</html>') |
| |
| self._http_server.SetDataForPath('/top.html', |
| """ |
| <html><body> |
| <div id='top'> |
| <input id='button' type="button" onclick="run()" value='Click'> |
| </div> |
| <script> |
| function run() { |
| var iframe = document.createElement('iframe'); |
| iframe.id = 'iframe'; |
| iframe.setAttribute('src', '%s'); |
| document.body.appendChild(iframe); |
| } |
| </script> |
| </body></html>""" % self._sync_server.GetUrl()) |
| self._driver.Load(self._http_server.GetUrl() + '/top.html') |
| thread = threading.Thread(target=waitAndRespond) |
| thread.start() |
| self._driver.FindElement('css selector', '#button').Click() |
| # If ChromeDriver correctly waits for slow iframe to load, then |
| # SwitchToFrame succeeds, and element with id='top' won't be found. |
| # If ChromeDriver didn't wait for iframe load, then SwitchToFrame fails, |
| # we remain in top frame, and FindElement succeeds. |
| frame = self._driver.FindElement('css selector', '#iframe') |
| self._driver.SwitchToFrame(frame) |
| with self.assertRaises(chromedriver.NoSuchElement): |
| self._driver.FindElement('css selector', '#top') |
| thread.join() |
| |
| @staticmethod |
| def MakeRedImageTestScript(png_data_in_base64): |
| """Used by the takeElementScreenshot* tests to load the PNG image via a data |
| URI, analyze it, and PASS/FAIL depending on whether all the pixels are all |
| rgb(255,0,0).""" |
| return ( |
| """ |
| const resolve = arguments[arguments.length - 1]; |
| const image = new Image(); |
| image.onload = () => { |
| var canvas = document.createElement('canvas'); |
| canvas.width = image.width; |
| canvas.height = image.height; |
| var context = canvas.getContext('2d'); |
| context.drawImage(image, 0, 0); |
| const pixels = |
| context.getImageData(0, 0, image.width, image.height).data; |
| for (let i = 0; i < pixels.length; i += 4) { |
| if (pixels[i + 0] != 255 || // Red |
| pixels[i + 1] != 0 || // Green |
| pixels[i + 2] != 0) { // Blue |
| const message = ( |
| 'FAIL: Bad pixel rgb(' + pixels.slice(i, i + 3).join(',') + |
| ') at offset ' + i + ' from ' + image.src); |
| // "Disabled" on Mac 10.10: 1/15 test runs produces an incorrect |
| // pixel. Since no later Mac version, nor any other platform, |
| // exhibits this problem, we assume this is due to a bug in this |
| // specific version of Mac OS. So, just log the error and pass |
| // the test. http://crbug.com/913603 |
| if (navigator.userAgent.indexOf('Mac OS X 10_10') != -1) { |
| console.error(message); |
| console.error('Passing test due to Mac 10.10-specific bug.'); |
| resolve('PASS'); |
| } else { |
| resolve(message); |
| } |
| return; |
| } |
| } |
| resolve('PASS'); |
| }; |
| image.src = 'data:image/png;base64,%s'; |
| """ % png_data_in_base64.replace("'", "\\'")) |
| |
| def testTakeElementScreenshot(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/page_with_redbox.html')) |
| elementScreenshotPNGBase64 = self._driver.FindElement( |
| 'css selector', '#box').TakeElementScreenshot() |
| self.assertIsNotNone(elementScreenshotPNGBase64) |
| analysisResult = self._driver.ExecuteAsyncScript( |
| ChromeDriverTest.MakeRedImageTestScript(elementScreenshotPNGBase64)) |
| self.assertEquals('PASS', analysisResult) |
| |
| def testTakeElementScreenshotInIframe(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/page_with_iframe_redbox.html')) |
| frame = self._driver.FindElement('css selector', '#frm') |
| self._driver.SwitchToFrame(frame) |
| elementScreenshotPNGBase64 = self._driver.FindElement( |
| 'css selector', '#box').TakeElementScreenshot() |
| self.assertIsNotNone(elementScreenshotPNGBase64) |
| analysisResult = self._driver.ExecuteAsyncScript( |
| ChromeDriverTest.MakeRedImageTestScript(elementScreenshotPNGBase64)) |
| self.assertEquals('PASS', analysisResult) |
| |
| def testGenerateTestReport(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/reporting_observer.html')) |
| self._driver.GenerateTestReport('test report message'); |
| report = self._driver.ExecuteScript('return window.result;') |
| |
| self.assertEquals('test', report['type']); |
| self.assertEquals('test report message', report['body']['message']); |
| |
| # Tests in the following class are expected to be moved to ChromeDriverTest |
| # class when we no longer support the legacy mode. |
| class ChromeDriverW3cTest(ChromeDriverBaseTestWithWebServer): |
| """W3C mode specific tests.""" |
| |
| def setUp(self): |
| self._driver = self.CreateDriver( |
| send_w3c_capability=True, send_w3c_request=True) |
| |
| def testSendKeysToElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| text = self._driver.ExecuteScript( |
| 'document.body.innerHTML = \'<input type="text">\';' |
| 'var input = document.getElementsByTagName("input")[0];' |
| 'input.addEventListener("change", function() {' |
| ' document.body.appendChild(document.createElement("br"));' |
| '});' |
| 'return input;') |
| text.SendKeys('0123456789+-*/ Hi') |
| text.SendKeys(', there!') |
| value = self._driver.ExecuteScript('return arguments[0].value;', text) |
| self.assertEquals('0123456789+-*/ Hi, there!', value) |
| |
| def testUnexpectedAlertOpenExceptionMessage(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript('window.alert("Hi");') |
| self.assertRaisesRegexp(chromedriver.UnexpectedAlertOpen, |
| '{Alert text : Hi}', |
| self._driver.FindElement, 'tag name', 'divine') |
| # In W3C mode, the alert is dismissed by default. |
| self.assertFalse(self._driver.IsAlertOpen()) |
| |
| |
| class ChromeDriverTestLegacy(ChromeDriverBaseTestWithWebServer): |
| """End to end tests for ChromeDriver in Legacy mode.""" |
| |
| def setUp(self): |
| self._driver = self.CreateDriver(send_w3c_capability=False, |
| send_w3c_request=False) |
| |
| def testContextMenuEventFired(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/context_menu.html')) |
| self._driver.MouseMoveTo(self._driver.FindElement('tag name', 'div')) |
| self._driver.MouseClick(2) |
| self.assertTrue(self._driver.ExecuteScript('return success')) |
| |
| def testDragAndDropWithSVGImage(self): |
| self._driver.Load( |
| self.GetHttpUrlForFile('/chromedriver/drag_and_drop.svg')) |
| drag = self._driver.FindElement("css selector", "#GreenRectangle") |
| drop = self._driver.FindElement("css selector", "#FolderRectangle") |
| self._driver.MouseMoveTo(drag) |
| self._driver.MouseButtonDown() |
| self._driver.MouseMoveTo(drop) |
| self._driver.MouseButtonUp() |
| self.assertTrue(self._driver.IsAlertOpen()) |
| self.assertEquals('GreenRectangle has been dropped into a folder.', |
| self._driver.GetAlertMessage()) |
| self._driver.HandleAlert(True) |
| self.assertEquals('translate(300,55)', drag.GetAttribute("transform")) |
| |
| def testMouseButtonDownAndUp(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("mousedown", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new1<br>";' |
| '});' |
| 'div.addEventListener("mouseup", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new2<a></a>";' |
| '});') |
| self._driver.MouseMoveTo(None, 50, 50) |
| self._driver.MouseButtonDown() |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| self._driver.MouseButtonUp() |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'a'))) |
| |
| def testMouseClick(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| div = self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("click", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| self._driver.MouseMoveTo(div) |
| self._driver.MouseClick() |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testMouseDoubleClick(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| div = self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("dblclick", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| self._driver.MouseMoveTo(div, 1, 1) |
| self._driver.MouseDoubleClick() |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testMouseMoveTo(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| div = self._driver.ExecuteScript( |
| 'document.body.innerHTML = "<div>old</div>";' |
| 'var div = document.getElementsByTagName("div")[0];' |
| 'div.style["width"] = "100px";' |
| 'div.style["height"] = "100px";' |
| 'div.addEventListener("mouseover", function() {' |
| ' var div = document.getElementsByTagName("div")[0];' |
| ' div.innerHTML="new<br>";' |
| '});' |
| 'return div;') |
| self._driver.MouseMoveTo(div, 10, 10) |
| self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) |
| |
| def testMoveToElementAndClick(self): |
| # This page gets rendered differently depending on which platform the test |
| # is running on, and what window size is being used. So we need to do some |
| # sanity checks to make sure that the <a> element is split across two lines |
| # of text. |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/multiline.html')) |
| |
| # Check that link element spans two lines and that the first ClientRect is |
| # above the second. |
| link = self._driver.FindElements('tag name', 'a')[0] |
| client_rects = self._driver.ExecuteScript( |
| 'return arguments[0].getClientRects();', link) |
| self.assertEquals(2, len(client_rects)) |
| self.assertTrue(client_rects[0]['bottom'] <= client_rects[1]['top']) |
| |
| # Check that the center of the link's bounding ClientRect is outside the |
| # element. |
| bounding_client_rect = self._driver.ExecuteScript( |
| 'return arguments[0].getBoundingClientRect();', link) |
| center = bounding_client_rect['left'] + bounding_client_rect['width'] / 2 |
| self.assertTrue(client_rects[1]['right'] < center) |
| self.assertTrue(center < client_rects[0]['left']) |
| |
| self._driver.MouseMoveTo(link) |
| self._driver.MouseClick() |
| self.assertTrue(self._driver.GetCurrentUrl().endswith('#top')) |
| |
| |
| def _FindElementInShadowDom(self, css_selectors): |
| """Find an element inside shadow DOM using CSS selectors. |
| The last item in css_selectors identify the element to find. All preceding |
| selectors identify the hierarchy of shadow hosts to traverse in order to |
| reach the target shadow DOM.""" |
| current = None |
| for selector in css_selectors: |
| if current is None: |
| # First CSS selector, start from root DOM. |
| current = self._driver |
| else: |
| # current is a shadow host selected previously. |
| # Enter the corresponding shadow root. |
| current = self._driver.ExecuteScript( |
| 'return arguments[0].shadowRoot', current) |
| current = current.FindElement('css selector', selector) |
| return current |
| |
| def testShadowDomDisplayed(self): |
| """Checks that trying to manipulate shadow DOM elements that are detached |
| from the document raises a StaleElementReference exception""" |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/shadow_dom_test.html')) |
| elem = self._FindElementInShadowDom( |
| ["#innerDiv", "#parentDiv", "#button"]) |
| self.assertTrue(elem.IsDisplayed()) |
| elem2 = self._driver.FindElement("css selector", "#hostContent") |
| self.assertTrue(elem2.IsDisplayed()) |
| self._driver.ExecuteScript( |
| 'document.querySelector("#outerDiv").style.display="None";') |
| self.assertFalse(elem.IsDisplayed()) |
| |
| def testSendingTabKeyMovesToNextInputElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/two_inputs.html')) |
| first = self._driver.FindElement('css selector', '#first') |
| second = self._driver.FindElement('css selector', '#second') |
| first.Click() |
| self._driver.SendKeys('snoopy') |
| self._driver.SendKeys(u'\uE004') |
| self._driver.SendKeys('prickly pete') |
| self.assertEquals('snoopy', self._driver.ExecuteScript( |
| 'return arguments[0].value;', first)) |
| self.assertEquals('prickly pete', self._driver.ExecuteScript( |
| 'return arguments[0].value;', second)) |
| |
| def testMobileEmulationDisabledByDefault(self): |
| self.assertFalse(self._driver.capabilities['mobileEmulationEnabled']) |
| |
| def testSendKeysToElement(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| text = self._driver.ExecuteScript( |
| 'document.body.innerHTML = \'<input type="text">\';' |
| 'var input = document.getElementsByTagName("input")[0];' |
| 'input.addEventListener("change", function() {' |
| ' document.body.appendChild(document.createElement("br"));' |
| '});' |
| 'return input;') |
| text.SendKeys('0123456789+-*/ Hi') |
| text.SendKeys(', there!') |
| value = self._driver.ExecuteScript('return arguments[0].value;', text) |
| self.assertEquals('0123456789+-*/ Hi, there!', value) |
| |
| def testUnexpectedAlertOpenExceptionMessage(self): |
| self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) |
| self._driver.ExecuteScript('window.alert("Hi");') |
| self.assertRaisesRegexp(chromedriver.UnexpectedAlertOpen, |
| 'unexpected alert open: {Alert text : Hi}', |
| self._driver.FindElement, 'tag name', 'divine') |
| |
| def testTouchScrollElement(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/touch_action_tests.html')) |
| scroll_left = 'return document.documentElement.scrollLeft;' |
| scroll_top = 'return document.documentElement.scrollTop;' |
| self.assertEquals(0, self._driver.ExecuteScript(scroll_left)) |
| self.assertEquals(0, self._driver.ExecuteScript(scroll_top)) |
| target = self._driver.FindElement('css selector', '#target') |
| self._driver.TouchScroll(target, 47, 53) |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1179 |
| self.assertAlmostEqual(47, self._driver.ExecuteScript(scroll_left), delta=1) |
| self.assertAlmostEqual(53, self._driver.ExecuteScript(scroll_top), delta=1) |
| |
| def testTouchDoubleTapElement(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/touch_action_tests.html')) |
| target = self._driver.FindElement('css selector', '#target') |
| target.DoubleTap() |
| events = self._driver.FindElement('css selector', '#events') |
| self.assertEquals('events: touchstart touchend touchstart touchend', |
| events.GetText()) |
| |
| def testTouchLongPressElement(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/touch_action_tests.html')) |
| target = self._driver.FindElement('css selector', '#target') |
| target.LongPress() |
| events = self._driver.FindElement('css selector', '#events') |
| self.assertEquals('events: touchstart touchcancel', events.GetText()) |
| |
| def testTouchSingleTapElement(self): |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/touch_action_tests.html')) |
| target = self._driver.FindElement('css selector', '#target') |
| target.SingleTap() |
| events = self._driver.FindElement('css selector', '#events') |
| self.assertEquals('events: touchstart touchend', events.GetText()) |
| |
| class ChromeDriverSiteIsolation(ChromeDriverBaseTestWithWebServer): |
| """Tests for ChromeDriver with the new Site Isolation Chrome feature. |
| |
| This feature can be turned on using the --site-per-process flag. |
| |
| In order to trick the test into thinking that we are on two separate origins, |
| the cross_domain_iframe.html code points to localhost instead of 127.0.0.1. |
| |
| Note that Chrome does not allow "localhost" to be passed to --isolate-origins |
| for fixable technical reasons related to subdomain matching. |
| """ |
| |
| def setUp(self): |
| self._driver = self.CreateDriver(chrome_switches=['--site-per-process']) |
| |
| def testCanClickOOPIF(self): |
| """Test that you can click into an Out of Process I-Frame (OOPIF). |
| |
| Note that the Iframe will not be out-of-process if the correct |
| flags are not passed into Chrome. |
| """ |
| if util.GetPlatformName() == 'win': |
| # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2198 |
| # This test is unreliable on Windows, as FindElement can be called too |
| # soon, before the child frame is fully loaded. This causes element not |
| # found error. Add an implicit wait works around this issue. |
| self._driver.SetTimeouts({'implicit': 2000}) |
| self._driver.Load(self.GetHttpUrlForFile( |
| '/chromedriver/cross_domain_iframe.html')) |
| a_outer = self._driver.FindElement('tag name', 'a') |
| a_outer.Click() |
| frame_url = self._driver.ExecuteScript('return window.location.href') |
| self.assertTrue(frame_url.endswith('#one')) |
| frame = self._driver.FindElement('tag name', 'iframe') |
| self._driver.SwitchToFrame(frame) |
| a_inner = self._driver.FindElement('tag name', 'a') |
| a_inner.Click() |
| frame_url = self._driver.ExecuteScript('return window.location.href') |
| self.assertTrue(frame_url.endswith('#two')) |
| |
| |
| class ChromeDriverPageLoadTimeoutTest(ChromeDriverBaseTestWithWebServer): |
| |
| class _RequestHandler(object): |
| def __init__(self): |
| self.request_received_event = threading.Event() |
| self.send_response_event = threading.Event() |
| |
| def handle(self, request): |
| self.request_received_event.set() |
| # Don't hang infinitely, 10 seconds are enough. |
| self.send_response_event.wait(10) |
| self.send_response_event.clear() |
| return {'Cache-Control': 'no-store'}, 'Hi!' |
| |
| def setUp(self): |
| self._handler = ChromeDriverPageLoadTimeoutTest._RequestHandler() |
| self._http_server.SetCallbackForPath('/hang', self._handler.handle) |
| super(ChromeDriverPageLoadTimeoutTest, self).setUp() |
| |
| self._driver = self.CreateDriver( |
| chrome_switches=['host-resolver-rules=MAP * 127.0.0.1']) |
| self._initial_url = self.GetHttpUrlForFile('/chromedriver/empty.html') |
| self._driver.Load(self._initial_url) |
| # When send_response_event is set, navigating to the hang URL takes only |
| # about 0.1 second on Linux and Windows, but takes half a second or longer |
| # on Mac. So we use longer timeout on Mac, 0.5 second on others. |
| timeout = 3000 if util.GetPlatformName() == 'mac' else 500 |
| self._driver.SetTimeouts({'pageLoad': timeout}) |
| |
| def tearDown(self): |
| super(ChromeDriverPageLoadTimeoutTest, self).tearDown() |
| self._http_server.SetCallbackForPath('/hang', None) |
| |
| def _LoadHangingUrl(self, host=None): |
| self._driver.Load(self._http_server.GetUrl(host) + '/hang') |
| |
| def _CheckPageLoadTimeout(self, action): |
| self._handler.request_received_event.clear() |
| timed_out = False |
| try: |
| action() |
| except chromedriver.ChromeDriverException as e: |
| self.assertNotEqual(-1, e.message.find('timeout')) |
| timed_out = True |
| finally: |
| self._handler.send_response_event.set() |
| |
| self.assertTrue(timed_out) |
| # Verify that the browser actually made that request. |
| self.assertTrue(self._handler.request_received_event.wait(1)) |
| |
| def testPageLoadTimeout(self): |
| self._CheckPageLoadTimeout(self._LoadHangingUrl) |
| self.assertEquals(self._initial_url, self._driver.GetCurrentUrl()) |
| |
| def testPageLoadTimeoutCrossDomain(self): |
| # Cross-domain navigation is likely to be a cross-process one. In this case |
| # DevToolsAgentHost behaves quite differently and does not send command |
| # responses if the navigation hangs, so this case deserves a dedicated test. |
| self._CheckPageLoadTimeout(lambda: self._LoadHangingUrl('foo.bar')) |
| self.assertEquals(self._initial_url, self._driver.GetCurrentUrl()) |
| |
| def testHistoryNavigationWithPageLoadTimeout(self): |
| # Allow the page to load for the first time. |
| self._handler.send_response_event.set() |
| self._LoadHangingUrl() |
| self.assertTrue(self._handler.request_received_event.wait(1)) |
| |
| self._driver.GoBack() |
| self._CheckPageLoadTimeout(self._driver.GoForward) |
| self.assertEquals(self._initial_url, self._driver.GetCurrentUrl()) |
| |
| def testRefreshWithPageLoadTimeout(self): |
| # Allow the page to load for the first time. |
| self._handler.send_response_event.set() |
| self._LoadHangingUrl() |
| self.assertTrue(self._handler.request_received_event.wait(1)) |
| |
| self._CheckPageLoadTimeout(self._driver.Refresh) |
| |
| |
| class ChromeDriverAndroidTest(ChromeDriverBaseTest): |
| """End to end tests for Android-specific tests.""" |
| |
| def testLatestAndroidAppInstalled(self): |
| if ('stable' not in _ANDROID_PACKAGE_KEY and |
| 'beta' not in _ANDROID_PACKAGE_KEY): |
| return |
| |
| self._driver = self.CreateDriver() |
| |
| try: |
| omaha_list = json.loads( |
| urllib2.urlopen('http://omahaproxy.appspot.com/all.json').read()) |
| for l in omaha_list: |
| if l['os'] != 'android': |
| continue |
| for v in l['versions']: |
| if (('stable' in v['channel'] and 'stable' in _ANDROID_PACKAGE_KEY) or |
| ('beta' in v['channel'] and 'beta' in _ANDROID_PACKAGE_KEY)): |
| omaha = map(int, v['version'].split('.')) |
| device = map(int, self._driver.capabilities['version'].split('.')) |
| self.assertTrue(omaha <= device) |
| return |
| raise RuntimeError('Malformed omaha JSON') |
| except urllib2.URLError as e: |
| print 'Unable to fetch current version info from omahaproxy (%s)' % e |
| |
| def testDeviceManagement(self): |
| self._drivers = [self.CreateDriver() |
| for _ in device_utils.DeviceUtils.HealthyDevices()] |
| self.assertRaises(chromedriver.UnknownError, self.CreateDriver) |
| self._drivers[0].Quit() |
| self._drivers[0] = self.CreateDriver() |
| |
| def testScreenOrientation(self): |
| self._driver = self.CreateDriver() |
| self._driver.Load( |
| ChromeDriverTest.GetHttpUrlForFile('/chromedriver/orientation_test.html')) |
| screen_orientation_js = self._driver.ExecuteScript( |
| 'return screen.orientation.type') |
| screen_orientation = self._driver.GetScreenOrientation()['orientation'] |
| if screen_orientation == "LANDSCAPE": |
| screen_orientation = 'landscape-primary' |
| elif screen_orientation == "PORTRAIT": |
| screen_orientation = 'portrait-primary' |
| self.assertEqual(screen_orientation, screen_orientation_js) |
| |
| self._driver.SetScreenOrientation("portrait-primary") |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.WaitForCondition( |
| lambda: 'orientation change 1' in self._driver.FindElement( |
| 'tag name', 'div').GetText()) |
| self.assertEqual(screen_orientation['orientation'], "PORTRAIT") |
| |
| self._driver.SetScreenOrientation("portrait-secondary") |
| self.WaitForCondition( |
| lambda: 'orientation change 2' in self._driver.FindElement( |
| 'tag name', 'div').GetText()) |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(screen_orientation['orientation'], "PORTRAIT") |
| |
| self._driver.SetScreenOrientation("PORTRAIT") |
| self.WaitForCondition( |
| lambda: 'orientation change 3' in self._driver.FindElement( |
| 'tag name', 'div').GetText()) |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(screen_orientation['orientation'], "PORTRAIT") |
| |
| self._driver.SetScreenOrientation("landscape-primary") |
| self.WaitForCondition( |
| lambda: 'orientation change 4' in self._driver.FindElement( |
| 'tag name', 'div').GetText()) |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") |
| |
| self._driver.SetScreenOrientation("landscape-secondary") |
| self.WaitForCondition( |
| lambda: 'orientation change 5' in self._driver.FindElement( |
| 'tag name', 'div').GetText()) |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") |
| |
| self._driver.SetScreenOrientation("LANDSCAPE") |
| self.WaitForCondition( |
| lambda: 'orientation change 6' in self._driver.FindElement( |
| 'tag name', 'div').GetText()) |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") |
| |
| def testMultipleScreenOrientationChanges(self): |
| self._driver = self.CreateDriver() |
| |
| self._driver.SetScreenOrientation('PORTRAIT') |
| self.assertEqual( |
| self._driver.GetScreenOrientation()['orientation'], 'PORTRAIT') |
| |
| self._driver.SetScreenOrientation('PORTRAIT') |
| self.assertEqual( |
| self._driver.GetScreenOrientation()['orientation'], 'PORTRAIT') |
| |
| self._driver.DeleteScreenOrientation() |
| self._driver.DeleteScreenOrientation() |
| |
| def testDeleteScreenOrientationManual(self): |
| self._driver = self.CreateDriver() |
| |
| manual_test = False; |
| |
| self._driver.SetScreenOrientation("LANDSCAPE") |
| screen_orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") |
| if(manual_test): |
| time.sleep(10) |
| # While sleeping, test that the orientation cannot be changed. |
| |
| print "Screen orientation lock deleted." |
| self._driver.DeleteScreenOrientation(); |
| if(manual_test): |
| time.sleep(10) |
| # While sleeping, test that orientation can be changed by manually |
| # rotating the device. |
| |
| def testScreenOrientationAcrossMultipleTabs(self): |
| self._driver = self.CreateDriver() |
| |
| self._driver.SetScreenOrientation('LANDSCAPE') |
| self._driver.Load( |
| ChromeDriverTest.GetHttpUrlForFile('/chromedriver/page_test.html')) |
| window1 = self._driver.GetCurrentWindowHandle() |
| self._driver.FindElement('css selector', '#link').Click() |
| orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(orientation['orientation'], 'LANDSCAPE') |
| |
| self._driver.ExecuteScript('window.name = "oldWindow";') |
| self._driver.SwitchToWindow('oldWindow') |
| self.assertEqual(window1, self._driver.GetCurrentWindowHandle()) |
| orientation = self._driver.GetScreenOrientation() |
| self.assertEqual(orientation['orientation'], 'LANDSCAPE') |
| |
| def testAndroidGetWindowSize(self): |
| self._driver = self.CreateDriver() |
| size = self._driver.GetWindowRect() |
| |
| script_size = self._driver.ExecuteScript( |
| "return [window.outerWidth * window.devicePixelRatio," |
| "window.outerHeight * window.devicePixelRatio, 0, 0]") |
| self.assertEquals(size, script_size) |
| |
| script_inner = self._driver.ExecuteScript( |
| "return [window.innerWidth, window.innerHeight]") |
| self.assertLessEqual(script_inner[0], size[0]) |
| self.assertLessEqual(script_inner[1], size[1]) |
| # Sanity check: screen dimensions in the range 2-20000px |
| self.assertLessEqual(size[0], 20000) |
| self.assertLessEqual(size[1], 20000) |
| self.assertGreaterEqual(size[0], 2) |
| self.assertGreaterEqual(size[1], 2) |
| |
| class ChromeDownloadDirTest(ChromeDriverBaseTest): |
| |
| def __init__(self, *args, **kwargs): |
| super(ChromeDownloadDirTest, self).__init__(*args, **kwargs) |
| self._temp_dirs = [] |
| |
| def CreateTempDir(self): |
| temp_dir = tempfile.mkdtemp() |
| self._temp_dirs.append(temp_dir) |
| return temp_dir |
| |
| def RespondWithCsvFile(self, request): |
| return {'Content-Type': 'text/csv'}, 'a,b,c\n1,2,3\n' |
| |
| def WaitForFileToDownload(self, path): |
| deadline = time.time() + 60 |
| while True: |
| time.sleep(0.1) |
| if os.path.isfile(path) or time.time() > deadline: |
| break |
| self.assertTrue(os.path.isfile(path), "Failed to download file!") |
| |
| def tearDown(self): |
| # Call the superclass tearDown() method before deleting temp dirs, so that |
| # Chrome has a chance to exit before its user data dir is blown away from |
| # underneath it. |
| super(ChromeDownloadDirTest, self).tearDown() |
| for temp_dir in self._temp_dirs: |
| # Deleting temp dir can fail if Chrome hasn't yet fully exited and still |
| # has open files in there. So we ignore errors, and retry if necessary. |
| shutil.rmtree(temp_dir, ignore_errors=True) |
| retry = 0 |
| while retry < 10 and os.path.exists(temp_dir): |
| time.sleep(0.1) |
| shutil.rmtree(temp_dir, ignore_errors=True) |
| |
| def testFileDownloadWithClick(self): |
| download_dir = self.CreateTempDir() |
| download_name = os.path.join(download_dir, 'a_red_dot.png') |
| driver = self.CreateDriver(download_dir=download_dir) |
| driver.Load(ChromeDriverTest.GetHttpUrlForFile( |
| '/chromedriver/download.html')) |
| driver.FindElement('css selector', '#red-dot').Click() |
| self.WaitForFileToDownload(download_name) |
| self.assertEqual( |
| ChromeDriverTest.GetHttpUrlForFile('/chromedriver/download.html'), |
| driver.GetCurrentUrl()) |
| |
| def testFileDownloadWithGet(self): |
| ChromeDriverTest._http_server.SetCallbackForPath( |
| '/abc.csv', self.RespondWithCsvFile) |
| download_dir = self.CreateTempDir() |
| driver = self.CreateDriver(download_dir=download_dir) |
| original_url = driver.GetCurrentUrl() |
| driver.Load(ChromeDriverTest.GetHttpUrlForFile('/abc.csv')) |
| self.WaitForFileToDownload(os.path.join(download_dir, 'abc.csv')) |
| self.assertEqual(original_url, driver.GetCurrentUrl()) |
| |
| def testDownloadDirectoryOverridesExistingPreferences(self): |
| user_data_dir = self.CreateTempDir() |
| download_dir = self.CreateTempDir() |
| sub_dir = os.path.join(user_data_dir, 'Default') |
| os.mkdir(sub_dir) |
| prefs_file_path = os.path.join(sub_dir, 'Preferences') |
| |
| prefs = { |
| 'test': 'this should not be changed', |
| 'download': { |
| 'default_directory': '/old/download/directory' |
| } |
| } |
| |
| with open(prefs_file_path, 'w') as f: |
| json.dump(prefs, f) |
| |
| driver = self.CreateDriver( |
| chrome_switches=['user-data-dir=' + user_data_dir], |
| download_dir=download_dir) |
| |
| with open(prefs_file_path) as f: |
| prefs = json.load(f) |
| |
| self.assertEqual('this should not be changed', prefs['test']) |
| download = prefs['download'] |
| self.assertEqual(download['default_directory'], download_dir) |
| |
| |
| class ChromeSwitchesCapabilityTest(ChromeDriverBaseTest): |
| """Tests that chromedriver properly processes chromeOptions.args capabilities. |
| |
| Makes sure the switches are passed to Chrome. |
| """ |
| |
| def testSwitchWithoutArgument(self): |
| """Tests that switch --dom-automation can be passed to Chrome. |
| |
| Unless --dom-automation is specified, window.domAutomationController |
| is undefined. |
| """ |
| driver = self.CreateDriver(chrome_switches=['dom-automation']) |
| self.assertNotEqual( |
| None, |
| driver.ExecuteScript('return window.domAutomationController')) |
| |
| def testRemoteDebuggingPort(self): |
| """Tests that passing --remote-debugging-port through capabilities works. |
| """ |
| # Must use retries since there is an inherent race condition in port |
| # selection. |
| ports_generator = util.FindProbableFreePorts() |
| for _ in range(3): |
| port = ports_generator.next() |
| port_flag = 'remote-debugging-port=%s' % port |
| try: |
| driver = self.CreateDriver(chrome_switches=[port_flag]) |
| except: |
| continue |
| driver.Load('chrome:version') |
| command_line = driver.FindElement('css selector', |
| '#command_line').GetText() |
| self.assertIn(port_flag, command_line) |
| break |
| else: # Else clause gets invoked if "break" never happens. |
| raise # This re-raises the most recent exception. |
| |
| |
| class ChromeDesiredCapabilityTest(ChromeDriverBaseTest): |
| """Tests that chromedriver properly processes desired capabilities.""" |
| |
| def testDefaultTimeouts(self): |
| driver = self.CreateDriver() |
| timeouts = driver.GetTimeouts() |
| # Compare against defaults in W3C spec |
| self.assertEquals(timeouts['implicit'], 0) |
| self.assertEquals(timeouts['pageLoad'], 300000) |
| self.assertEquals(timeouts['script'], 30000) |
| |
| def testTimeouts(self): |
| driver = self.CreateDriver(timeouts = { |
| 'implicit': 123, |
| 'pageLoad': 456, |
| 'script': 789 |
| }) |
| timeouts = driver.GetTimeouts() |
| self.assertEquals(timeouts['implicit'], 123) |
| self.assertEquals(timeouts['pageLoad'], 456) |
| self.assertEquals(timeouts['script'], 789) |
| |
| # Run in Legacy mode |
| def testUnexpectedAlertBehaviourLegacy(self): |
| driver = self.CreateDriver(unexpected_alert_behaviour="accept", |
| send_w3c_capability=False, |
| send_w3c_request=False) |
| self.assertEquals("accept", |
| driver.capabilities['unexpectedAlertBehaviour']) |
| driver.ExecuteScript('alert("HI");') |
| self.WaitForCondition(driver.IsAlertOpen) |
| self.assertRaisesRegexp(chromedriver.UnexpectedAlertOpen, |
| 'unexpected alert open: {Alert text : HI}', |
| driver.FindElement, 'tag name', 'div') |
| self.assertFalse(driver.IsAlertOpen()) |
| |
| def testUnexpectedAlertBehaviourW3c(self): |
| driver = self.CreateDriver(unexpected_alert_behaviour='accept', |
| send_w3c_capability=True, send_w3c_request=True) |
| self.assertEquals('accept', |
| driver.capabilities['unhandledPromptBehavior']) |
| driver.ExecuteScript('alert("HI");') |
| self.WaitForCondition(driver.IsAlertOpen) |
| # With unhandledPromptBehavior=accept, calling GetTitle (and most other |
| # endpoints) automatically dismisses the alert, so IsAlertOpen() becomes |
| # False afterwards. |
| self.assertEquals(driver.GetTitle(), '') |
| self.assertFalse(driver.IsAlertOpen()) |
| |
| |
| class ChromeExtensionsCapabilityTest(ChromeDriverBaseTest): |
| """Tests that chromedriver properly processes chromeOptions.extensions.""" |
| |
| def _PackExtension(self, ext_path): |
| return base64.b64encode(open(ext_path, 'rb').read()) |
| |
| def testExtensionsInstall(self): |
| """Checks that chromedriver can take the extensions in crx format.""" |
| crx_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.crx') |
| crx_2 = os.path.join(_TEST_DATA_DIR, 'ext_test_2.crx') |
| self.CreateDriver(chrome_extensions=[self._PackExtension(crx_1), |
| self._PackExtension(crx_2)]) |
| |
| def testExtensionsInstallZip(self): |
| """Checks that chromedriver can take the extensions in zip format.""" |
| zip_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.zip') |
| self.CreateDriver(chrome_extensions=[self._PackExtension(zip_1)]) |
| |
| def testWaitsForExtensionToLoad(self): |
| did_load_event = threading.Event() |
| server = webserver.SyncWebServer() |
| def RunServer(): |
| time.sleep(5) |
| server.RespondWithContent('<html>iframe</html>') |
| did_load_event.set() |
| |
| thread = threading.Thread(target=RunServer) |
| thread.daemon = True |
| thread.start() |
| crx = os.path.join(_TEST_DATA_DIR, 'ext_slow_loader.crx') |
| driver = self.CreateDriver( |
| chrome_switches=['user-agent=' + server.GetUrl()], |
| chrome_extensions=[self._PackExtension(crx)]) |
| self.assertTrue(did_load_event.is_set()) |
| |
| def testCanLaunchApp(self): |
| app_path = os.path.join(_TEST_DATA_DIR, 'test_app') |
| driver = self.CreateDriver(chrome_switches=['load-extension=%s' % app_path]) |
| old_handles = driver.GetWindowHandles() |
| self.assertEqual(1, len(old_handles)) |
| driver.LaunchApp('gegjcdcfeiojglhifpmibkadodekakpc') |
| new_window_handle = self.WaitForNewWindow(driver, old_handles) |
| driver.SwitchToWindow(new_window_handle) |
| body_element = driver.FindElement('tag name', 'body') |
| self.assertEqual('It works!', body_element.GetText()) |
| |
| def testCanInspectBackgroundPage(self): |
| app_path = os.path.join(_TEST_DATA_DIR, 'test_app') |
| extension_path = os.path.join(_TEST_DATA_DIR, 'all_frames') |
| driver = self.CreateDriver( |
| chrome_switches=['load-extension=%s' % app_path], |
| experimental_options={'windowTypes': ['background_page']}) |
| old_handles = driver.GetWindowHandles() |
| driver.LaunchApp('gegjcdcfeiojglhifpmibkadodekakpc') |
| new_window_handle = self.WaitForNewWindow( |
| driver, old_handles, check_closed_windows=False) |
| handles = driver.GetWindowHandles() |
| for handle in handles: |
| driver.SwitchToWindow(handle) |
| if driver.GetCurrentUrl() == 'chrome-extension://' \ |
| 'gegjcdcfeiojglhifpmibkadodekakpc/_generated_background_page.html': |
| self.assertEqual(42, driver.ExecuteScript('return magic;')) |
| return |
| self.fail("couldn't find generated background page for test app") |
| |
| def testIFrameWithExtensionsSource(self): |
| crx_path = os.path.join(_TEST_DATA_DIR, 'frames_extension.crx') |
| driver = self.CreateDriver( |
| chrome_extensions=[self._PackExtension(crx_path)]) |
| driver.Load( |
| ChromeDriverTest._http_server.GetUrl() + |
| '/chromedriver/iframe_extension.html') |
| driver.SwitchToFrame('testframe') |
| element = driver.FindElement('css selector', '#p1') |
| self.assertEqual('Its a frame with extension source', element.GetText()) |
| |
| def testDontExecuteScriptsInContentScriptContext(self): |
| # This test extension has a content script which runs in all frames (see |
| # https://developer.chrome.com/extensions/content_scripts) which causes each |
| # frame on the page to be associated with multiple JS execution contexts. |
| # Make sure that ExecuteScript operates on the page's context, rather than |
| # the extension's content script's one. |
| extension_path = os.path.join(_TEST_DATA_DIR, 'all_frames') |
| driver = self.CreateDriver( |
| chrome_switches=['load-extension=%s' % extension_path]) |
| driver.Load( |
| ChromeDriverTest._http_server.GetUrl() + '/chromedriver/container.html') |
| driver.SwitchToMainFrame() |
| self.assertEqual('one', driver.ExecuteScript("return window['global_var']")) |
| driver.SwitchToFrame('iframe') |
| self.assertEqual('two', driver.ExecuteScript("return window['iframe_var']")) |
| |
| def testDontUseAutomationExtension(self): |
| driver = self.CreateDriver( |
| experimental_options={'useAutomationExtension': False}) |
| driver.Load('chrome:version') |
| command_line = driver.FindElement('css selector', '#command_line').GetText() |
| self.assertNotIn('load-extension', command_line) |
| |
| |
| class ChromeLogPathCapabilityTest(ChromeDriverBaseTest): |
| |