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."""
21 _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
22 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))
23 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir, 'client'))
24 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir, 'server'))
31 from webelement import WebElement
34 _TEST_DATA_DIR = os.path.join(chrome_paths.GetTestData(), 'chromedriver')
37 sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android'))
38 from pylib import android_commands
39 from pylib import constants
40 from pylib import forwarder
41 from pylib import valgrind_tools
45 # https://code.google.com/p/chromedriver/issues/detail?id=213
46 'ChromeDriverTest.testClickElementInSubFrame',
47 # This test is flaky since it uses setTimeout.
48 # Re-enable once crbug.com/177511 is fixed and we can remove setTimeout.
49 'ChromeDriverTest.testAlert',
52 _VERSION_SPECIFIC_FILTER = {}
53 _VERSION_SPECIFIC_FILTER['HEAD'] = []
55 _OS_SPECIFIC_FILTER = {}
56 _OS_SPECIFIC_FILTER['win'] = [
57 # https://code.google.com/p/chromedriver/issues/detail?id=214
58 'ChromeDriverTest.testCloseWindow',
59 # https://code.google.com/p/chromedriver/issues/detail?id=299
60 'ChromeLogPathCapabilityTest.testChromeLogPath',
62 _OS_SPECIFIC_FILTER['linux'] = [
63 # Xvfb doesn't support maximization.
64 'ChromeDriverTest.testWindowMaximize',
65 # https://code.google.com/p/chromedriver/issues/detail?id=302
66 'ChromeDriverTest.testWindowPosition',
67 'ChromeDriverTest.testWindowSize',
69 _OS_SPECIFIC_FILTER['mac'] = [
70 # https://code.google.com/p/chromedriver/issues/detail?id=304
71 'ChromeDriverTest.testGoBackAndGoForward',
74 _DESKTOP_NEGATIVE_FILTER = [
75 # Desktop doesn't support touch (without --touch-events).
76 'ChromeDriverTest.testSingleTapElement',
77 'ChromeDriverTest.testTouchDownUpElement',
78 'ChromeDriverTest.testTouchMovedElement',
79 'ChromeDriverAndroidTest.*',
83 def _GetDesktopNegativeFilter(version_name):
84 filter = _NEGATIVE_FILTER + _DESKTOP_NEGATIVE_FILTER
85 os = util.GetPlatformName()
86 if os in _OS_SPECIFIC_FILTER:
87 filter += _OS_SPECIFIC_FILTER[os]
88 if version_name in _VERSION_SPECIFIC_FILTER:
89 filter += _VERSION_SPECIFIC_FILTER[version_name]
92 _ANDROID_NEGATIVE_FILTER = {}
93 _ANDROID_NEGATIVE_FILTER['chrome'] = (
95 # TODO(chrisgao): fix hang of tab crash test on android.
96 'ChromeDriverTest.testTabCrash',
97 # Android doesn't support switches and extensions.
98 'ChromeSwitchesCapabilityTest.*',
99 'ChromeExtensionsCapabilityTest.*',
100 # https://crbug.com/274650
101 'ChromeDriverTest.testCloseWindow',
102 # https://code.google.com/p/chromedriver/issues/detail?id=270
103 'ChromeDriverTest.testPopups',
104 # https://code.google.com/p/chromedriver/issues/detail?id=298
105 'ChromeDriverTest.testWindowPosition',
106 'ChromeDriverTest.testWindowSize',
107 'ChromeDriverTest.testWindowMaximize',
108 'ChromeLogPathCapabilityTest.testChromeLogPath',
109 'ExistingBrowserTest.*',
110 # Don't enable perf testing on Android yet.
111 'PerfTest.testSessionStartTime',
112 'PerfTest.testSessionStopTime',
113 'PerfTest.testColdExecuteScript',
114 # https://code.google.com/p/chromedriver/issues/detail?id=459
115 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
118 _ANDROID_NEGATIVE_FILTER['chrome_stable'] = (
119 _ANDROID_NEGATIVE_FILTER['chrome'])
120 _ANDROID_NEGATIVE_FILTER['chrome_beta'] = (
121 _ANDROID_NEGATIVE_FILTER['chrome'])
122 _ANDROID_NEGATIVE_FILTER['chromium_test_shell'] = (
123 _ANDROID_NEGATIVE_FILTER['chrome'] + [
124 # ChromiumTestShell doesn't support multiple tabs.
125 'ChromeDriverTest.testGetWindowHandles',
126 'ChromeDriverTest.testSwitchToWindow',
127 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
130 _ANDROID_NEGATIVE_FILTER['chromedriver_webview_shell'] = (
131 _ANDROID_NEGATIVE_FILTER['chromium_test_shell'])
134 class ChromeDriverBaseTest(unittest.TestCase):
135 """Base class for testing chromedriver functionalities."""
137 def __init__(self, *args, **kwargs):
138 super(ChromeDriverBaseTest, self).__init__(*args, **kwargs)
142 for driver in self._drivers:
148 def CreateDriver(self, server_url=None, **kwargs):
149 if server_url is None:
150 server_url = _CHROMEDRIVER_SERVER_URL
152 android_package = None
153 android_activity = None
154 android_process = None
155 if _ANDROID_PACKAGE_KEY:
156 android_package = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].package
157 if _ANDROID_PACKAGE_KEY == 'chromedriver_webview_shell':
158 android_activity = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].activity
159 android_process = '%s:main' % android_package
161 driver = chromedriver.ChromeDriver(server_url,
162 chrome_binary=_CHROME_BINARY,
163 android_package=android_package,
164 android_activity=android_activity,
165 android_process=android_process,
167 self._drivers += [driver]
171 class ChromeDriverTest(ChromeDriverBaseTest):
172 """End to end tests for ChromeDriver."""
176 ChromeDriverTest._http_server = webserver.WebServer(
177 chrome_paths.GetTestData())
178 ChromeDriverTest._sync_server = webserver.SyncWebServer()
179 if _ANDROID_PACKAGE_KEY:
180 ChromeDriverTest._adb = android_commands.AndroidCommands(
181 android_commands.GetAttachedDevices()[0])
182 http_host_port = ChromeDriverTest._http_server._server.server_port
183 sync_host_port = ChromeDriverTest._sync_server._server.server_port
184 forwarder.Forwarder.Map(
185 [(http_host_port, http_host_port), (sync_host_port, sync_host_port)],
186 ChromeDriverTest._adb)
189 def GlobalTearDown():
190 if _ANDROID_PACKAGE_KEY:
191 forwarder.Forwarder.UnmapAllDevicePorts(ChromeDriverTest._adb)
192 ChromeDriverTest._http_server.Shutdown()
195 def GetHttpUrlForFile(file_path):
196 return ChromeDriverTest._http_server.GetUrl() + file_path
199 self._driver = self.CreateDriver()
201 def testStartStop(self):
204 def testLoadUrl(self):
205 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
207 def testGetCurrentWindowHandle(self):
208 self._driver.GetCurrentWindowHandle()
210 def _WaitForNewWindow(self, old_handles):
211 """Wait for at least one new window to show up in 20 seconds.
214 old_handles: Handles to all old windows before the new window is added.
217 Handle to a new window. None if timeout.
219 timeout = time.time() + 20
220 while time.time() < timeout:
221 new_handles = self._driver.GetWindowHandles()
222 if len(new_handles) > len(old_handles):
223 for index, old_handle in enumerate(old_handles):
224 self.assertEquals(old_handle, new_handles[index])
225 return new_handles[len(old_handles)]
229 def testCloseWindow(self):
230 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
231 old_handles = self._driver.GetWindowHandles()
232 self._driver.FindElement('id', 'link').Click()
233 new_window_handle = self._WaitForNewWindow(old_handles)
234 self.assertNotEqual(None, new_window_handle)
235 self._driver.SwitchToWindow(new_window_handle)
236 self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle())
237 self.assertRaises(chromedriver.NoSuchElement,
238 self._driver.FindElement, 'id', 'link')
239 self._driver.CloseWindow()
240 self.assertRaises(chromedriver.NoSuchWindow,
241 self._driver.GetCurrentWindowHandle)
242 new_handles = self._driver.GetWindowHandles()
243 for old_handle in old_handles:
244 self.assertTrue(old_handle in new_handles)
245 for handle in new_handles:
246 self._driver.SwitchToWindow(handle)
247 self.assertEquals(handle, self._driver.GetCurrentWindowHandle())
248 self._driver.CloseWindow()
250 def testGetWindowHandles(self):
251 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
252 old_handles = self._driver.GetWindowHandles()
253 self._driver.FindElement('id', 'link').Click()
254 self.assertNotEqual(None, self._WaitForNewWindow(old_handles))
256 def testSwitchToWindow(self):
257 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
259 1, self._driver.ExecuteScript('window.name = "oldWindow"; return 1;'))
260 window1_handle = self._driver.GetCurrentWindowHandle()
261 old_handles = self._driver.GetWindowHandles()
262 self._driver.FindElement('id', 'link').Click()
263 new_window_handle = self._WaitForNewWindow(old_handles)
264 self.assertNotEqual(None, new_window_handle)
265 self._driver.SwitchToWindow(new_window_handle)
266 self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle())
267 self.assertRaises(chromedriver.NoSuchElement,
268 self._driver.FindElement, 'id', 'link')
269 self._driver.SwitchToWindow('oldWindow')
270 self.assertEquals(window1_handle, self._driver.GetCurrentWindowHandle())
272 def testEvaluateScript(self):
273 self.assertEquals(1, self._driver.ExecuteScript('return 1'))
274 self.assertEquals(None, self._driver.ExecuteScript(''))
276 def testEvaluateScriptWithArgs(self):
277 script = ('document.body.innerHTML = "<div>b</div><div>c</div>";'
278 'return {stuff: document.querySelectorAll("div")};')
279 stuff = self._driver.ExecuteScript(script)['stuff']
280 script = 'return arguments[0].innerHTML + arguments[1].innerHTML'
282 'bc', self._driver.ExecuteScript(script, stuff[0], stuff[1]))
284 def testEvaluateInvalidScript(self):
285 self.assertRaises(chromedriver.ChromeDriverException,
286 self._driver.ExecuteScript, '{{{')
288 def testExecuteAsyncScript(self):
289 self._driver.SetTimeout('script', 3000)
291 chromedriver.ScriptTimeout,
292 self._driver.ExecuteAsyncScript,
293 'var callback = arguments[0];'
294 'setTimeout(function(){callback(1);}, 10000);')
297 self._driver.ExecuteAsyncScript(
298 'var callback = arguments[0];'
299 'setTimeout(function(){callback(2);}, 300);'))
301 def testSwitchToFrame(self):
302 self._driver.ExecuteScript(
303 'var frame = document.createElement("iframe");'
306 'document.body.appendChild(frame);')
307 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
308 self._driver.SwitchToFrame('id')
309 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
310 self._driver.SwitchToMainFrame()
311 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
312 self._driver.SwitchToFrame('name')
313 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
314 self._driver.SwitchToMainFrame()
315 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
316 self._driver.SwitchToFrameByIndex(0)
317 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
318 self._driver.SwitchToMainFrame()
319 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
320 self._driver.SwitchToFrame(self._driver.FindElement('tag name', 'iframe'))
321 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
323 def testExecuteInRemovedFrame(self):
324 self._driver.ExecuteScript(
325 'var frame = document.createElement("iframe");'
328 'document.body.appendChild(frame);'
329 'window.addEventListener("message",'
330 ' function(event) { document.body.removeChild(frame); });')
331 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
332 self._driver.SwitchToFrame('id')
333 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
334 self._driver.ExecuteScript('parent.postMessage("remove", "*");')
335 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
337 def testGetTitle(self):
338 script = 'document.title = "title"; return 1;'
339 self.assertEquals(1, self._driver.ExecuteScript(script))
340 self.assertEquals('title', self._driver.GetTitle())
342 def testGetPageSource(self):
343 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
344 self.assertTrue('Link to empty.html' in self._driver.GetPageSource())
346 def testFindElement(self):
347 self._driver.ExecuteScript(
348 'document.body.innerHTML = "<div>a</div><div>b</div>";')
350 isinstance(self._driver.FindElement('tag name', 'div'), WebElement))
352 def testFindElements(self):
353 self._driver.ExecuteScript(
354 'document.body.innerHTML = "<div>a</div><div>b</div>";')
355 divs = self._driver.FindElements('tag name', 'div')
356 self.assertTrue(isinstance(divs, list))
357 self.assertEquals(2, len(divs))
359 self.assertTrue(isinstance(div, WebElement))
361 def testFindChildElement(self):
362 self._driver.ExecuteScript(
363 'document.body.innerHTML = "<div><br><br></div><div><a></a></div>";')
364 element = self._driver.FindElement('tag name', 'div')
366 isinstance(element.FindElement('tag name', 'br'), WebElement))
368 def testFindChildElements(self):
369 self._driver.ExecuteScript(
370 'document.body.innerHTML = "<div><br><br></div><div><br></div>";')
371 element = self._driver.FindElement('tag name', 'div')
372 brs = element.FindElements('tag name', 'br')
373 self.assertTrue(isinstance(brs, list))
374 self.assertEquals(2, len(brs))
376 self.assertTrue(isinstance(br, WebElement))
378 def testHoverOverElement(self):
379 div = self._driver.ExecuteScript(
380 'document.body.innerHTML = "<div>old</div>";'
381 'var div = document.getElementsByTagName("div")[0];'
382 'div.addEventListener("mouseover", function() {'
383 ' document.body.appendChild(document.createElement("br"));'
387 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
389 def testClickElement(self):
390 div = self._driver.ExecuteScript(
391 'document.body.innerHTML = "<div>old</div>";'
392 'var div = document.getElementsByTagName("div")[0];'
393 'div.addEventListener("click", function() {'
394 ' div.innerHTML="new<br>";'
398 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
400 def testSingleTapElement(self):
401 div = self._driver.ExecuteScript(
402 'document.body.innerHTML = "<div>old</div>";'
403 'var div = document.getElementsByTagName("div")[0];'
404 'div.addEventListener("touchend", function() {'
405 ' div.innerHTML="new<br>";'
409 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
411 def testTouchDownUpElement(self):
412 div = self._driver.ExecuteScript(
413 'document.body.innerHTML = "<div>old</div>";'
414 'var div = document.getElementsByTagName("div")[0];'
415 'div.addEventListener("touchend", function() {'
416 ' div.innerHTML="new<br>";'
419 loc = div.GetLocation()
420 self._driver.TouchDown(loc['x'], loc['y'])
421 self._driver.TouchUp(loc['x'], loc['y'])
422 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
424 def testTouchMovedElement(self):
425 div = self._driver.ExecuteScript(
426 'document.body.innerHTML = "<div>old</div>";'
427 'var div = document.getElementsByTagName("div")[0];'
428 'div.addEventListener("touchmove", function() {'
429 ' div.innerHTML="new<br>";'
432 loc = div.GetLocation()
433 self._driver.TouchDown(loc['x'], loc['y'])
434 self._driver.TouchMove(loc['x'] + 1, loc['y'] + 1)
435 self._driver.TouchUp(loc['x'] + 1, loc['y'] + 1)
436 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
438 def testClickElementInSubFrame(self):
439 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/frame_test.html'))
440 frame = self._driver.FindElement('tag name', 'iframe')
441 self._driver.SwitchToFrame(frame)
442 # Test clicking element in the sub frame.
443 self.testClickElement()
445 def testClearElement(self):
446 text = self._driver.ExecuteScript(
447 'document.body.innerHTML = \'<input type="text" value="abc">\';'
448 'var input = document.getElementsByTagName("input")[0];'
449 'input.addEventListener("change", function() {'
450 ' document.body.appendChild(document.createElement("br"));'
454 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
456 def testSendKeysToElement(self):
457 text = self._driver.ExecuteScript(
458 'document.body.innerHTML = \'<input type="text">\';'
459 'var input = document.getElementsByTagName("input")[0];'
460 'input.addEventListener("change", function() {'
461 ' document.body.appendChild(document.createElement("br"));'
464 text.SendKeys('0123456789+-*/ Hi')
465 text.SendKeys(', there!')
466 value = self._driver.ExecuteScript('return arguments[0].value;', text)
467 self.assertEquals('0123456789+-*/ Hi, there!', value)
469 def testGetCurrentUrl(self):
470 self.assertEquals('data:,', self._driver.GetCurrentUrl())
472 def testGoBackAndGoForward(self):
473 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
474 self._driver.GoBack()
475 self._driver.GoForward()
477 def testRefresh(self):
478 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
479 self._driver.Refresh()
481 def testMouseMoveTo(self):
482 div = self._driver.ExecuteScript(
483 'document.body.innerHTML = "<div>old</div>";'
484 'var div = document.getElementsByTagName("div")[0];'
485 'div.style["width"] = "100px";'
486 'div.style["height"] = "100px";'
487 'div.addEventListener("mouseover", function() {'
488 ' var div = document.getElementsByTagName("div")[0];'
489 ' div.innerHTML="new<br>";'
492 self._driver.MouseMoveTo(div, 10, 10)
493 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
495 def testMouseClick(self):
496 div = self._driver.ExecuteScript(
497 'document.body.innerHTML = "<div>old</div>";'
498 'var div = document.getElementsByTagName("div")[0];'
499 'div.style["width"] = "100px";'
500 'div.style["height"] = "100px";'
501 'div.addEventListener("click", function() {'
502 ' var div = document.getElementsByTagName("div")[0];'
503 ' div.innerHTML="new<br>";'
506 self._driver.MouseMoveTo(div)
507 self._driver.MouseClick()
508 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
510 def testMouseButtonDownAndUp(self):
511 self._driver.ExecuteScript(
512 'document.body.innerHTML = "<div>old</div>";'
513 'var div = document.getElementsByTagName("div")[0];'
514 'div.style["width"] = "100px";'
515 'div.style["height"] = "100px";'
516 'div.addEventListener("mousedown", function() {'
517 ' var div = document.getElementsByTagName("div")[0];'
518 ' div.innerHTML="new1<br>";'
520 'div.addEventListener("mouseup", function() {'
521 ' var div = document.getElementsByTagName("div")[0];'
522 ' div.innerHTML="new2<a></a>";'
524 self._driver.MouseMoveTo(None, 50, 50)
525 self._driver.MouseButtonDown()
526 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
527 self._driver.MouseButtonUp()
528 self.assertEquals(1, len(self._driver.FindElements('tag name', 'a')))
530 def testMouseDoubleClick(self):
531 div = self._driver.ExecuteScript(
532 'document.body.innerHTML = "<div>old</div>";'
533 'var div = document.getElementsByTagName("div")[0];'
534 'div.style["width"] = "100px";'
535 'div.style["height"] = "100px";'
536 'div.addEventListener("dblclick", function() {'
537 ' var div = document.getElementsByTagName("div")[0];'
538 ' div.innerHTML="new<br>";'
541 self._driver.MouseMoveTo(div, 1, 1)
542 self._driver.MouseDoubleClick()
543 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
546 self.assertFalse(self._driver.IsAlertOpen())
547 self._driver.ExecuteScript(
549 ' function() { window.confirmed = confirm(\'HI\'); },'
551 self.assertTrue(self._driver.IsAlertOpen())
552 self.assertEquals('HI', self._driver.GetAlertMessage())
553 self._driver.HandleAlert(False)
554 self.assertFalse(self._driver.IsAlertOpen())
555 self.assertEquals(False,
556 self._driver.ExecuteScript('return window.confirmed'))
558 def testShouldHandleNewWindowLoadingProperly(self):
559 """Tests that ChromeDriver determines loading correctly for new windows."""
560 self._http_server.SetDataForPath(
565 <a href='%s' target='_blank'>new window/tab</a>
567 </html>""" % self._sync_server.GetUrl())
568 self._driver.Load(self._http_server.GetUrl() + '/newwindow')
569 old_windows = self._driver.GetWindowHandles()
570 self._driver.FindElement('tagName', 'a').Click()
571 new_window = self._WaitForNewWindow(old_windows)
572 self.assertNotEqual(None, new_window)
574 self.assertFalse(self._driver.IsLoading())
575 self._driver.SwitchToWindow(new_window)
576 self.assertTrue(self._driver.IsLoading())
577 self._sync_server.RespondWithContent('<html>new window</html>')
578 self._driver.ExecuteScript('return 1') # Shouldn't hang.
580 def testPopups(self):
581 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
582 old_handles = self._driver.GetWindowHandles()
583 self._driver.ExecuteScript('window.open("about:blank")')
584 new_window_handle = self._WaitForNewWindow(old_handles)
585 self.assertNotEqual(None, new_window_handle)
587 def testNoSuchFrame(self):
588 self.assertRaises(chromedriver.NoSuchFrame,
589 self._driver.SwitchToFrame, 'nosuchframe')
590 self.assertRaises(chromedriver.NoSuchFrame,
591 self._driver.SwitchToFrame,
592 self._driver.FindElement('tagName', 'body'))
594 def testWindowPosition(self):
595 position = self._driver.GetWindowPosition()
596 self._driver.SetWindowPosition(position[0], position[1])
597 self.assertEquals(position, self._driver.GetWindowPosition())
599 # Resize so the window isn't moved offscreen.
600 # See https://code.google.com/p/chromedriver/issues/detail?id=297.
601 self._driver.SetWindowSize(300, 300)
603 self._driver.SetWindowPosition(100, 200)
604 self.assertEquals([100, 200], self._driver.GetWindowPosition())
606 def testWindowSize(self):
607 size = self._driver.GetWindowSize()
608 self._driver.SetWindowSize(size[0], size[1])
609 self.assertEquals(size, self._driver.GetWindowSize())
611 self._driver.SetWindowSize(600, 400)
612 self.assertEquals([600, 400], self._driver.GetWindowSize())
614 def testWindowMaximize(self):
615 self._driver.SetWindowPosition(100, 200)
616 self._driver.SetWindowSize(600, 400)
617 self._driver.MaximizeWindow()
619 self.assertNotEqual([100, 200], self._driver.GetWindowPosition())
620 self.assertNotEqual([600, 400], self._driver.GetWindowSize())
621 # Set size first so that the window isn't moved offscreen.
622 # See https://code.google.com/p/chromedriver/issues/detail?id=297.
623 self._driver.SetWindowSize(600, 400)
624 self._driver.SetWindowPosition(100, 200)
625 self.assertEquals([100, 200], self._driver.GetWindowPosition())
626 self.assertEquals([600, 400], self._driver.GetWindowSize())
628 def testConsoleLogSources(self):
629 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/console_log.html'))
630 logs = self._driver.GetLog('browser')
631 self.assertEquals(len(logs), 2)
632 self.assertEquals(logs[0]['source'], 'network')
633 self.assertEquals(logs[1]['source'], 'javascript')
635 def testAutoReporting(self):
636 self.assertFalse(self._driver.IsAutoReporting())
637 self._driver.SetAutoReporting(True)
638 self.assertTrue(self._driver.IsAutoReporting())
639 url = self.GetHttpUrlForFile('/chromedriver/console_log.html')
640 self.assertRaisesRegexp(chromedriver.UnknownError,
641 '.*(404|Failed to load resource).*',
645 def testContextMenuEventFired(self):
646 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/context_menu.html'))
647 self._driver.MouseMoveTo(self._driver.FindElement('tagName', 'div'))
648 self._driver.MouseClick(2)
649 self.assertTrue(self._driver.ExecuteScript('return success'))
651 def testHasFocusOnStartup(self):
652 # Some pages (about:blank) cause Chrome to put the focus in URL bar.
653 # This breaks tests depending on focus.
654 self.assertTrue(self._driver.ExecuteScript('return document.hasFocus()'))
656 def testTabCrash(self):
657 # If a tab is crashed, the session will be deleted.
658 # When 31 is released, will reload the tab instead.
659 # https://code.google.com/p/chromedriver/issues/detail?id=547
660 self.assertRaises(chromedriver.UnknownError,
661 self._driver.Load, 'chrome://crash')
662 self.assertRaises(chromedriver.NoSuchSession,
663 self._driver.GetCurrentUrl)
665 def testDoesntHangOnDebugger(self):
666 self._driver.ExecuteScript('debugger;')
669 class ChromeDriverAndroidTest(ChromeDriverBaseTest):
670 """End to end tests for Android-specific tests."""
672 def testLatestAndroidAppInstalled(self):
673 if ('stable' not in _ANDROID_PACKAGE_KEY and
674 'beta' not in _ANDROID_PACKAGE_KEY):
677 self._driver = self.CreateDriver()
680 omaha_list = json.loads(
681 urllib2.urlopen('http://omahaproxy.appspot.com/all.json').read())
683 if l['os'] != 'android':
685 for v in l['versions']:
686 if (('stable' in v['channel'] and 'stable' in _ANDROID_PACKAGE_KEY) or
687 ('beta' in v['channel'] and 'beta' in _ANDROID_PACKAGE_KEY)):
688 self.assertEquals(v['version'],
689 self._driver.capabilities['version'])
691 raise RuntimeError('Malformed omaha JSON')
692 except urllib2.URLError as e:
693 print 'Unable to fetch current version info from omahaproxy (%s)' % e
695 def testDeviceManagement(self):
696 self._drivers = [self.CreateDriver() for x in
697 android_commands.GetAttachedDevices()]
698 self.assertRaises(chromedriver.UnknownError, self.CreateDriver)
699 self._drivers[0].Quit()
700 self._drivers[0] = self.CreateDriver()
703 class ChromeSwitchesCapabilityTest(ChromeDriverBaseTest):
704 """Tests that chromedriver properly processes chromeOptions.args capabilities.
706 Makes sure the switches are passed to Chrome.
709 def testSwitchWithoutArgument(self):
710 """Tests that switch --dom-automation can be passed to Chrome.
712 Unless --dom-automation is specified, window.domAutomationController
715 driver = self.CreateDriver(chrome_switches=['dom-automation'])
718 driver.ExecuteScript('return window.domAutomationController'))
721 class ChromeExtensionsCapabilityTest(ChromeDriverBaseTest):
722 """Tests that chromedriver properly processes chromeOptions.extensions."""
724 def _PackExtension(self, ext_path):
725 return base64.b64encode(open(ext_path, 'rb').read())
727 def testExtensionsInstall(self):
728 """Checks that chromedriver can take the extensions."""
729 crx_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.crx')
730 crx_2 = os.path.join(_TEST_DATA_DIR, 'ext_test_2.crx')
731 self.CreateDriver(chrome_extensions=[self._PackExtension(crx_1),
732 self._PackExtension(crx_2)])
734 def testWaitsForExtensionToLoad(self):
735 did_load_event = threading.Event()
736 server = webserver.SyncWebServer()
739 server.RespondWithContent('<html>iframe</html>')
742 thread = threading.Thread(target=RunServer)
745 crx = os.path.join(_TEST_DATA_DIR, 'ext_slow_loader.crx')
746 driver = self.CreateDriver(
747 chrome_switches=['user-agent=' + server.GetUrl()],
748 chrome_extensions=[self._PackExtension(crx)])
749 self.assertTrue(did_load_event.is_set())
752 class ChromeLogPathCapabilityTest(ChromeDriverBaseTest):
753 """Tests that chromedriver properly processes chromeOptions.logPath."""
755 LOG_MESSAGE = 'Welcome to ChromeLogPathCapabilityTest!'
757 def testChromeLogPath(self):
758 """Checks that user can specify the path of the chrome log.
760 Verifies that a log message is written into the specified log file.
762 tmp_log_path = tempfile.NamedTemporaryFile()
763 driver = self.CreateDriver(chrome_log_path=tmp_log_path.name)
764 driver.ExecuteScript('console.info("%s")' % self.LOG_MESSAGE)
766 self.assertTrue(self.LOG_MESSAGE in open(tmp_log_path.name).read())
769 class ChromeDriverLogTest(unittest.TestCase):
770 """Tests that chromedriver produces the expected log file."""
772 UNEXPECTED_CHROMEOPTION_CAP = 'unexpected_chromeoption_capability'
773 LOG_MESSAGE = 'unrecognized chrome option: %s' % UNEXPECTED_CHROMEOPTION_CAP
775 def testChromeDriverLog(self):
776 _, tmp_log_path = tempfile.mkstemp(prefix='chromedriver_log_')
777 chromedriver_server = server.Server(
778 _CHROMEDRIVER_BINARY, log_path=tmp_log_path)
780 driver = chromedriver.ChromeDriver(
781 chromedriver_server.GetUrl(), chrome_binary=_CHROME_BINARY,
782 experimental_options={ self.UNEXPECTED_CHROMEOPTION_CAP : 1 })
784 except chromedriver.ChromeDriverException, e:
785 self.assertTrue(self.LOG_MESSAGE in e.message)
787 chromedriver_server.Kill()
788 with open(tmp_log_path, 'r') as f:
789 self.assertTrue(self.LOG_MESSAGE in f.read())
792 class SessionHandlingTest(ChromeDriverBaseTest):
793 """Tests for session operations."""
794 def testQuitASessionMoreThanOnce(self):
795 driver = self.CreateDriver()
800 class ExistingBrowserTest(ChromeDriverBaseTest):
801 """Tests for ChromeDriver existing browser capability."""
803 self.assertTrue(_CHROME_BINARY is not None,
804 'must supply a chrome binary arg')
806 def testConnectToExistingBrowser(self):
807 port = self.FindFreePort()
808 temp_dir = util.MakeTempDir()
809 process = subprocess.Popen([_CHROME_BINARY,
810 '--remote-debugging-port=%d' % port,
811 '--user-data-dir=%s' % temp_dir])
813 raise RuntimeError('Chrome could not be started with debugging port')
815 driver = self.CreateDriver(debugger_address='127.0.0.1:%d' % port)
816 driver.ExecuteScript('console.info("%s")' % 'connecting at %d!' % port)
821 def FindFreePort(self):
822 for port in range(10000, 10100):
824 socket.create_connection(('127.0.0.1', port), 0.2).close()
827 raise RuntimeError('Cannot find open port')
829 class PerfTest(ChromeDriverBaseTest):
830 """Tests for ChromeDriver perf."""
832 self.assertTrue(_REFERENCE_CHROMEDRIVER is not None,
833 'must supply a reference-chromedriver arg')
835 def _RunDriverPerfTest(self, name, test_func):
836 """Runs a perf test comparing a reference and new ChromeDriver server.
839 name: The name of the perf test.
840 test_func: Called with the server url to perform the test action. Must
841 return the time elapsed.
843 class Results(object):
847 ref_server = server.Server(_REFERENCE_CHROMEDRIVER)
849 result_url_pairs = zip([results.new, results.ref],
850 [_CHROMEDRIVER_SERVER_URL, ref_server.GetUrl()])
851 for iteration in range(30):
852 for result, url in result_url_pairs:
853 result += [test_func(url)]
854 # Reverse the order for the next run.
855 result_url_pairs = result_url_pairs[::-1]
857 def PrintResult(build, result):
858 mean = sum(result) / len(result)
859 avg_dev = sum([abs(sample - mean) for sample in result]) / len(result)
860 print 'perf result', build, name, mean, avg_dev, result
861 util.AddBuildStepText('%s %s: %.3f+-%.3f' % (
862 build, name, mean, avg_dev))
864 # Discard first result, which may be off due to cold start.
865 PrintResult('new', results.new[1:])
866 PrintResult('ref', results.ref[1:])
868 def testSessionStartTime(self):
871 driver = self.CreateDriver(url)
875 self._RunDriverPerfTest('session start', Run)
877 def testSessionStopTime(self):
879 driver = self.CreateDriver(url)
884 self._RunDriverPerfTest('session stop', Run)
886 def testColdExecuteScript(self):
888 driver = self.CreateDriver(url)
890 driver.ExecuteScript('return 1')
894 self._RunDriverPerfTest('cold exe js', Run)
896 if __name__ == '__main__':
897 parser = optparse.OptionParser()
899 '', '--chromedriver',
900 help='Path to chromedriver server (REQUIRED!)')
903 help='Output verbose server logs to this file')
905 '', '--reference-chromedriver',
906 help='Path to the reference chromedriver server')
908 '', '--chrome', help='Path to a build of the chrome binary')
910 '', '--chrome-version', default='HEAD',
911 help='Version of chrome. Default is \'HEAD\'.')
913 '', '--filter', type='string', default='*',
914 help=('Filter for specifying what tests to run, "*" will run all. E.g., '
917 '', '--android-package',
918 help=('Android package key. Possible values: ' +
919 str(_ANDROID_NEGATIVE_FILTER.keys())))
920 options, args = parser.parse_args()
922 if not options.chromedriver or not os.path.exists(options.chromedriver):
923 parser.error('chromedriver is required or the given path is invalid.' +
924 'Please run "%s --help" for help' % __file__)
926 global _CHROMEDRIVER_BINARY
927 _CHROMEDRIVER_BINARY = options.chromedriver
929 if (options.android_package and
930 options.android_package not in _ANDROID_NEGATIVE_FILTER):
931 parser.error('Invalid --android-package')
933 chromedriver_server = server.Server(os.path.abspath(_CHROMEDRIVER_BINARY),
935 global _CHROMEDRIVER_SERVER_URL
936 _CHROMEDRIVER_SERVER_URL = chromedriver_server.GetUrl()
938 global _REFERENCE_CHROMEDRIVER
939 _REFERENCE_CHROMEDRIVER = options.reference_chromedriver
941 global _CHROME_BINARY
943 _CHROME_BINARY = os.path.abspath(options.chrome)
945 _CHROME_BINARY = None
947 global _ANDROID_PACKAGE_KEY
948 _ANDROID_PACKAGE_KEY = options.android_package
950 if options.filter == '*':
951 if _ANDROID_PACKAGE_KEY:
952 negative_filter = _ANDROID_NEGATIVE_FILTER[_ANDROID_PACKAGE_KEY]
954 negative_filter = _GetDesktopNegativeFilter(options.chrome_version)
955 options.filter = '*-' + ':__main__.'.join([''] + negative_filter)
957 all_tests_suite = unittest.defaultTestLoader.loadTestsFromModule(
958 sys.modules[__name__])
959 tests = unittest_util.FilterTestSuite(all_tests_suite, options.filter)
960 ChromeDriverTest.GlobalSetUp()
961 result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(tests)
962 ChromeDriverTest.GlobalTearDown()
963 sys.exit(len(result.failures) + len(result.errors))