2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """End to end tests for ChromeDriver."""
22 _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
23 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))
24 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir, 'client'))
25 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir, 'server'))
32 from webelement import WebElement
35 _TEST_DATA_DIR = os.path.join(chrome_paths.GetTestData(), 'chromedriver')
38 sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android'))
39 from pylib import android_commands
40 from pylib import constants
41 from pylib import forwarder
42 from pylib import valgrind_tools
46 # https://code.google.com/p/chromedriver/issues/detail?id=213
47 'ChromeDriverTest.testClickElementInSubFrame',
48 # This test is flaky since it uses setTimeout.
49 # Re-enable once crbug.com/177511 is fixed and we can remove setTimeout.
50 'ChromeDriverTest.testAlert',
53 _VERSION_SPECIFIC_FILTER = {}
54 _VERSION_SPECIFIC_FILTER['HEAD'] = []
56 _OS_SPECIFIC_FILTER = {}
57 _OS_SPECIFIC_FILTER['win'] = [
58 # https://code.google.com/p/chromedriver/issues/detail?id=214
59 'ChromeDriverTest.testCloseWindow',
60 # https://code.google.com/p/chromedriver/issues/detail?id=299
61 'ChromeLogPathCapabilityTest.testChromeLogPath',
63 _OS_SPECIFIC_FILTER['linux'] = [
64 # Xvfb doesn't support maximization.
65 'ChromeDriverTest.testWindowMaximize',
66 # https://code.google.com/p/chromedriver/issues/detail?id=302
67 'ChromeDriverTest.testWindowPosition',
68 'ChromeDriverTest.testWindowSize',
70 _OS_SPECIFIC_FILTER['mac'] = [
71 # https://code.google.com/p/chromedriver/issues/detail?id=304
72 'ChromeDriverTest.testGoBackAndGoForward',
75 _DESKTOP_NEGATIVE_FILTER = [
76 # Desktop doesn't support touch (without --touch-events).
77 'ChromeDriverTest.testSingleTapElement',
78 'ChromeDriverTest.testTouchDownUpElement',
79 'ChromeDriverTest.testTouchFlickElement',
80 'ChromeDriverTest.testTouchMovedElement',
81 'ChromeDriverAndroidTest.*',
85 def _GetDesktopNegativeFilter(version_name):
86 filter = _NEGATIVE_FILTER + _DESKTOP_NEGATIVE_FILTER
87 os = util.GetPlatformName()
88 if os in _OS_SPECIFIC_FILTER:
89 filter += _OS_SPECIFIC_FILTER[os]
90 if version_name in _VERSION_SPECIFIC_FILTER:
91 filter += _VERSION_SPECIFIC_FILTER[version_name]
94 _ANDROID_NEGATIVE_FILTER = {}
95 _ANDROID_NEGATIVE_FILTER['chrome'] = (
97 # TODO(chrisgao): fix hang of tab crash test on android.
98 'ChromeDriverTest.testTabCrash',
99 # Android doesn't support switches and extensions.
100 'ChromeSwitchesCapabilityTest.*',
101 'ChromeExtensionsCapabilityTest.*',
102 # https://crbug.com/274650
103 'ChromeDriverTest.testCloseWindow',
104 # https://code.google.com/p/chromedriver/issues/detail?id=270
105 'ChromeDriverTest.testPopups',
106 # https://code.google.com/p/chromedriver/issues/detail?id=298
107 'ChromeDriverTest.testWindowPosition',
108 'ChromeDriverTest.testWindowSize',
109 'ChromeDriverTest.testWindowMaximize',
110 'ChromeLogPathCapabilityTest.testChromeLogPath',
111 'ExistingBrowserTest.*',
112 # Don't enable perf testing on Android yet.
113 'PerfTest.testSessionStartTime',
114 'PerfTest.testSessionStopTime',
115 'PerfTest.testColdExecuteScript',
116 # https://code.google.com/p/chromedriver/issues/detail?id=459
117 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
120 _ANDROID_NEGATIVE_FILTER['chrome_stable'] = (
121 _ANDROID_NEGATIVE_FILTER['chrome'])
122 _ANDROID_NEGATIVE_FILTER['chrome_beta'] = (
123 _ANDROID_NEGATIVE_FILTER['chrome'])
124 _ANDROID_NEGATIVE_FILTER['chromium_test_shell'] = (
125 _ANDROID_NEGATIVE_FILTER['chrome'] + [
126 # ChromiumTestShell doesn't support multiple tabs.
127 'ChromeDriverTest.testGetWindowHandles',
128 'ChromeDriverTest.testSwitchToWindow',
129 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
132 _ANDROID_NEGATIVE_FILTER['chromedriver_webview_shell'] = (
133 _ANDROID_NEGATIVE_FILTER['chromium_test_shell'])
136 class ChromeDriverBaseTest(unittest.TestCase):
137 """Base class for testing chromedriver functionalities."""
139 def __init__(self, *args, **kwargs):
140 super(ChromeDriverBaseTest, self).__init__(*args, **kwargs)
144 for driver in self._drivers:
150 def CreateDriver(self, server_url=None, **kwargs):
151 if server_url is None:
152 server_url = _CHROMEDRIVER_SERVER_URL
154 android_package = None
155 android_activity = None
156 android_process = None
157 if _ANDROID_PACKAGE_KEY:
158 android_package = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].package
159 if _ANDROID_PACKAGE_KEY == 'chromedriver_webview_shell':
160 android_activity = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].activity
161 android_process = '%s:main' % android_package
163 driver = chromedriver.ChromeDriver(server_url,
164 chrome_binary=_CHROME_BINARY,
165 android_package=android_package,
166 android_activity=android_activity,
167 android_process=android_process,
169 self._drivers += [driver]
173 class ChromeDriverTest(ChromeDriverBaseTest):
174 """End to end tests for ChromeDriver."""
178 ChromeDriverTest._http_server = webserver.WebServer(
179 chrome_paths.GetTestData())
180 ChromeDriverTest._sync_server = webserver.SyncWebServer()
181 if _ANDROID_PACKAGE_KEY:
182 ChromeDriverTest._adb = android_commands.AndroidCommands(
183 android_commands.GetAttachedDevices()[0])
184 http_host_port = ChromeDriverTest._http_server._server.server_port
185 sync_host_port = ChromeDriverTest._sync_server._server.server_port
186 forwarder.Forwarder.Map(
187 [(http_host_port, http_host_port), (sync_host_port, sync_host_port)],
188 ChromeDriverTest._adb)
191 def GlobalTearDown():
192 if _ANDROID_PACKAGE_KEY:
193 forwarder.Forwarder.UnmapAllDevicePorts(ChromeDriverTest._adb)
194 ChromeDriverTest._http_server.Shutdown()
197 def GetHttpUrlForFile(file_path):
198 return ChromeDriverTest._http_server.GetUrl() + file_path
201 self._driver = self.CreateDriver()
203 def testStartStop(self):
206 def testLoadUrl(self):
207 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
209 def testGetCurrentWindowHandle(self):
210 self._driver.GetCurrentWindowHandle()
212 def _WaitForNewWindow(self, old_handles):
213 """Wait for at least one new window to show up in 20 seconds.
216 old_handles: Handles to all old windows before the new window is added.
219 Handle to a new window. None if timeout.
221 timeout = time.time() + 20
222 while time.time() < timeout:
223 new_handles = self._driver.GetWindowHandles()
224 if len(new_handles) > len(old_handles):
225 for index, old_handle in enumerate(old_handles):
226 self.assertEquals(old_handle, new_handles[index])
227 return new_handles[len(old_handles)]
231 def testCloseWindow(self):
232 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
233 old_handles = self._driver.GetWindowHandles()
234 self._driver.FindElement('id', 'link').Click()
235 new_window_handle = self._WaitForNewWindow(old_handles)
236 self.assertNotEqual(None, new_window_handle)
237 self._driver.SwitchToWindow(new_window_handle)
238 self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle())
239 self.assertRaises(chromedriver.NoSuchElement,
240 self._driver.FindElement, 'id', 'link')
241 self._driver.CloseWindow()
242 self.assertRaises(chromedriver.NoSuchWindow,
243 self._driver.GetCurrentWindowHandle)
244 new_handles = self._driver.GetWindowHandles()
245 for old_handle in old_handles:
246 self.assertTrue(old_handle in new_handles)
247 for handle in new_handles:
248 self._driver.SwitchToWindow(handle)
249 self.assertEquals(handle, self._driver.GetCurrentWindowHandle())
250 self._driver.CloseWindow()
252 def testGetWindowHandles(self):
253 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
254 old_handles = self._driver.GetWindowHandles()
255 self._driver.FindElement('id', 'link').Click()
256 self.assertNotEqual(None, self._WaitForNewWindow(old_handles))
258 def testSwitchToWindow(self):
259 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
261 1, self._driver.ExecuteScript('window.name = "oldWindow"; return 1;'))
262 window1_handle = self._driver.GetCurrentWindowHandle()
263 old_handles = self._driver.GetWindowHandles()
264 self._driver.FindElement('id', 'link').Click()
265 new_window_handle = self._WaitForNewWindow(old_handles)
266 self.assertNotEqual(None, new_window_handle)
267 self._driver.SwitchToWindow(new_window_handle)
268 self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle())
269 self.assertRaises(chromedriver.NoSuchElement,
270 self._driver.FindElement, 'id', 'link')
271 self._driver.SwitchToWindow('oldWindow')
272 self.assertEquals(window1_handle, self._driver.GetCurrentWindowHandle())
274 def testEvaluateScript(self):
275 self.assertEquals(1, self._driver.ExecuteScript('return 1'))
276 self.assertEquals(None, self._driver.ExecuteScript(''))
278 def testEvaluateScriptWithArgs(self):
279 script = ('document.body.innerHTML = "<div>b</div><div>c</div>";'
280 'return {stuff: document.querySelectorAll("div")};')
281 stuff = self._driver.ExecuteScript(script)['stuff']
282 script = 'return arguments[0].innerHTML + arguments[1].innerHTML'
284 'bc', self._driver.ExecuteScript(script, stuff[0], stuff[1]))
286 def testEvaluateInvalidScript(self):
287 self.assertRaises(chromedriver.ChromeDriverException,
288 self._driver.ExecuteScript, '{{{')
290 def testExecuteAsyncScript(self):
291 self._driver.SetTimeout('script', 3000)
293 chromedriver.ScriptTimeout,
294 self._driver.ExecuteAsyncScript,
295 'var callback = arguments[0];'
296 'setTimeout(function(){callback(1);}, 10000);')
299 self._driver.ExecuteAsyncScript(
300 'var callback = arguments[0];'
301 'setTimeout(function(){callback(2);}, 300);'))
303 def testSwitchToFrame(self):
304 self._driver.ExecuteScript(
305 'var frame = document.createElement("iframe");'
308 'document.body.appendChild(frame);')
309 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
310 self._driver.SwitchToFrame('id')
311 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
312 self._driver.SwitchToMainFrame()
313 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
314 self._driver.SwitchToFrame('name')
315 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
316 self._driver.SwitchToMainFrame()
317 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
318 self._driver.SwitchToFrameByIndex(0)
319 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
320 self._driver.SwitchToMainFrame()
321 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
322 self._driver.SwitchToFrame(self._driver.FindElement('tag name', 'iframe'))
323 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
325 def testExecuteInRemovedFrame(self):
326 self._driver.ExecuteScript(
327 'var frame = document.createElement("iframe");'
330 'document.body.appendChild(frame);'
331 'window.addEventListener("message",'
332 ' function(event) { document.body.removeChild(frame); });')
333 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
334 self._driver.SwitchToFrame('id')
335 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
336 self._driver.ExecuteScript('parent.postMessage("remove", "*");')
337 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
339 def testGetTitle(self):
340 script = 'document.title = "title"; return 1;'
341 self.assertEquals(1, self._driver.ExecuteScript(script))
342 self.assertEquals('title', self._driver.GetTitle())
344 def testGetPageSource(self):
345 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
346 self.assertTrue('Link to empty.html' in self._driver.GetPageSource())
348 def testFindElement(self):
349 self._driver.ExecuteScript(
350 'document.body.innerHTML = "<div>a</div><div>b</div>";')
352 isinstance(self._driver.FindElement('tag name', 'div'), WebElement))
354 def testFindElements(self):
355 self._driver.ExecuteScript(
356 'document.body.innerHTML = "<div>a</div><div>b</div>";')
357 divs = self._driver.FindElements('tag name', 'div')
358 self.assertTrue(isinstance(divs, list))
359 self.assertEquals(2, len(divs))
361 self.assertTrue(isinstance(div, WebElement))
363 def testFindChildElement(self):
364 self._driver.ExecuteScript(
365 'document.body.innerHTML = "<div><br><br></div><div><a></a></div>";')
366 element = self._driver.FindElement('tag name', 'div')
368 isinstance(element.FindElement('tag name', 'br'), WebElement))
370 def testFindChildElements(self):
371 self._driver.ExecuteScript(
372 'document.body.innerHTML = "<div><br><br></div><div><br></div>";')
373 element = self._driver.FindElement('tag name', 'div')
374 brs = element.FindElements('tag name', 'br')
375 self.assertTrue(isinstance(brs, list))
376 self.assertEquals(2, len(brs))
378 self.assertTrue(isinstance(br, WebElement))
380 def testHoverOverElement(self):
381 div = self._driver.ExecuteScript(
382 'document.body.innerHTML = "<div>old</div>";'
383 'var div = document.getElementsByTagName("div")[0];'
384 'div.addEventListener("mouseover", function() {'
385 ' document.body.appendChild(document.createElement("br"));'
389 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
391 def testClickElement(self):
392 div = self._driver.ExecuteScript(
393 'document.body.innerHTML = "<div>old</div>";'
394 'var div = document.getElementsByTagName("div")[0];'
395 'div.addEventListener("click", function() {'
396 ' div.innerHTML="new<br>";'
400 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
402 def testSingleTapElement(self):
403 div = self._driver.ExecuteScript(
404 'document.body.innerHTML = "<div>old</div>";'
405 'var div = document.getElementsByTagName("div")[0];'
406 'div.addEventListener("touchend", function() {'
407 ' div.innerHTML="new<br>";'
411 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
413 def testTouchDownUpElement(self):
414 div = self._driver.ExecuteScript(
415 'document.body.innerHTML = "<div>old</div>";'
416 'var div = document.getElementsByTagName("div")[0];'
417 'div.addEventListener("touchend", function() {'
418 ' div.innerHTML="new<br>";'
421 loc = div.GetLocation()
422 self._driver.TouchDown(loc['x'], loc['y'])
423 self._driver.TouchUp(loc['x'], loc['y'])
424 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
426 def testTouchFlickElement(self):
430 flickTouchEventsPerSecond = 30
432 math.sqrt(dx * dx + dy * dy) * flickTouchEventsPerSecond / speed)
433 div = self._driver.ExecuteScript(
434 'document.body.innerHTML = "<div>old</div>";'
435 'var div = document.getElementsByTagName("div")[0];'
436 'div.addEventListener("touchstart", function() {'
437 ' div.innerHTML = "preMove0";'
439 'div.addEventListener("touchmove", function() {'
440 ' res = div.innerHTML.match(/preMove(\d+)/);'
441 ' if (res != null) {'
442 ' div.innerHTML = "preMove" + (parseInt(res[1], 10) + 1);'
445 'div.addEventListener("touchend", function() {'
446 ' if (div.innerHTML == "preMove' + str(moveEvents) + '") {'
447 ' div.innerHTML = "new<br>";'
451 self._driver.TouchFlick(div, dx, dy, speed)
452 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
454 def testTouchMovedElement(self):
455 div = self._driver.ExecuteScript(
456 'document.body.innerHTML = "<div>old</div>";'
457 'var div = document.getElementsByTagName("div")[0];'
458 'div.addEventListener("touchmove", function() {'
459 ' div.innerHTML="new<br>";'
462 loc = div.GetLocation()
463 self._driver.TouchDown(loc['x'], loc['y'])
464 self._driver.TouchMove(loc['x'] + 1, loc['y'] + 1)
465 self._driver.TouchUp(loc['x'] + 1, loc['y'] + 1)
466 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
468 def testClickElementInSubFrame(self):
469 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/frame_test.html'))
470 frame = self._driver.FindElement('tag name', 'iframe')
471 self._driver.SwitchToFrame(frame)
472 # Test clicking element in the sub frame.
473 self.testClickElement()
475 def testClearElement(self):
476 text = self._driver.ExecuteScript(
477 'document.body.innerHTML = \'<input type="text" value="abc">\';'
478 'var input = document.getElementsByTagName("input")[0];'
479 'input.addEventListener("change", function() {'
480 ' document.body.appendChild(document.createElement("br"));'
484 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
486 def testSendKeysToElement(self):
487 text = self._driver.ExecuteScript(
488 'document.body.innerHTML = \'<input type="text">\';'
489 'var input = document.getElementsByTagName("input")[0];'
490 'input.addEventListener("change", function() {'
491 ' document.body.appendChild(document.createElement("br"));'
494 text.SendKeys('0123456789+-*/ Hi')
495 text.SendKeys(', there!')
496 value = self._driver.ExecuteScript('return arguments[0].value;', text)
497 self.assertEquals('0123456789+-*/ Hi, there!', value)
499 def testGetCurrentUrl(self):
500 self.assertEquals('data:,', self._driver.GetCurrentUrl())
502 def testGoBackAndGoForward(self):
503 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
504 self._driver.GoBack()
505 self._driver.GoForward()
507 def testRefresh(self):
508 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
509 self._driver.Refresh()
511 def testMouseMoveTo(self):
512 div = self._driver.ExecuteScript(
513 'document.body.innerHTML = "<div>old</div>";'
514 'var div = document.getElementsByTagName("div")[0];'
515 'div.style["width"] = "100px";'
516 'div.style["height"] = "100px";'
517 'div.addEventListener("mouseover", function() {'
518 ' var div = document.getElementsByTagName("div")[0];'
519 ' div.innerHTML="new<br>";'
522 self._driver.MouseMoveTo(div, 10, 10)
523 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
525 def testMouseClick(self):
526 div = self._driver.ExecuteScript(
527 'document.body.innerHTML = "<div>old</div>";'
528 'var div = document.getElementsByTagName("div")[0];'
529 'div.style["width"] = "100px";'
530 'div.style["height"] = "100px";'
531 'div.addEventListener("click", function() {'
532 ' var div = document.getElementsByTagName("div")[0];'
533 ' div.innerHTML="new<br>";'
536 self._driver.MouseMoveTo(div)
537 self._driver.MouseClick()
538 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
540 def testMouseButtonDownAndUp(self):
541 self._driver.ExecuteScript(
542 'document.body.innerHTML = "<div>old</div>";'
543 'var div = document.getElementsByTagName("div")[0];'
544 'div.style["width"] = "100px";'
545 'div.style["height"] = "100px";'
546 'div.addEventListener("mousedown", function() {'
547 ' var div = document.getElementsByTagName("div")[0];'
548 ' div.innerHTML="new1<br>";'
550 'div.addEventListener("mouseup", function() {'
551 ' var div = document.getElementsByTagName("div")[0];'
552 ' div.innerHTML="new2<a></a>";'
554 self._driver.MouseMoveTo(None, 50, 50)
555 self._driver.MouseButtonDown()
556 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
557 self._driver.MouseButtonUp()
558 self.assertEquals(1, len(self._driver.FindElements('tag name', 'a')))
560 def testMouseDoubleClick(self):
561 div = self._driver.ExecuteScript(
562 'document.body.innerHTML = "<div>old</div>";'
563 'var div = document.getElementsByTagName("div")[0];'
564 'div.style["width"] = "100px";'
565 'div.style["height"] = "100px";'
566 'div.addEventListener("dblclick", function() {'
567 ' var div = document.getElementsByTagName("div")[0];'
568 ' div.innerHTML="new<br>";'
571 self._driver.MouseMoveTo(div, 1, 1)
572 self._driver.MouseDoubleClick()
573 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
576 self.assertFalse(self._driver.IsAlertOpen())
577 self._driver.ExecuteScript(
579 ' function() { window.confirmed = confirm(\'HI\'); },'
581 self.assertTrue(self._driver.IsAlertOpen())
582 self.assertEquals('HI', self._driver.GetAlertMessage())
583 self._driver.HandleAlert(False)
584 self.assertFalse(self._driver.IsAlertOpen())
585 self.assertEquals(False,
586 self._driver.ExecuteScript('return window.confirmed'))
588 def testShouldHandleNewWindowLoadingProperly(self):
589 """Tests that ChromeDriver determines loading correctly for new windows."""
590 self._http_server.SetDataForPath(
595 <a href='%s' target='_blank'>new window/tab</a>
597 </html>""" % self._sync_server.GetUrl())
598 self._driver.Load(self._http_server.GetUrl() + '/newwindow')
599 old_windows = self._driver.GetWindowHandles()
600 self._driver.FindElement('tagName', 'a').Click()
601 new_window = self._WaitForNewWindow(old_windows)
602 self.assertNotEqual(None, new_window)
604 self.assertFalse(self._driver.IsLoading())
605 self._driver.SwitchToWindow(new_window)
606 self.assertTrue(self._driver.IsLoading())
607 self._sync_server.RespondWithContent('<html>new window</html>')
608 self._driver.ExecuteScript('return 1') # Shouldn't hang.
610 def testPopups(self):
611 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
612 old_handles = self._driver.GetWindowHandles()
613 self._driver.ExecuteScript('window.open("about:blank")')
614 new_window_handle = self._WaitForNewWindow(old_handles)
615 self.assertNotEqual(None, new_window_handle)
617 def testNoSuchFrame(self):
618 self.assertRaises(chromedriver.NoSuchFrame,
619 self._driver.SwitchToFrame, 'nosuchframe')
620 self.assertRaises(chromedriver.NoSuchFrame,
621 self._driver.SwitchToFrame,
622 self._driver.FindElement('tagName', 'body'))
624 def testWindowPosition(self):
625 position = self._driver.GetWindowPosition()
626 self._driver.SetWindowPosition(position[0], position[1])
627 self.assertEquals(position, self._driver.GetWindowPosition())
629 # Resize so the window isn't moved offscreen.
630 # See https://code.google.com/p/chromedriver/issues/detail?id=297.
631 self._driver.SetWindowSize(300, 300)
633 self._driver.SetWindowPosition(100, 200)
634 self.assertEquals([100, 200], self._driver.GetWindowPosition())
636 def testWindowSize(self):
637 size = self._driver.GetWindowSize()
638 self._driver.SetWindowSize(size[0], size[1])
639 self.assertEquals(size, self._driver.GetWindowSize())
641 self._driver.SetWindowSize(600, 400)
642 self.assertEquals([600, 400], self._driver.GetWindowSize())
644 def testWindowMaximize(self):
645 self._driver.SetWindowPosition(100, 200)
646 self._driver.SetWindowSize(600, 400)
647 self._driver.MaximizeWindow()
649 self.assertNotEqual([100, 200], self._driver.GetWindowPosition())
650 self.assertNotEqual([600, 400], self._driver.GetWindowSize())
651 # Set size first so that the window isn't moved offscreen.
652 # See https://code.google.com/p/chromedriver/issues/detail?id=297.
653 self._driver.SetWindowSize(600, 400)
654 self._driver.SetWindowPosition(100, 200)
655 self.assertEquals([100, 200], self._driver.GetWindowPosition())
656 self.assertEquals([600, 400], self._driver.GetWindowSize())
658 def testConsoleLogSources(self):
659 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/console_log.html'))
660 logs = self._driver.GetLog('browser')
661 self.assertEquals(len(logs), 2)
662 self.assertEquals(logs[0]['source'], 'network')
663 self.assertEquals(logs[1]['source'], 'javascript')
665 def testAutoReporting(self):
666 self.assertFalse(self._driver.IsAutoReporting())
667 self._driver.SetAutoReporting(True)
668 self.assertTrue(self._driver.IsAutoReporting())
669 url = self.GetHttpUrlForFile('/chromedriver/console_log.html')
670 self.assertRaisesRegexp(chromedriver.UnknownError,
671 '.*(404|Failed to load resource).*',
675 def testContextMenuEventFired(self):
676 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/context_menu.html'))
677 self._driver.MouseMoveTo(self._driver.FindElement('tagName', 'div'))
678 self._driver.MouseClick(2)
679 self.assertTrue(self._driver.ExecuteScript('return success'))
681 def testHasFocusOnStartup(self):
682 # Some pages (about:blank) cause Chrome to put the focus in URL bar.
683 # This breaks tests depending on focus.
684 self.assertTrue(self._driver.ExecuteScript('return document.hasFocus()'))
686 def testTabCrash(self):
687 # If a tab is crashed, the session will be deleted.
688 # When 31 is released, will reload the tab instead.
689 # https://code.google.com/p/chromedriver/issues/detail?id=547
690 self.assertRaises(chromedriver.UnknownError,
691 self._driver.Load, 'chrome://crash')
692 self.assertRaises(chromedriver.NoSuchSession,
693 self._driver.GetCurrentUrl)
695 def testDoesntHangOnDebugger(self):
696 self._driver.ExecuteScript('debugger;')
699 class ChromeDriverAndroidTest(ChromeDriverBaseTest):
700 """End to end tests for Android-specific tests."""
702 def testLatestAndroidAppInstalled(self):
703 if ('stable' not in _ANDROID_PACKAGE_KEY and
704 'beta' not in _ANDROID_PACKAGE_KEY):
707 self._driver = self.CreateDriver()
710 omaha_list = json.loads(
711 urllib2.urlopen('http://omahaproxy.appspot.com/all.json').read())
713 if l['os'] != 'android':
715 for v in l['versions']:
716 if (('stable' in v['channel'] and 'stable' in _ANDROID_PACKAGE_KEY) or
717 ('beta' in v['channel'] and 'beta' in _ANDROID_PACKAGE_KEY)):
718 self.assertEquals(v['version'],
719 self._driver.capabilities['version'])
721 raise RuntimeError('Malformed omaha JSON')
722 except urllib2.URLError as e:
723 print 'Unable to fetch current version info from omahaproxy (%s)' % e
725 def testDeviceManagement(self):
726 self._drivers = [self.CreateDriver() for x in
727 android_commands.GetAttachedDevices()]
728 self.assertRaises(chromedriver.UnknownError, self.CreateDriver)
729 self._drivers[0].Quit()
730 self._drivers[0] = self.CreateDriver()
733 class ChromeSwitchesCapabilityTest(ChromeDriverBaseTest):
734 """Tests that chromedriver properly processes chromeOptions.args capabilities.
736 Makes sure the switches are passed to Chrome.
739 def testSwitchWithoutArgument(self):
740 """Tests that switch --dom-automation can be passed to Chrome.
742 Unless --dom-automation is specified, window.domAutomationController
745 driver = self.CreateDriver(chrome_switches=['dom-automation'])
748 driver.ExecuteScript('return window.domAutomationController'))
751 class ChromeExtensionsCapabilityTest(ChromeDriverBaseTest):
752 """Tests that chromedriver properly processes chromeOptions.extensions."""
754 def _PackExtension(self, ext_path):
755 return base64.b64encode(open(ext_path, 'rb').read())
757 def testExtensionsInstall(self):
758 """Checks that chromedriver can take the extensions."""
759 crx_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.crx')
760 crx_2 = os.path.join(_TEST_DATA_DIR, 'ext_test_2.crx')
761 self.CreateDriver(chrome_extensions=[self._PackExtension(crx_1),
762 self._PackExtension(crx_2)])
764 def testWaitsForExtensionToLoad(self):
765 did_load_event = threading.Event()
766 server = webserver.SyncWebServer()
769 server.RespondWithContent('<html>iframe</html>')
772 thread = threading.Thread(target=RunServer)
775 crx = os.path.join(_TEST_DATA_DIR, 'ext_slow_loader.crx')
776 driver = self.CreateDriver(
777 chrome_switches=['user-agent=' + server.GetUrl()],
778 chrome_extensions=[self._PackExtension(crx)])
779 self.assertTrue(did_load_event.is_set())
782 class ChromeLogPathCapabilityTest(ChromeDriverBaseTest):
783 """Tests that chromedriver properly processes chromeOptions.logPath."""
785 LOG_MESSAGE = 'Welcome to ChromeLogPathCapabilityTest!'
787 def testChromeLogPath(self):
788 """Checks that user can specify the path of the chrome log.
790 Verifies that a log message is written into the specified log file.
792 tmp_log_path = tempfile.NamedTemporaryFile()
793 driver = self.CreateDriver(chrome_log_path=tmp_log_path.name)
794 driver.ExecuteScript('console.info("%s")' % self.LOG_MESSAGE)
796 self.assertTrue(self.LOG_MESSAGE in open(tmp_log_path.name).read())
799 class ChromeDriverLogTest(unittest.TestCase):
800 """Tests that chromedriver produces the expected log file."""
802 UNEXPECTED_CHROMEOPTION_CAP = 'unexpected_chromeoption_capability'
803 LOG_MESSAGE = 'unrecognized chrome option: %s' % UNEXPECTED_CHROMEOPTION_CAP
805 def testChromeDriverLog(self):
806 _, tmp_log_path = tempfile.mkstemp(prefix='chromedriver_log_')
807 chromedriver_server = server.Server(
808 _CHROMEDRIVER_BINARY, log_path=tmp_log_path)
810 driver = chromedriver.ChromeDriver(
811 chromedriver_server.GetUrl(), chrome_binary=_CHROME_BINARY,
812 experimental_options={ self.UNEXPECTED_CHROMEOPTION_CAP : 1 })
814 except chromedriver.ChromeDriverException, e:
815 self.assertTrue(self.LOG_MESSAGE in e.message)
817 chromedriver_server.Kill()
818 with open(tmp_log_path, 'r') as f:
819 self.assertTrue(self.LOG_MESSAGE in f.read())
822 class SessionHandlingTest(ChromeDriverBaseTest):
823 """Tests for session operations."""
824 def testQuitASessionMoreThanOnce(self):
825 driver = self.CreateDriver()
830 class ExistingBrowserTest(ChromeDriverBaseTest):
831 """Tests for ChromeDriver existing browser capability."""
833 self.assertTrue(_CHROME_BINARY is not None,
834 'must supply a chrome binary arg')
836 def testConnectToExistingBrowser(self):
837 port = self.FindFreePort()
838 temp_dir = util.MakeTempDir()
839 process = subprocess.Popen([_CHROME_BINARY,
840 '--remote-debugging-port=%d' % port,
841 '--user-data-dir=%s' % temp_dir])
843 raise RuntimeError('Chrome could not be started with debugging port')
845 driver = self.CreateDriver(debugger_address='127.0.0.1:%d' % port)
846 driver.ExecuteScript('console.info("%s")' % 'connecting at %d!' % port)
851 def FindFreePort(self):
852 for port in range(10000, 10100):
854 socket.create_connection(('127.0.0.1', port), 0.2).close()
857 raise RuntimeError('Cannot find open port')
859 class PerfTest(ChromeDriverBaseTest):
860 """Tests for ChromeDriver perf."""
862 self.assertTrue(_REFERENCE_CHROMEDRIVER is not None,
863 'must supply a reference-chromedriver arg')
865 def _RunDriverPerfTest(self, name, test_func):
866 """Runs a perf test comparing a reference and new ChromeDriver server.
869 name: The name of the perf test.
870 test_func: Called with the server url to perform the test action. Must
871 return the time elapsed.
873 class Results(object):
877 ref_server = server.Server(_REFERENCE_CHROMEDRIVER)
879 result_url_pairs = zip([results.new, results.ref],
880 [_CHROMEDRIVER_SERVER_URL, ref_server.GetUrl()])
881 for iteration in range(30):
882 for result, url in result_url_pairs:
883 result += [test_func(url)]
884 # Reverse the order for the next run.
885 result_url_pairs = result_url_pairs[::-1]
887 def PrintResult(build, result):
888 mean = sum(result) / len(result)
889 avg_dev = sum([abs(sample - mean) for sample in result]) / len(result)
890 print 'perf result', build, name, mean, avg_dev, result
891 util.AddBuildStepText('%s %s: %.3f+-%.3f' % (
892 build, name, mean, avg_dev))
894 # Discard first result, which may be off due to cold start.
895 PrintResult('new', results.new[1:])
896 PrintResult('ref', results.ref[1:])
898 def testSessionStartTime(self):
901 driver = self.CreateDriver(url)
905 self._RunDriverPerfTest('session start', Run)
907 def testSessionStopTime(self):
909 driver = self.CreateDriver(url)
914 self._RunDriverPerfTest('session stop', Run)
916 def testColdExecuteScript(self):
918 driver = self.CreateDriver(url)
920 driver.ExecuteScript('return 1')
924 self._RunDriverPerfTest('cold exe js', Run)
926 if __name__ == '__main__':
927 parser = optparse.OptionParser()
929 '', '--chromedriver',
930 help='Path to chromedriver server (REQUIRED!)')
933 help='Output verbose server logs to this file')
935 '', '--reference-chromedriver',
936 help='Path to the reference chromedriver server')
938 '', '--chrome', help='Path to a build of the chrome binary')
940 '', '--chrome-version', default='HEAD',
941 help='Version of chrome. Default is \'HEAD\'.')
943 '', '--filter', type='string', default='*',
944 help=('Filter for specifying what tests to run, "*" will run all. E.g., '
947 '', '--android-package',
948 help=('Android package key. Possible values: ' +
949 str(_ANDROID_NEGATIVE_FILTER.keys())))
950 options, args = parser.parse_args()
952 options.chromedriver = util.GetAbsolutePathOfUserPath(options.chromedriver)
953 if not options.chromedriver or not os.path.exists(options.chromedriver):
954 parser.error('chromedriver is required or the given path is invalid.' +
955 'Please run "%s --help" for help' % __file__)
957 global _CHROMEDRIVER_BINARY
958 _CHROMEDRIVER_BINARY = options.chromedriver
960 if (options.android_package and
961 options.android_package not in _ANDROID_NEGATIVE_FILTER):
962 parser.error('Invalid --android-package')
964 chromedriver_server = server.Server(_CHROMEDRIVER_BINARY, options.log_path)
965 global _CHROMEDRIVER_SERVER_URL
966 _CHROMEDRIVER_SERVER_URL = chromedriver_server.GetUrl()
968 global _REFERENCE_CHROMEDRIVER
969 _REFERENCE_CHROMEDRIVER = util.GetAbsolutePathOfUserPath(
970 options.reference_chromedriver)
972 global _CHROME_BINARY
974 _CHROME_BINARY = util.GetAbsolutePathOfUserPath(options.chrome)
976 _CHROME_BINARY = None
978 global _ANDROID_PACKAGE_KEY
979 _ANDROID_PACKAGE_KEY = options.android_package
981 if options.filter == '*':
982 if _ANDROID_PACKAGE_KEY:
983 negative_filter = _ANDROID_NEGATIVE_FILTER[_ANDROID_PACKAGE_KEY]
985 negative_filter = _GetDesktopNegativeFilter(options.chrome_version)
986 options.filter = '*-' + ':__main__.'.join([''] + negative_filter)
988 all_tests_suite = unittest.defaultTestLoader.loadTestsFromModule(
989 sys.modules[__name__])
990 tests = unittest_util.FilterTestSuite(all_tests_suite, options.filter)
991 ChromeDriverTest.GlobalSetUp()
992 result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(tests)
993 ChromeDriverTest.GlobalTearDown()
994 sys.exit(len(result.failures) + len(result.errors))