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
43 from pylib.device import device_utils
47 # https://code.google.com/p/chromedriver/issues/detail?id=213
48 'ChromeDriverTest.testClickElementInSubFrame',
49 # This test is flaky since it uses setTimeout.
50 # Re-enable once crbug.com/177511 is fixed and we can remove setTimeout.
51 'ChromeDriverTest.testAlert',
54 _VERSION_SPECIFIC_FILTER = {}
55 _VERSION_SPECIFIC_FILTER['HEAD'] = [
56 # https://code.google.com/p/chromedriver/issues/detail?id=815
57 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
60 _OS_SPECIFIC_FILTER = {}
61 _OS_SPECIFIC_FILTER['win'] = [
62 # https://code.google.com/p/chromedriver/issues/detail?id=214
63 'ChromeDriverTest.testCloseWindow',
64 # https://code.google.com/p/chromedriver/issues/detail?id=299
65 'ChromeLogPathCapabilityTest.testChromeLogPath',
67 _OS_SPECIFIC_FILTER['linux'] = [
68 # Xvfb doesn't support maximization.
69 'ChromeDriverTest.testWindowMaximize',
70 # https://code.google.com/p/chromedriver/issues/detail?id=302
71 'ChromeDriverTest.testWindowPosition',
72 'ChromeDriverTest.testWindowSize',
74 _OS_SPECIFIC_FILTER['mac'] = [
75 # https://code.google.com/p/chromedriver/issues/detail?id=304
76 'ChromeDriverTest.testGoBackAndGoForward',
79 _DESKTOP_NEGATIVE_FILTER = [
80 # Desktop doesn't support touch (without --touch-events).
81 'ChromeDriverTest.testSingleTapElement',
82 'ChromeDriverTest.testTouchDownUpElement',
83 'ChromeDriverTest.testTouchFlickElement',
84 'ChromeDriverTest.testTouchMovedElement',
85 'ChromeDriverAndroidTest.*',
89 def _GetDesktopNegativeFilter(version_name):
90 filter = _NEGATIVE_FILTER + _DESKTOP_NEGATIVE_FILTER
91 os = util.GetPlatformName()
92 if os in _OS_SPECIFIC_FILTER:
93 filter += _OS_SPECIFIC_FILTER[os]
94 if version_name in _VERSION_SPECIFIC_FILTER:
95 filter += _VERSION_SPECIFIC_FILTER[version_name]
98 _ANDROID_NEGATIVE_FILTER = {}
99 _ANDROID_NEGATIVE_FILTER['chrome'] = (
101 # TODO(chrisgao): fix hang of tab crash test on android.
102 'ChromeDriverTest.testTabCrash',
103 # Android doesn't support switches and extensions.
104 'ChromeSwitchesCapabilityTest.*',
105 'ChromeExtensionsCapabilityTest.*',
106 'MobileEmulationCapabilityTest.*',
107 # https://crbug.com/274650
108 'ChromeDriverTest.testCloseWindow',
109 # https://code.google.com/p/chromedriver/issues/detail?id=270
110 'ChromeDriverTest.testPopups',
111 # https://code.google.com/p/chromedriver/issues/detail?id=298
112 'ChromeDriverTest.testWindowPosition',
113 'ChromeDriverTest.testWindowSize',
114 'ChromeDriverTest.testWindowMaximize',
115 'ChromeLogPathCapabilityTest.testChromeLogPath',
116 'RemoteBrowserTest.*',
117 # Don't enable perf testing on Android yet.
118 'PerfTest.testSessionStartTime',
119 'PerfTest.testSessionStopTime',
120 'PerfTest.testColdExecuteScript',
121 # https://code.google.com/p/chromedriver/issues/detail?id=459
122 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
125 _ANDROID_NEGATIVE_FILTER['chrome_stable'] = (
126 _ANDROID_NEGATIVE_FILTER['chrome'])
127 _ANDROID_NEGATIVE_FILTER['chrome_beta'] = (
128 _ANDROID_NEGATIVE_FILTER['chrome'])
129 _ANDROID_NEGATIVE_FILTER['chrome_shell'] = (
130 _ANDROID_NEGATIVE_FILTER['chrome'] + [
131 # ChromeShell doesn't support multiple tabs.
132 'ChromeDriverTest.testGetWindowHandles',
133 'ChromeDriverTest.testSwitchToWindow',
134 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
137 _ANDROID_NEGATIVE_FILTER['chromedriver_webview_shell'] = (
138 _ANDROID_NEGATIVE_FILTER['chrome_shell'])
141 class ChromeDriverBaseTest(unittest.TestCase):
142 """Base class for testing chromedriver functionalities."""
144 def __init__(self, *args, **kwargs):
145 super(ChromeDriverBaseTest, self).__init__(*args, **kwargs)
149 for driver in self._drivers:
155 def CreateDriver(self, server_url=None, **kwargs):
156 if server_url is None:
157 server_url = _CHROMEDRIVER_SERVER_URL
159 android_package = None
160 android_activity = None
161 android_process = None
162 if _ANDROID_PACKAGE_KEY:
163 android_package = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].package
164 if _ANDROID_PACKAGE_KEY == 'chromedriver_webview_shell':
165 android_activity = constants.PACKAGE_INFO[_ANDROID_PACKAGE_KEY].activity
166 android_process = '%s:main' % android_package
168 driver = chromedriver.ChromeDriver(server_url,
169 chrome_binary=_CHROME_BINARY,
170 android_package=android_package,
171 android_activity=android_activity,
172 android_process=android_process,
174 self._drivers += [driver]
178 class ChromeDriverTest(ChromeDriverBaseTest):
179 """End to end tests for ChromeDriver."""
183 ChromeDriverTest._http_server = webserver.WebServer(
184 chrome_paths.GetTestData())
185 ChromeDriverTest._sync_server = webserver.SyncWebServer()
186 if _ANDROID_PACKAGE_KEY:
187 ChromeDriverTest._device = device_utils.DeviceUtils(
188 android_commands.GetAttachedDevices()[0])
189 http_host_port = ChromeDriverTest._http_server._server.server_port
190 sync_host_port = ChromeDriverTest._sync_server._server.server_port
191 forwarder.Forwarder.Map(
192 [(http_host_port, http_host_port), (sync_host_port, sync_host_port)],
193 ChromeDriverTest._device)
196 def GlobalTearDown():
197 if _ANDROID_PACKAGE_KEY:
198 forwarder.Forwarder.UnmapAllDevicePorts(ChromeDriverTest._device)
199 ChromeDriverTest._http_server.Shutdown()
202 def GetHttpUrlForFile(file_path):
203 return ChromeDriverTest._http_server.GetUrl() + file_path
206 self._driver = self.CreateDriver()
208 def testStartStop(self):
211 def testLoadUrl(self):
212 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
214 def testGetCurrentWindowHandle(self):
215 self._driver.GetCurrentWindowHandle()
217 def _WaitForNewWindow(self, old_handles):
218 """Wait for at least one new window to show up in 20 seconds.
221 old_handles: Handles to all old windows before the new window is added.
224 Handle to a new window. None if timeout.
226 timeout = time.time() + 20
227 while time.time() < timeout:
228 new_handles = self._driver.GetWindowHandles()
229 if len(new_handles) > len(old_handles):
230 for index, old_handle in enumerate(old_handles):
231 self.assertEquals(old_handle, new_handles[index])
232 return new_handles[len(old_handles)]
236 def testCloseWindow(self):
237 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
238 old_handles = self._driver.GetWindowHandles()
239 self._driver.FindElement('id', 'link').Click()
240 new_window_handle = self._WaitForNewWindow(old_handles)
241 self.assertNotEqual(None, new_window_handle)
242 self._driver.SwitchToWindow(new_window_handle)
243 self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle())
244 self.assertRaises(chromedriver.NoSuchElement,
245 self._driver.FindElement, 'id', 'link')
246 self._driver.CloseWindow()
247 self.assertRaises(chromedriver.NoSuchWindow,
248 self._driver.GetCurrentWindowHandle)
249 new_handles = self._driver.GetWindowHandles()
250 for old_handle in old_handles:
251 self.assertTrue(old_handle in new_handles)
252 for handle in new_handles:
253 self._driver.SwitchToWindow(handle)
254 self.assertEquals(handle, self._driver.GetCurrentWindowHandle())
255 self._driver.CloseWindow()
257 def testGetWindowHandles(self):
258 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
259 old_handles = self._driver.GetWindowHandles()
260 self._driver.FindElement('id', 'link').Click()
261 self.assertNotEqual(None, self._WaitForNewWindow(old_handles))
263 def testSwitchToWindow(self):
264 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
266 1, self._driver.ExecuteScript('window.name = "oldWindow"; return 1;'))
267 window1_handle = self._driver.GetCurrentWindowHandle()
268 old_handles = self._driver.GetWindowHandles()
269 self._driver.FindElement('id', 'link').Click()
270 new_window_handle = self._WaitForNewWindow(old_handles)
271 self.assertNotEqual(None, new_window_handle)
272 self._driver.SwitchToWindow(new_window_handle)
273 self.assertEquals(new_window_handle, self._driver.GetCurrentWindowHandle())
274 self.assertRaises(chromedriver.NoSuchElement,
275 self._driver.FindElement, 'id', 'link')
276 self._driver.SwitchToWindow('oldWindow')
277 self.assertEquals(window1_handle, self._driver.GetCurrentWindowHandle())
279 def testEvaluateScript(self):
280 self.assertEquals(1, self._driver.ExecuteScript('return 1'))
281 self.assertEquals(None, self._driver.ExecuteScript(''))
283 def testEvaluateScriptWithArgs(self):
284 script = ('document.body.innerHTML = "<div>b</div><div>c</div>";'
285 'return {stuff: document.querySelectorAll("div")};')
286 stuff = self._driver.ExecuteScript(script)['stuff']
287 script = 'return arguments[0].innerHTML + arguments[1].innerHTML'
289 'bc', self._driver.ExecuteScript(script, stuff[0], stuff[1]))
291 def testEvaluateInvalidScript(self):
292 self.assertRaises(chromedriver.ChromeDriverException,
293 self._driver.ExecuteScript, '{{{')
295 def testExecuteAsyncScript(self):
296 self._driver.SetTimeout('script', 3000)
298 chromedriver.ScriptTimeout,
299 self._driver.ExecuteAsyncScript,
300 'var callback = arguments[0];'
301 'setTimeout(function(){callback(1);}, 10000);')
304 self._driver.ExecuteAsyncScript(
305 'var callback = arguments[0];'
306 'setTimeout(function(){callback(2);}, 300);'))
308 def testSwitchToFrame(self):
309 self._driver.ExecuteScript(
310 'var frame = document.createElement("iframe");'
313 'document.body.appendChild(frame);')
314 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
315 self._driver.SwitchToFrame('id')
316 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
317 self._driver.SwitchToMainFrame()
318 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
319 self._driver.SwitchToFrame('name')
320 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
321 self._driver.SwitchToMainFrame()
322 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
323 self._driver.SwitchToFrameByIndex(0)
324 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
325 self._driver.SwitchToMainFrame()
326 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
327 self._driver.SwitchToFrame(self._driver.FindElement('tag name', 'iframe'))
328 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
330 def testSwitchToParentFrame(self):
331 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/nested.html'))
332 self.assertTrue('One' in self._driver.GetPageSource())
333 self._driver.SwitchToFrameByIndex(0)
334 self.assertTrue('Two' in self._driver.GetPageSource())
335 self._driver.SwitchToFrameByIndex(0)
336 self.assertTrue('Three' in self._driver.GetPageSource())
337 self._driver.SwitchToParentFrame()
338 self.assertTrue('Two' in self._driver.GetPageSource())
339 self._driver.SwitchToParentFrame()
340 self.assertTrue('One' in self._driver.GetPageSource())
342 def testExecuteInRemovedFrame(self):
343 self._driver.ExecuteScript(
344 'var frame = document.createElement("iframe");'
347 'document.body.appendChild(frame);'
348 'window.addEventListener("message",'
349 ' function(event) { document.body.removeChild(frame); });')
350 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
351 self._driver.SwitchToFrame('id')
352 self.assertTrue(self._driver.ExecuteScript('return window.top != window'))
353 self._driver.ExecuteScript('parent.postMessage("remove", "*");')
354 self.assertTrue(self._driver.ExecuteScript('return window.top == window'))
356 def testGetTitle(self):
357 script = 'document.title = "title"; return 1;'
358 self.assertEquals(1, self._driver.ExecuteScript(script))
359 self.assertEquals('title', self._driver.GetTitle())
361 def testGetPageSource(self):
362 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html'))
363 self.assertTrue('Link to empty.html' in self._driver.GetPageSource())
365 def testFindElement(self):
366 self._driver.ExecuteScript(
367 'document.body.innerHTML = "<div>a</div><div>b</div>";')
369 isinstance(self._driver.FindElement('tag name', 'div'), WebElement))
371 def testFindElements(self):
372 self._driver.ExecuteScript(
373 'document.body.innerHTML = "<div>a</div><div>b</div>";')
374 divs = self._driver.FindElements('tag name', 'div')
375 self.assertTrue(isinstance(divs, list))
376 self.assertEquals(2, len(divs))
378 self.assertTrue(isinstance(div, WebElement))
380 def testFindChildElement(self):
381 self._driver.ExecuteScript(
382 'document.body.innerHTML = "<div><br><br></div><div><a></a></div>";')
383 element = self._driver.FindElement('tag name', 'div')
385 isinstance(element.FindElement('tag name', 'br'), WebElement))
387 def testFindChildElements(self):
388 self._driver.ExecuteScript(
389 'document.body.innerHTML = "<div><br><br></div><div><br></div>";')
390 element = self._driver.FindElement('tag name', 'div')
391 brs = element.FindElements('tag name', 'br')
392 self.assertTrue(isinstance(brs, list))
393 self.assertEquals(2, len(brs))
395 self.assertTrue(isinstance(br, WebElement))
397 def testHoverOverElement(self):
398 div = self._driver.ExecuteScript(
399 'document.body.innerHTML = "<div>old</div>";'
400 'var div = document.getElementsByTagName("div")[0];'
401 'div.addEventListener("mouseover", function() {'
402 ' document.body.appendChild(document.createElement("br"));'
406 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
408 def testClickElement(self):
409 div = self._driver.ExecuteScript(
410 'document.body.innerHTML = "<div>old</div>";'
411 'var div = document.getElementsByTagName("div")[0];'
412 'div.addEventListener("click", function() {'
413 ' div.innerHTML="new<br>";'
417 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
419 def testSingleTapElement(self):
420 div = self._driver.ExecuteScript(
421 'document.body.innerHTML = "<div>old</div>";'
422 'var div = document.getElementsByTagName("div")[0];'
423 'div.addEventListener("touchend", function() {'
424 ' div.innerHTML="new<br>";'
428 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
430 def testTouchDownUpElement(self):
431 div = self._driver.ExecuteScript(
432 'document.body.innerHTML = "<div>old</div>";'
433 'var div = document.getElementsByTagName("div")[0];'
434 'div.addEventListener("touchend", function() {'
435 ' div.innerHTML="new<br>";'
438 loc = div.GetLocation()
439 self._driver.TouchDown(loc['x'], loc['y'])
440 self._driver.TouchUp(loc['x'], loc['y'])
441 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
443 def testTouchFlickElement(self):
447 flickTouchEventsPerSecond = 30
449 math.sqrt(dx * dx + dy * dy) * flickTouchEventsPerSecond / speed)
450 div = self._driver.ExecuteScript(
451 'document.body.innerHTML = "<div>old</div>";'
452 'var div = document.getElementsByTagName("div")[0];'
453 'div.addEventListener("touchstart", function() {'
454 ' div.innerHTML = "preMove0";'
456 'div.addEventListener("touchmove", function() {'
457 ' res = div.innerHTML.match(/preMove(\d+)/);'
458 ' if (res != null) {'
459 ' div.innerHTML = "preMove" + (parseInt(res[1], 10) + 1);'
462 'div.addEventListener("touchend", function() {'
463 ' if (div.innerHTML == "preMove' + str(moveEvents) + '") {'
464 ' div.innerHTML = "new<br>";'
468 self._driver.TouchFlick(div, dx, dy, speed)
469 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
471 def testTouchMovedElement(self):
472 div = self._driver.ExecuteScript(
473 'document.body.innerHTML = "<div>old</div>";'
474 'var div = document.getElementsByTagName("div")[0];'
475 'div.addEventListener("touchmove", function() {'
476 ' div.innerHTML="new<br>";'
479 loc = div.GetLocation()
480 self._driver.TouchDown(loc['x'], loc['y'])
481 self._driver.TouchMove(loc['x'] + 1, loc['y'] + 1)
482 self._driver.TouchUp(loc['x'] + 1, loc['y'] + 1)
483 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
485 def testClickElementInSubFrame(self):
486 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/frame_test.html'))
487 frame = self._driver.FindElement('tag name', 'iframe')
488 self._driver.SwitchToFrame(frame)
489 # Test clicking element in the sub frame.
490 self.testClickElement()
492 def testClearElement(self):
493 text = self._driver.ExecuteScript(
494 'document.body.innerHTML = \'<input type="text" value="abc">\';'
495 'var input = document.getElementsByTagName("input")[0];'
496 'input.addEventListener("change", function() {'
497 ' document.body.appendChild(document.createElement("br"));'
501 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
503 def testSendKeysToElement(self):
504 text = self._driver.ExecuteScript(
505 'document.body.innerHTML = \'<input type="text">\';'
506 'var input = document.getElementsByTagName("input")[0];'
507 'input.addEventListener("change", function() {'
508 ' document.body.appendChild(document.createElement("br"));'
511 text.SendKeys('0123456789+-*/ Hi')
512 text.SendKeys(', there!')
513 value = self._driver.ExecuteScript('return arguments[0].value;', text)
514 self.assertEquals('0123456789+-*/ Hi, there!', value)
516 def testGetCurrentUrl(self):
517 self.assertEquals('data:,', self._driver.GetCurrentUrl())
519 def testGoBackAndGoForward(self):
520 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
521 self._driver.GoBack()
522 self._driver.GoForward()
524 def testRefresh(self):
525 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
526 self._driver.Refresh()
528 def testMouseMoveTo(self):
529 div = self._driver.ExecuteScript(
530 'document.body.innerHTML = "<div>old</div>";'
531 'var div = document.getElementsByTagName("div")[0];'
532 'div.style["width"] = "100px";'
533 'div.style["height"] = "100px";'
534 'div.addEventListener("mouseover", function() {'
535 ' var div = document.getElementsByTagName("div")[0];'
536 ' div.innerHTML="new<br>";'
539 self._driver.MouseMoveTo(div, 10, 10)
540 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
542 def testMouseClick(self):
543 div = self._driver.ExecuteScript(
544 'document.body.innerHTML = "<div>old</div>";'
545 'var div = document.getElementsByTagName("div")[0];'
546 'div.style["width"] = "100px";'
547 'div.style["height"] = "100px";'
548 'div.addEventListener("click", function() {'
549 ' var div = document.getElementsByTagName("div")[0];'
550 ' div.innerHTML="new<br>";'
553 self._driver.MouseMoveTo(div)
554 self._driver.MouseClick()
555 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
557 def testMouseButtonDownAndUp(self):
558 self._driver.ExecuteScript(
559 'document.body.innerHTML = "<div>old</div>";'
560 'var div = document.getElementsByTagName("div")[0];'
561 'div.style["width"] = "100px";'
562 'div.style["height"] = "100px";'
563 'div.addEventListener("mousedown", function() {'
564 ' var div = document.getElementsByTagName("div")[0];'
565 ' div.innerHTML="new1<br>";'
567 'div.addEventListener("mouseup", function() {'
568 ' var div = document.getElementsByTagName("div")[0];'
569 ' div.innerHTML="new2<a></a>";'
571 self._driver.MouseMoveTo(None, 50, 50)
572 self._driver.MouseButtonDown()
573 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
574 self._driver.MouseButtonUp()
575 self.assertEquals(1, len(self._driver.FindElements('tag name', 'a')))
577 def testMouseDoubleClick(self):
578 div = self._driver.ExecuteScript(
579 'document.body.innerHTML = "<div>old</div>";'
580 'var div = document.getElementsByTagName("div")[0];'
581 'div.style["width"] = "100px";'
582 'div.style["height"] = "100px";'
583 'div.addEventListener("dblclick", function() {'
584 ' var div = document.getElementsByTagName("div")[0];'
585 ' div.innerHTML="new<br>";'
588 self._driver.MouseMoveTo(div, 1, 1)
589 self._driver.MouseDoubleClick()
590 self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
593 self.assertFalse(self._driver.IsAlertOpen())
594 self._driver.ExecuteScript(
596 ' function() { window.confirmed = confirm(\'HI\'); },'
598 self.assertTrue(self._driver.IsAlertOpen())
599 self.assertEquals('HI', self._driver.GetAlertMessage())
600 self._driver.HandleAlert(False)
601 self.assertFalse(self._driver.IsAlertOpen())
602 self.assertEquals(False,
603 self._driver.ExecuteScript('return window.confirmed'))
605 def testShouldHandleNewWindowLoadingProperly(self):
606 """Tests that ChromeDriver determines loading correctly for new windows."""
607 self._http_server.SetDataForPath(
612 <a href='%s' target='_blank'>new window/tab</a>
614 </html>""" % self._sync_server.GetUrl())
615 self._driver.Load(self._http_server.GetUrl() + '/newwindow')
616 old_windows = self._driver.GetWindowHandles()
617 self._driver.FindElement('tagName', 'a').Click()
618 new_window = self._WaitForNewWindow(old_windows)
619 self.assertNotEqual(None, new_window)
621 self.assertFalse(self._driver.IsLoading())
622 self._driver.SwitchToWindow(new_window)
623 self.assertTrue(self._driver.IsLoading())
624 self._sync_server.RespondWithContent('<html>new window</html>')
625 self._driver.ExecuteScript('return 1') # Shouldn't hang.
627 def testPopups(self):
628 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
629 old_handles = self._driver.GetWindowHandles()
630 self._driver.ExecuteScript('window.open("about:blank")')
631 new_window_handle = self._WaitForNewWindow(old_handles)
632 self.assertNotEqual(None, new_window_handle)
634 def testNoSuchFrame(self):
635 self.assertRaises(chromedriver.NoSuchFrame,
636 self._driver.SwitchToFrame, 'nosuchframe')
637 self.assertRaises(chromedriver.NoSuchFrame,
638 self._driver.SwitchToFrame,
639 self._driver.FindElement('tagName', 'body'))
641 def testWindowPosition(self):
642 position = self._driver.GetWindowPosition()
643 self._driver.SetWindowPosition(position[0], position[1])
644 self.assertEquals(position, self._driver.GetWindowPosition())
646 # Resize so the window isn't moved offscreen.
647 # See https://code.google.com/p/chromedriver/issues/detail?id=297.
648 self._driver.SetWindowSize(300, 300)
650 self._driver.SetWindowPosition(100, 200)
651 self.assertEquals([100, 200], self._driver.GetWindowPosition())
653 def testWindowSize(self):
654 size = self._driver.GetWindowSize()
655 self._driver.SetWindowSize(size[0], size[1])
656 self.assertEquals(size, self._driver.GetWindowSize())
658 self._driver.SetWindowSize(600, 400)
659 self.assertEquals([600, 400], self._driver.GetWindowSize())
661 def testWindowMaximize(self):
662 self._driver.SetWindowPosition(100, 200)
663 self._driver.SetWindowSize(600, 400)
664 self._driver.MaximizeWindow()
666 self.assertNotEqual([100, 200], self._driver.GetWindowPosition())
667 self.assertNotEqual([600, 400], self._driver.GetWindowSize())
668 # Set size first so that the window isn't moved offscreen.
669 # See https://code.google.com/p/chromedriver/issues/detail?id=297.
670 self._driver.SetWindowSize(600, 400)
671 self._driver.SetWindowPosition(100, 200)
672 self.assertEquals([100, 200], self._driver.GetWindowPosition())
673 self.assertEquals([600, 400], self._driver.GetWindowSize())
675 def testConsoleLogSources(self):
676 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/console_log.html'))
677 logs = self._driver.GetLog('browser')
678 self.assertEquals(len(logs), 2)
679 self.assertEquals(logs[0]['source'], 'network')
680 self.assertEquals(logs[1]['source'], 'javascript')
682 def testAutoReporting(self):
683 self.assertFalse(self._driver.IsAutoReporting())
684 self._driver.SetAutoReporting(True)
685 self.assertTrue(self._driver.IsAutoReporting())
686 url = self.GetHttpUrlForFile('/chromedriver/console_log.html')
687 self.assertRaisesRegexp(chromedriver.UnknownError,
688 '.*(404|Failed to load resource).*',
692 def testContextMenuEventFired(self):
693 self._driver.Load(self.GetHttpUrlForFile('/chromedriver/context_menu.html'))
694 self._driver.MouseMoveTo(self._driver.FindElement('tagName', 'div'))
695 self._driver.MouseClick(2)
696 self.assertTrue(self._driver.ExecuteScript('return success'))
698 def testHasFocusOnStartup(self):
699 # Some pages (about:blank) cause Chrome to put the focus in URL bar.
700 # This breaks tests depending on focus.
701 self.assertTrue(self._driver.ExecuteScript('return document.hasFocus()'))
703 def testTabCrash(self):
704 # If a tab is crashed, the session will be deleted.
705 # When 31 is released, will reload the tab instead.
706 # https://code.google.com/p/chromedriver/issues/detail?id=547
707 self.assertRaises(chromedriver.UnknownError,
708 self._driver.Load, 'chrome://crash')
709 self.assertRaises(chromedriver.NoSuchSession,
710 self._driver.GetCurrentUrl)
712 def testDoesntHangOnDebugger(self):
713 self._driver.ExecuteScript('debugger;')
715 def testMobileEmulationDisabledByDefault(self):
716 self.assertFalse(self._driver.capabilities['mobileEmulationEnabled'])
719 class ChromeDriverAndroidTest(ChromeDriverBaseTest):
720 """End to end tests for Android-specific tests."""
722 def testLatestAndroidAppInstalled(self):
723 if ('stable' not in _ANDROID_PACKAGE_KEY and
724 'beta' not in _ANDROID_PACKAGE_KEY):
727 self._driver = self.CreateDriver()
730 omaha_list = json.loads(
731 urllib2.urlopen('http://omahaproxy.appspot.com/all.json').read())
733 if l['os'] != 'android':
735 for v in l['versions']:
736 if (('stable' in v['channel'] and 'stable' in _ANDROID_PACKAGE_KEY) or
737 ('beta' in v['channel'] and 'beta' in _ANDROID_PACKAGE_KEY)):
738 self.assertEquals(v['version'],
739 self._driver.capabilities['version'])
741 raise RuntimeError('Malformed omaha JSON')
742 except urllib2.URLError as e:
743 print 'Unable to fetch current version info from omahaproxy (%s)' % e
745 def testDeviceManagement(self):
746 self._drivers = [self.CreateDriver() for x in
747 android_commands.GetAttachedDevices()]
748 self.assertRaises(chromedriver.UnknownError, self.CreateDriver)
749 self._drivers[0].Quit()
750 self._drivers[0] = self.CreateDriver()
753 class ChromeSwitchesCapabilityTest(ChromeDriverBaseTest):
754 """Tests that chromedriver properly processes chromeOptions.args capabilities.
756 Makes sure the switches are passed to Chrome.
759 def testSwitchWithoutArgument(self):
760 """Tests that switch --dom-automation can be passed to Chrome.
762 Unless --dom-automation is specified, window.domAutomationController
765 driver = self.CreateDriver(chrome_switches=['dom-automation'])
768 driver.ExecuteScript('return window.domAutomationController'))
771 class ChromeExtensionsCapabilityTest(ChromeDriverBaseTest):
772 """Tests that chromedriver properly processes chromeOptions.extensions."""
774 def _PackExtension(self, ext_path):
775 return base64.b64encode(open(ext_path, 'rb').read())
777 def testExtensionsInstall(self):
778 """Checks that chromedriver can take the extensions in crx format."""
779 crx_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.crx')
780 crx_2 = os.path.join(_TEST_DATA_DIR, 'ext_test_2.crx')
781 self.CreateDriver(chrome_extensions=[self._PackExtension(crx_1),
782 self._PackExtension(crx_2)])
784 def testExtensionsInstallZip(self):
785 """Checks that chromedriver can take the extensions in zip format."""
786 zip_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.zip')
787 self.CreateDriver(chrome_extensions=[self._PackExtension(zip_1)])
789 def testWaitsForExtensionToLoad(self):
790 did_load_event = threading.Event()
791 server = webserver.SyncWebServer()
794 server.RespondWithContent('<html>iframe</html>')
797 thread = threading.Thread(target=RunServer)
800 crx = os.path.join(_TEST_DATA_DIR, 'ext_slow_loader.crx')
801 driver = self.CreateDriver(
802 chrome_switches=['user-agent=' + server.GetUrl()],
803 chrome_extensions=[self._PackExtension(crx)])
804 self.assertTrue(did_load_event.is_set())
807 class ChromeLogPathCapabilityTest(ChromeDriverBaseTest):
808 """Tests that chromedriver properly processes chromeOptions.logPath."""
810 LOG_MESSAGE = 'Welcome to ChromeLogPathCapabilityTest!'
812 def testChromeLogPath(self):
813 """Checks that user can specify the path of the chrome log.
815 Verifies that a log message is written into the specified log file.
817 tmp_log_path = tempfile.NamedTemporaryFile()
818 driver = self.CreateDriver(chrome_log_path=tmp_log_path.name)
819 driver.ExecuteScript('console.info("%s")' % self.LOG_MESSAGE)
821 self.assertTrue(self.LOG_MESSAGE in open(tmp_log_path.name).read())
824 class MobileEmulationCapabilityTest(ChromeDriverBaseTest):
825 """Tests that ChromeDriver processes chromeOptions.mobileEmulation.
827 Makes sure the device metrics are overridden in DevTools and user agent is
828 overridden in Chrome.
833 def respondWithUserAgentString(request):
834 return request.GetHeader('User-Agent')
836 MobileEmulationCapabilityTest._http_server = webserver.WebServer(
837 chrome_paths.GetTestData())
838 MobileEmulationCapabilityTest._http_server.SetCallbackForPath(
839 '/userAgent', respondWithUserAgentString)
842 def GlobalTearDown():
843 MobileEmulationCapabilityTest._http_server.Shutdown()
845 def testDeviceMetrics(self):
846 driver = self.CreateDriver(
848 'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3}})
849 self.assertTrue(driver.capabilities['mobileEmulationEnabled'])
850 self.assertEqual(360, driver.ExecuteScript('return window.innerWidth'))
851 self.assertEqual(640, driver.ExecuteScript('return window.innerHeight'))
853 def testUserAgent(self):
854 driver = self.CreateDriver(
855 mobile_emulation = {'userAgent': 'Agent Smith'})
856 driver.Load(self._http_server.GetUrl() + '/userAgent')
857 body_tag = driver.FindElement('tag name', 'body')
858 self.assertEqual("Agent Smith", body_tag.GetText())
860 def testDeviceName(self):
861 driver = self.CreateDriver(
862 mobile_emulation = {'deviceName': 'Google Nexus 5'})
863 driver.Load(self._http_server.GetUrl() + '/userAgent')
864 self.assertEqual(360, driver.ExecuteScript('return window.innerWidth'))
865 self.assertEqual(640, driver.ExecuteScript('return window.innerHeight'))
866 body_tag = driver.FindElement('tag name', 'body')
868 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleW'
869 'ebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/53'
874 class ChromeDriverLogTest(unittest.TestCase):
875 """Tests that chromedriver produces the expected log file."""
877 UNEXPECTED_CHROMEOPTION_CAP = 'unexpected_chromeoption_capability'
878 LOG_MESSAGE = 'unrecognized chrome option: %s' % UNEXPECTED_CHROMEOPTION_CAP
880 def testChromeDriverLog(self):
881 _, tmp_log_path = tempfile.mkstemp(prefix='chromedriver_log_')
882 chromedriver_server = server.Server(
883 _CHROMEDRIVER_BINARY, log_path=tmp_log_path)
885 driver = chromedriver.ChromeDriver(
886 chromedriver_server.GetUrl(), chrome_binary=_CHROME_BINARY,
887 experimental_options={ self.UNEXPECTED_CHROMEOPTION_CAP : 1 })
889 except chromedriver.ChromeDriverException, e:
890 self.assertTrue(self.LOG_MESSAGE in e.message)
892 chromedriver_server.Kill()
893 with open(tmp_log_path, 'r') as f:
894 self.assertTrue(self.LOG_MESSAGE in f.read())
897 class SessionHandlingTest(ChromeDriverBaseTest):
898 """Tests for session operations."""
899 def testQuitASessionMoreThanOnce(self):
900 driver = self.CreateDriver()
905 class RemoteBrowserTest(ChromeDriverBaseTest):
906 """Tests for ChromeDriver remote browser capability."""
908 self.assertTrue(_CHROME_BINARY is not None,
909 'must supply a chrome binary arg')
911 def testConnectToRemoteBrowser(self):
912 port = self.FindFreePort()
913 temp_dir = util.MakeTempDir()
914 process = subprocess.Popen([_CHROME_BINARY,
915 '--remote-debugging-port=%d' % port,
916 '--user-data-dir=%s' % temp_dir])
918 raise RuntimeError('Chrome could not be started with debugging port')
920 driver = self.CreateDriver(debugger_address='127.0.0.1:%d' % port)
921 driver.ExecuteScript('console.info("%s")' % 'connecting at %d!' % port)
926 def FindFreePort(self):
927 for port in range(10000, 10100):
929 socket.create_connection(('127.0.0.1', port), 0.2).close()
932 raise RuntimeError('Cannot find open port')
934 class PerfTest(ChromeDriverBaseTest):
935 """Tests for ChromeDriver perf."""
937 self.assertTrue(_REFERENCE_CHROMEDRIVER is not None,
938 'must supply a reference-chromedriver arg')
940 def _RunDriverPerfTest(self, name, test_func):
941 """Runs a perf test comparing a reference and new ChromeDriver server.
944 name: The name of the perf test.
945 test_func: Called with the server url to perform the test action. Must
946 return the time elapsed.
948 class Results(object):
952 ref_server = server.Server(_REFERENCE_CHROMEDRIVER)
954 result_url_pairs = zip([results.new, results.ref],
955 [_CHROMEDRIVER_SERVER_URL, ref_server.GetUrl()])
956 for iteration in range(30):
957 for result, url in result_url_pairs:
958 result += [test_func(url)]
959 # Reverse the order for the next run.
960 result_url_pairs = result_url_pairs[::-1]
962 def PrintResult(build, result):
963 mean = sum(result) / len(result)
964 avg_dev = sum([abs(sample - mean) for sample in result]) / len(result)
965 print 'perf result', build, name, mean, avg_dev, result
966 util.AddBuildStepText('%s %s: %.3f+-%.3f' % (
967 build, name, mean, avg_dev))
969 # Discard first result, which may be off due to cold start.
970 PrintResult('new', results.new[1:])
971 PrintResult('ref', results.ref[1:])
973 def testSessionStartTime(self):
976 driver = self.CreateDriver(url)
980 self._RunDriverPerfTest('session start', Run)
982 def testSessionStopTime(self):
984 driver = self.CreateDriver(url)
989 self._RunDriverPerfTest('session stop', Run)
991 def testColdExecuteScript(self):
993 driver = self.CreateDriver(url)
995 driver.ExecuteScript('return 1')
999 self._RunDriverPerfTest('cold exe js', Run)
1001 if __name__ == '__main__':
1002 parser = optparse.OptionParser()
1004 '', '--chromedriver',
1005 help='Path to chromedriver server (REQUIRED!)')
1008 help='Output verbose server logs to this file')
1010 '', '--reference-chromedriver',
1011 help='Path to the reference chromedriver server')
1013 '', '--chrome', help='Path to a build of the chrome binary')
1015 '', '--chrome-version', default='HEAD',
1016 help='Version of chrome. Default is \'HEAD\'.')
1018 '', '--filter', type='string', default='*',
1019 help=('Filter for specifying what tests to run, "*" will run all. E.g., '
1022 '', '--android-package',
1023 help=('Android package key. Possible values: ' +
1024 str(_ANDROID_NEGATIVE_FILTER.keys())))
1025 options, args = parser.parse_args()
1027 options.chromedriver = util.GetAbsolutePathOfUserPath(options.chromedriver)
1028 if not options.chromedriver or not os.path.exists(options.chromedriver):
1029 parser.error('chromedriver is required or the given path is invalid.' +
1030 'Please run "%s --help" for help' % __file__)
1032 global _CHROMEDRIVER_BINARY
1033 _CHROMEDRIVER_BINARY = options.chromedriver
1035 if (options.android_package and
1036 options.android_package not in _ANDROID_NEGATIVE_FILTER):
1037 parser.error('Invalid --android-package')
1039 chromedriver_server = server.Server(_CHROMEDRIVER_BINARY, options.log_path)
1040 global _CHROMEDRIVER_SERVER_URL
1041 _CHROMEDRIVER_SERVER_URL = chromedriver_server.GetUrl()
1043 global _REFERENCE_CHROMEDRIVER
1044 _REFERENCE_CHROMEDRIVER = util.GetAbsolutePathOfUserPath(
1045 options.reference_chromedriver)
1047 global _CHROME_BINARY
1049 _CHROME_BINARY = util.GetAbsolutePathOfUserPath(options.chrome)
1051 _CHROME_BINARY = None
1053 global _ANDROID_PACKAGE_KEY
1054 _ANDROID_PACKAGE_KEY = options.android_package
1056 if options.filter == '*':
1057 if _ANDROID_PACKAGE_KEY:
1058 negative_filter = _ANDROID_NEGATIVE_FILTER[_ANDROID_PACKAGE_KEY]
1060 negative_filter = _GetDesktopNegativeFilter(options.chrome_version)
1061 options.filter = '*-' + ':__main__.'.join([''] + negative_filter)
1063 all_tests_suite = unittest.defaultTestLoader.loadTestsFromModule(
1064 sys.modules[__name__])
1065 tests = unittest_util.FilterTestSuite(all_tests_suite, options.filter)
1066 ChromeDriverTest.GlobalSetUp()
1067 MobileEmulationCapabilityTest.GlobalSetUp()
1068 result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(tests)
1069 ChromeDriverTest.GlobalTearDown()
1070 MobileEmulationCapabilityTest.GlobalTearDown()
1071 sys.exit(len(result.failures) + len(result.errors))