1# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Tests for ChromeDriver.
6
7If your test is testing a specific part of the WebDriver API, consider adding
8it to the appropriate place in the WebDriver tree instead.
9"""
10
11import binascii
12from distutils import archive_util
13import hashlib
14import httplib
15import os
16import platform
17import signal
18import subprocess
19import sys
20import tempfile
21import threading
22import time
23import unittest
24import urllib
25import urllib2
26import urlparse
27
28from chromedriver_factory import ChromeDriverFactory
29from chromedriver_launcher import ChromeDriverLauncher
30from chromedriver_test import ChromeDriverTest
31import test_paths
32import util
33
34try:
35  import simplejson as json
36except ImportError:
37  import json
38
39from selenium.common.exceptions import NoSuchWindowException
40from selenium.common.exceptions import WebDriverException
41from selenium.webdriver.common.action_chains import ActionChains
42from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
43from selenium.webdriver.common.keys import Keys
44from selenium.webdriver.remote.command import Command
45from selenium.webdriver.remote.webdriver import WebDriver
46from selenium.webdriver.support.ui import WebDriverWait
47
48
49def SkipIf(should_skip):
50  """Decorator which allows skipping individual test cases."""
51  if should_skip:
52    return lambda func: None
53  return lambda func: func
54
55
56class Request(urllib2.Request):
57  """Extends urllib2.Request to support all HTTP request types."""
58
59  def __init__(self, url, method=None, data=None):
60    """Initialise a new HTTP request.
61
62    Arguments:
63      url: The full URL to send the request to.
64      method: The HTTP request method to use; defaults to 'GET'.
65      data: The data to send with the request as a string. Defaults to
66          None and is ignored if |method| is not 'POST' or 'PUT'.
67    """
68    if method is None:
69      method = data is not None and 'POST' or 'GET'
70    elif method not in ('POST', 'PUT'):
71      data = None
72    self.method = method
73    urllib2.Request.__init__(self, url, data=data)
74
75  def get_method(self):
76    """Returns the HTTP method used by this request."""
77    return self.method
78
79
80def SendRequest(url, method=None, data=None):
81  """Sends a HTTP request to the WebDriver server.
82
83  Return values and exceptions raised are the same as those of
84  |urllib2.urlopen|.
85
86  Arguments:
87    url: The full URL to send the request to.
88    method: The HTTP request method to use; defaults to 'GET'.
89    data: The data to send with the request as a string. Defaults to
90        None and is ignored if |method| is not 'POST' or 'PUT'.
91
92    Returns:
93      A file-like object.
94  """
95  request = Request(url, method=method, data=data)
96  request.add_header('Accept', 'application/json')
97  opener = urllib2.build_opener(urllib2.HTTPRedirectHandler())
98  return opener.open(request)
99
100
101class BasicTest(ChromeDriverTest):
102  """Basic ChromeDriver tests."""
103
104  def setUp(self):
105    self._server2 = ChromeDriverLauncher(self.GetDriverPath()).Launch()
106
107  def tearDown(self):
108    self._server2.Kill()
109
110  def testShouldReturn403WhenSentAnUnknownCommandURL(self):
111    request_url = self._server2.GetUrl() + '/foo'
112    try:
113      SendRequest(request_url, method='GET')
114      self.fail('Should have raised a urllib.HTTPError for returned 403')
115    except urllib2.HTTPError, expected:
116      self.assertEquals(403, expected.code)
117
118  def testShouldReturnHTTP405WhenSendingANonPostToTheSessionURL(self):
119    request_url = self._server2.GetUrl() + '/session'
120    try:
121      SendRequest(request_url, method='GET')
122      self.fail('Should have raised a urllib.HTTPError for returned 405')
123    except urllib2.HTTPError, expected:
124      self.assertEquals(405, expected.code)
125      self.assertEquals('POST', expected.hdrs['Allow'])
126
127  def testShouldGetA404WhenAttemptingToDeleteAnUnknownSession(self):
128    request_url = self._server2.GetUrl() + '/session/unkown_session_id'
129    try:
130      SendRequest(request_url, method='DELETE')
131      self.fail('Should have raised a urllib.HTTPError for returned 404')
132    except urllib2.HTTPError, expected:
133      self.assertEquals(404, expected.code)
134
135  def testShouldReturn204ForFaviconRequests(self):
136    request_url = self._server2.GetUrl() + '/favicon.ico'
137    # In python2.5, a 204 status code causes an exception.
138    if sys.version_info[0:2] == (2, 5):
139      try:
140        SendRequest(request_url, method='GET')
141        self.fail('Should have raised a urllib.HTTPError for returned 204')
142      except urllib2.HTTPError, expected:
143        self.assertEquals(204, expected.code)
144    else:
145      response = SendRequest(request_url, method='GET')
146      try:
147        self.assertEquals(204, response.code)
148      finally:
149        response.close()
150
151  def testCreatingSessionShouldRedirectToCorrectURL(self):
152    request_url = self._server2.GetUrl() + '/session'
153    response = SendRequest(request_url, method='POST',
154                           data='{"desiredCapabilities": {}}')
155    self.assertEquals(200, response.code)
156    self.session_url = response.geturl()  # TODO(jleyba): verify this URL?
157
158    data = json.loads(response.read())
159    self.assertTrue(isinstance(data, dict))
160    self.assertEquals(0, data['status'])
161
162    url_parts = urlparse.urlparse(self.session_url)[2].split('/')
163    self.assertEquals(3, len(url_parts))
164    self.assertEquals('', url_parts[0])
165    self.assertEquals('session', url_parts[1])
166    self.assertEquals(data['sessionId'], url_parts[2])
167
168
169class WebserverTest(ChromeDriverTest):
170  """Tests the built-in ChromeDriver webserver."""
171
172  def testShouldNotServeFilesByDefault(self):
173    server = ChromeDriverLauncher(self.GetDriverPath()).Launch()
174    try:
175      SendRequest(server.GetUrl(), method='GET')
176      self.fail('Should have raised a urllib.HTTPError for returned 403')
177    except urllib2.HTTPError, expected:
178      self.assertEquals(403, expected.code)
179    finally:
180      server.Kill()
181
182  def testCanServeFiles(self):
183    launcher = ChromeDriverLauncher(self.GetDriverPath(),
184                                    root_path=os.path.dirname(__file__))
185    server = launcher.Launch()
186    request_url = server.GetUrl() + '/' + os.path.basename(__file__)
187    SendRequest(request_url, method='GET')
188    server.Kill()
189
190
191class DesiredCapabilitiesTest(ChromeDriverTest):
192  """Tests for webdriver desired capabilities."""
193
194  def testCustomSwitches(self):
195    switches = ['enable-file-cookie']
196    capabilities = {'chrome.switches': switches}
197
198    driver = self.GetNewDriver(capabilities)
199    driver.get('about:version')
200    self.assertNotEqual(-1, driver.page_source.find('enable-file-cookie'))
201    driver.quit()
202
203  def testBinary(self):
204    self.GetNewDriver({'chrome.binary': self.GetChromePath()})
205
206  def testUserProfile(self):
207    """Test starting WebDriver session with custom profile."""
208
209    # Open a new session and save the user profile.
210    profile_dir = tempfile.mkdtemp()
211    capabilities = {'chrome.switches': ['--user-data-dir=' + profile_dir]}
212    driver = self.GetNewDriver(capabilities)
213    driver.get(self.GetTestDataUrl() + '/test_page.html')
214    # Create a cookie.
215    cookie_dict = {}
216    cookie_dict['name'] = 'test_user_profile'
217    cookie_dict['value'] = 'chrome profile'
218    cookie_dict['expiry'] = time.time() + 120
219    driver.add_cookie(cookie_dict)
220    driver.quit()
221
222    profile_zip = archive_util.make_archive(os.path.join(profile_dir,
223                                                         'profile'),
224                                            'zip',
225                                            root_dir=profile_dir,
226                                            base_dir='Default')
227    f = open(profile_zip, 'rb')
228    base64_user_profile = binascii.b2a_base64(f.read()).strip()
229    f.close()
230    os.remove(profile_zip)
231
232    # Start new session with the saved user profile.
233    capabilities = {'chrome.profile': base64_user_profile}
234    driver = self.GetNewDriver(capabilities)
235    driver.get(self.GetTestDataUrl() + '/test_page.html')
236    cookie_dict = driver.get_cookie('test_user_profile')
237    self.assertNotEqual(cookie_dict, None)
238    self.assertEqual(cookie_dict['value'], 'chrome profile')
239    driver.quit()
240
241  def testInstallExtensions(self):
242    """Test starting web driver with multiple extensions."""
243    extensions = ['ext_test_1.crx', 'ext_test_2.crx']
244    base64_extensions = []
245    for ext in extensions:
246      f = open(test_paths.GetTestDataPath(ext), 'rb')
247      base64_ext = (binascii.b2a_base64(f.read()).strip())
248      base64_extensions.append(base64_ext)
249      f.close()
250    capabilities = {'chrome.extensions': base64_extensions}
251    driver = self.GetNewDriver(capabilities)
252    extension_names = [x.get_name() for x in driver.get_installed_extensions()]
253    self.assertEquals(2, len(extension_names))
254    self.assertTrue('ExtTest1' in extension_names)
255    self.assertTrue('ExtTest2' in extension_names)
256    driver.quit()
257
258  def testPrefs(self):
259    """Test that chromedriver can set user preferences."""
260    driver = self.GetNewDriver({
261      'chrome.noWebsiteTestingDefaults': True,
262      'chrome.prefs': {
263        'profile.default_content_settings': {
264          'popups': 1
265        },
266      }
267    })
268    driver.get(self.GetTestDataUrl() + '/empty.html')
269    driver.execute_script('window.open("about:blank")')
270    self.assertEquals(2, len(driver.window_handles))
271
272  def testLoadAsync(self):
273    """Test that chromedriver can load pages asynchronously."""
274    driver = self.GetNewDriver({'chrome.loadAsync': True})
275
276    # Check that navigate doesn't wait for the page to load.
277    driver.get(self.GetTestDataUrl() + '/hang')
278
279    # Check that the navigation actually starts.
280    def IsEmptyPage(driver):
281      return driver.current_url.endswith('empty.html')
282    driver.get(self.GetTestDataUrl() + '/empty.html')
283    WebDriverWait(driver, 10).until(IsEmptyPage)
284
285
286class DetachProcessTest(ChromeDriverTest):
287
288  def setUp(self):
289    self._server2 = ChromeDriverLauncher(self.GetDriverPath()).Launch()
290    self._factory2 = ChromeDriverFactory(self._server2)
291
292  def tearDown(self):
293    self._server2.Kill()
294
295  # TODO(kkania): Remove this when Chrome 15 is stable.
296  # crbug.com/134982
297  def DISABLED_testDetachProcess(self):
298    # This is a weak test. Its purpose is to just make sure we can start
299    # Chrome successfully in detached mode. There's not an easy way to know
300    # if Chrome is shutting down due to the channel error when the client
301    # disconnects.
302    driver = self._factory2.GetNewDriver({'chrome.detach': True})
303    driver.get('about:memory')
304    pid = int(driver.find_elements_by_xpath('//*[@jscontent="pid"]')[0].text)
305    self._server2.Kill()
306    try:
307      util.Kill(pid)
308    except OSError:
309      self.fail('Chrome quit after detached chromedriver server was killed')
310
311
312class CookieTest(ChromeDriverTest):
313  """Cookie test for the json webdriver protocol"""
314
315  def testAddCookie(self):
316    driver = self.GetNewDriver()
317    driver.get(self.GetTestDataUrl() + '/test_page.html')
318    cookie_dict = None
319    cookie_dict = driver.get_cookie("chromedriver_cookie_test")
320    cookie_dict = {}
321    cookie_dict["name"] = "chromedriver_cookie_test"
322    cookie_dict["value"] = "this is a test"
323    driver.add_cookie(cookie_dict)
324    cookie_dict = driver.get_cookie("chromedriver_cookie_test")
325    self.assertNotEqual(cookie_dict, None)
326    self.assertEqual(cookie_dict["value"], "this is a test")
327
328  def testDeleteCookie(self):
329    driver = self.GetNewDriver()
330    self.testAddCookie();
331    driver.delete_cookie("chromedriver_cookie_test")
332    cookie_dict = driver.get_cookie("chromedriver_cookie_test")
333    self.assertEqual(cookie_dict, None)
334
335
336class ScreenshotTest(ChromeDriverTest):
337  """Tests to verify screenshot retrieval"""
338
339  REDBOX = "automation_proxy_snapshot/set_size.html"
340
341  def testScreenCaptureAgainstReference(self):
342    # Create a red square of 2000x2000 pixels.
343    url = util.GetFileURLForPath(test_paths.GetChromeTestDataPath(self.REDBOX))
344    url += '?2000,2000'
345    driver = self.GetNewDriver()
346    driver.get(url)
347    s = driver.get_screenshot_as_base64()
348    h = hashlib.md5(s).hexdigest()
349    # Compare the PNG created to the reference hash.
350    self.assertEquals(h, '12c0ade27e3875da3d8866f52d2fa84f')
351
352  # This test requires Flash and must be run on a VM or via remote desktop.
353  # See crbug.com/96317.
354  def testSnapshotWithWindowlessFlashAndTransparentOverlay(self):
355    if not util.IsWin():
356      return
357
358    driver = self.GetNewDriver()
359    driver.get(self.GetTestDataUrl() + '/plugin_transparency_test.html')
360    snapshot = driver.get_screenshot_as_base64()
361    self.assertEquals(hashlib.md5(snapshot).hexdigest(),
362                      '72e5b8525e48758bae59997472f27f14')
363
364
365class SessionTest(ChromeDriverTest):
366  """Tests dealing with WebDriver sessions."""
367
368  def testShouldBeGivenCapabilitiesWhenStartingASession(self):
369    driver = self.GetNewDriver()
370    capabilities = driver.capabilities
371
372    self.assertEquals('chrome', capabilities['browserName'])
373    self.assertTrue(capabilities['javascriptEnabled'])
374    self.assertTrue(capabilities['takesScreenshot'])
375    self.assertTrue(capabilities['cssSelectorsEnabled'])
376
377    # Value depends on what version the server is starting.
378    self.assertTrue('version' in capabilities)
379    self.assertTrue(
380        isinstance(capabilities['version'], unicode),
381        'Expected a %s, but was %s' % (unicode,
382                                       type(capabilities['version'])))
383
384    system = platform.system()
385    if system == 'Linux':
386      self.assertEquals('linux', capabilities['platform'].lower())
387    elif system == 'Windows':
388      self.assertEquals('windows', capabilities['platform'].lower())
389    elif system == 'Darwin':
390      self.assertEquals('mac', capabilities['platform'].lower())
391    else:
392      # No python on ChromeOS, so we won't have a platform value, but
393      # the server will know and return the value accordingly.
394      self.assertEquals('chromeos', capabilities['platform'].lower())
395
396  def testSessionCreationDeletion(self):
397    self.GetNewDriver().quit()
398
399  # crbug.com/103396
400  def DISABLED_testMultipleSessionCreationDeletion(self):
401    for i in range(10):
402      self.GetNewDriver().quit()
403
404  def testSessionCommandsAfterSessionDeletionReturn404(self):
405    driver = self.GetNewDriver()
406    url = self.GetTestDataUrl()
407    url += '/session/' + driver.session_id
408    driver.quit()
409    try:
410      response = SendRequest(url, method='GET')
411      self.fail('Should have thrown 404 exception')
412    except urllib2.HTTPError, expected:
413      self.assertEquals(404, expected.code)
414
415  def testMultipleConcurrentSessions(self):
416    drivers = []
417    for i in range(10):
418      drivers += [self.GetNewDriver()]
419    for driver in drivers:
420      driver.quit()
421
422
423class ShutdownTest(ChromeDriverTest):
424
425  def setUp(self):
426    super(ShutdownTest, self).setUp()
427    self._custom_server = ChromeDriverLauncher(self.GetDriverPath()).Launch()
428    self._custom_factory = ChromeDriverFactory(self._custom_server,
429                                               self.GetChromePath())
430
431  def tearDown(self):
432    self._custom_server.Kill()
433    super(ShutdownTest, self).tearDown()
434
435  def testShutdownWithSession(self):
436    driver = self._custom_factory.GetNewDriver()
437    driver.get(self._custom_server.GetUrl() + '/status')
438    driver.find_element_by_tag_name('body')
439    self._custom_server.Kill()
440
441  def testShutdownWithBusySession(self):
442    def _Hang(driver):
443      """Waits for the process to quit and then notifies."""
444      try:
445        driver.get(self._custom_server.GetUrl() + '/hang')
446      except httplib.BadStatusLine:
447        pass
448
449    driver = self._custom_factory.GetNewDriver()
450    wait_thread = threading.Thread(target=_Hang, args=(driver,))
451    wait_thread.start()
452    wait_thread.join(5)
453    self.assertTrue(wait_thread.isAlive())
454
455    self._custom_server.Kill()
456    wait_thread.join(10)
457    self.assertFalse(wait_thread.isAlive())
458
459
460class MouseTest(ChromeDriverTest):
461  """Mouse command tests for the json webdriver protocol"""
462
463  def setUp(self):
464    super(MouseTest, self).setUp()
465    self._driver = self.GetNewDriver()
466
467  def testCanClickTransparentElement(self):
468    self._driver.get(self.GetTestDataUrl() + '/transparent.html')
469    self._driver.find_element_by_tag_name('a').click()
470    self.assertTrue(self._driver.execute_script('return window.success'))
471
472  # crbug.com/136875
473  def DISABLED_testClickElementThatNeedsContainerScrolling(self):
474    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
475    self._driver.find_element_by_name('hidden_scroll').click()
476    self.assertTrue(self._driver.execute_script('return window.success'))
477
478  # crbug.com/136875
479  def DISABLED_testClickElementThatNeedsIframeScrolling(self):
480    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
481    self._driver.switch_to_frame('iframe')
482    self._driver.find_element_by_name('hidden_scroll').click()
483    self.assertTrue(self._driver.execute_script('return window.success'))
484
485  def testClickElementThatNeedsPageScrolling(self):
486    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
487    self._driver.find_element_by_name('far_away').click()
488    self.assertTrue(self._driver.execute_script('return window.success'))
489
490  # TODO(kkania): Move this test to the webdriver repo.
491  def testClickDoesSelectOption(self):
492    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
493    option = self._driver.find_element_by_name('option')
494    self.assertFalse(option.is_selected())
495    option.click()
496    self.assertTrue(option.is_selected())
497
498  def testClickDoesUseFirstClientRect(self):
499    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
500    self._driver.find_element_by_name('wrapped').click()
501    self.assertTrue(self._driver.execute_script('return window.success'))
502
503  def testThrowErrorIfNotClickable(self):
504    self._driver.get(self.GetTestDataUrl() + '/not_clickable.html')
505    elem = self._driver.find_element_by_name('click')
506    self.assertRaises(WebDriverException, elem.click)
507
508
509# crbug.com/109698: when running in xvfb, 2 extra mouse moves are received.
510# crbug.com/138125: fails if the mouse cursor is left over the page.
511@SkipIf(True)
512class MouseEventTest(ChromeDriverTest):
513  """Tests for checking the correctness of mouse events."""
514
515  def setUp(self):
516    super(MouseEventTest, self).setUp()
517    self._driver = self.GetNewDriver()
518    ActionChains(self._driver).key_down([Keys.CONTROL, Keys.SHIFT]).perform()
519    self._driver.get(self.GetTestDataUrl() + '/events.html')
520    self._divs = self._driver.find_elements_by_tag_name('div')
521
522  def _CheckEvent(self, event, event_type, mouse_button, x, y):
523    """Checks the given event properties.
524
525    This function expects the ctrl and shift keys to be pressed.
526    """
527    self.assertEquals(event_type, event['type'])
528    self.assertEquals(mouse_button, event['button'])
529    self.assertEquals(False, event['altKey'])
530    self.assertEquals(True, event['ctrlKey'])
531    self.assertEquals(True, event['shiftKey'])
532    self.assertEquals(x, event['x'])
533    self.assertEquals(y, event['y'])
534
535  def _GetElementMiddle(self, elem):
536    x = elem.location['x']
537    y = elem.location['y']
538    return (x + (elem.size['width'] + 1) / 2, y + (elem.size['height'] + 1) / 2)
539
540  def testMoveCommand(self):
541    x = self._divs[0].location['x']
542    y = self._divs[0].location['y']
543    center_x, center_y = self._GetElementMiddle(self._divs[0])
544
545    # Move to element.
546    ActionChains(self._driver).move_to_element(self._divs[0]).perform()
547    events = self._driver.execute_script('return takeEvents()')
548    self.assertEquals(1, len(events))
549    self._CheckEvent(events[0], 'mousemove', 0, center_x, center_y)
550
551    # Move by offset.
552    ActionChains(self._driver).move_by_offset(1, 2).perform()
553    events = self._driver.execute_script('return takeEvents()')
554    self.assertEquals(1, len(events))
555    self._CheckEvent(events[0], 'mousemove', 0, center_x + 1, center_y + 2)
556
557    # Move to element and offset.
558    ActionChains(self._driver).move_to_element_with_offset(
559        self._divs[0], 2, 1).perform()
560    events = self._driver.execute_script('return takeEvents()')
561    self.assertEquals(1, len(events))
562    self._CheckEvent(events[0], 'mousemove', 0, x + 2, y + 1)
563
564  def testClickCommand(self):
565    center_x, center_y = self._GetElementMiddle(self._divs[0])
566
567    # Left click element.
568    ActionChains(self._driver).click(self._divs[0]).perform()
569    events = self._driver.execute_script('return takeEvents()')
570    self.assertEquals(3, len(events))
571    self._CheckEvent(events[0], 'mousemove', 0, center_x, center_y)
572    self._CheckEvent(events[1], 'mousedown', 0, center_x, center_y)
573    self._CheckEvent(events[2], 'mouseup', 0, center_x, center_y)
574
575    # Left click.
576    ActionChains(self._driver).click(None).perform()
577    events = self._driver.execute_script('return takeEvents()')
578    self.assertEquals(2, len(events))
579    self._CheckEvent(events[0], 'mousedown', 0, center_x, center_y)
580    self._CheckEvent(events[1], 'mouseup', 0, center_x, center_y)
581
582    # Right click.
583    ActionChains(self._driver).context_click(None).perform()
584    events = self._driver.execute_script('return takeEvents()')
585    self.assertEquals(2, len(events))
586    self._CheckEvent(events[0], 'mousedown', 2, center_x, center_y)
587    self._CheckEvent(events[1], 'mouseup', 2, center_x, center_y)
588
589  def testButtonDownUpCommand(self):
590    center_x, center_y = self._GetElementMiddle(self._divs[0])
591    center_x2, center_y2 = self._GetElementMiddle(self._divs[1])
592
593    # Press and release element.
594    ActionChains(self._driver).click_and_hold(self._divs[0]).release(
595        self._divs[1]).perform()
596    events = self._driver.execute_script('return takeEvents()')
597    self.assertEquals(4, len(events))
598    self._CheckEvent(events[0], 'mousemove', 0, center_x, center_y)
599    self._CheckEvent(events[1], 'mousedown', 0, center_x, center_y)
600    self._CheckEvent(events[2], 'mousemove', 0, center_x2, center_y2)
601    self._CheckEvent(events[3], 'mouseup', 0, center_x2, center_y2)
602
603    # Press and release.
604    ActionChains(self._driver).click_and_hold(None).release(None).perform()
605    events = self._driver.execute_script('return takeEvents()')
606    self.assertEquals(2, len(events))
607    self._CheckEvent(events[0], 'mousedown', 0, center_x2, center_y2)
608    self._CheckEvent(events[1], 'mouseup', 0, center_x2, center_y2)
609
610  def testDoubleClickCommand(self):
611    center_x, center_y = self._GetElementMiddle(self._divs[0])
612
613    # Double click element.
614    ActionChains(self._driver).double_click(self._divs[0]).perform()
615    events = self._driver.execute_script('return takeEvents()')
616    self.assertEquals(6, len(events))
617    self._CheckEvent(events[5], 'dblclick', 0, center_x, center_y)
618
619    # Double click.
620    ActionChains(self._driver).double_click(None).perform()
621    events = self._driver.execute_script('return takeEvents()')
622    self.assertEquals(5, len(events))
623    self._CheckEvent(events[4], 'dblclick', 0, center_x, center_y)
624
625  def testElementAPIClick(self):
626    center_x, center_y = self._GetElementMiddle(self._divs[0])
627
628    # Left click element.
629    self._divs[0].click()
630    events = self._driver.execute_script('return takeEvents()')
631    self.assertEquals(3, len(events))
632    self._CheckEvent(events[0], 'mousemove', 0, center_x, center_y)
633    self._CheckEvent(events[1], 'mousedown', 0, center_x, center_y)
634    self._CheckEvent(events[2], 'mouseup', 0, center_x, center_y)
635
636
637class TypingTest(ChromeDriverTest):
638
639  def setUp(self):
640    super(TypingTest, self).setUp()
641    self._driver = self.GetNewDriver()
642
643  def testSendKeysToEditingHostDiv(self):
644    self._driver.get(self.GetTestDataUrl() + '/content_editable.html')
645    div = self._driver.find_element_by_name('editable')
646    # Break into two to ensure element doesn't lose focus.
647    div.send_keys('hi')
648    div.send_keys(' there')
649    self.assertEquals('hi there', div.text)
650
651  def testSendKeysToNonFocusableChildOfEditingHost(self):
652    self._driver.get(self.GetTestDataUrl() + '/content_editable.html')
653    child = self._driver.find_element_by_name('editable_child')
654    self.assertRaises(WebDriverException, child.send_keys, 'hi')
655
656  def testSendKeysToFocusableChildOfEditingHost(self):
657    self._driver.get(self.GetTestDataUrl() + '/content_editable.html')
658    child = self._driver.find_element_by_tag_name('input')
659    child.send_keys('hi')
660    child.send_keys(' there')
661    self.assertEquals('hi there', child.get_attribute('value'))
662
663  def testSendKeysToDesignModePage(self):
664    self._driver.get(self.GetTestDataUrl() + '/design_mode_doc.html')
665    body = self._driver.find_element_by_tag_name('body')
666    body.send_keys('hi')
667    body.send_keys(' there')
668    self.assertEquals('hi there', body.text)
669
670  def testSendKeysToDesignModeIframe(self):
671    self._driver.get(self.GetTestDataUrl() + '/content_editable.html')
672    self._driver.switch_to_frame(0)
673    body = self._driver.find_element_by_tag_name('body')
674    body.send_keys('hi')
675    body.send_keys(' there')
676    self.assertEquals('hi there', body.text)
677
678  def testSendKeysToTransparentElement(self):
679    self._driver.get(self.GetTestDataUrl() + '/transparent.html')
680    text_box = self._driver.find_element_by_tag_name('input')
681    text_box.send_keys('hi')
682    self.assertEquals('hi', text_box.get_attribute('value'))
683
684  def testSendKeysDesignModePageAfterNavigate(self):
685    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
686    self._driver.get(self.GetTestDataUrl() + '/design_mode_doc.html')
687    body = self._driver.find_element_by_tag_name('body')
688    body.send_keys('hi')
689    body.send_keys(' there')
690    self.assertEquals('hi there', body.text)
691
692  def testAppendsToTextInput(self):
693    self._driver.get(self.GetTestDataUrl() + '/keyboard.html')
694    text_elem = self._driver.find_element_by_name('input')
695    text_elem.send_keys(' text')
696    self.assertEquals('more text', text_elem.get_attribute('value'))
697    area_elem = self._driver.find_element_by_name('area')
698    area_elem.send_keys(' text')
699    self.assertEquals('more text', area_elem.get_attribute('value'))
700
701  def testTextAreaKeepsCursorPosition(self):
702    self._driver.get(self.GetTestDataUrl() + '/keyboard.html')
703    area_elem = self._driver.find_element_by_name('area')
704    area_elem.send_keys(' text')
705    area_elem.send_keys(Keys.LEFT * 9)
706    area_elem.send_keys('much ')
707    self.assertEquals('much more text', area_elem.get_attribute('value'))
708
709  def testWithWebWidgets(self):
710    def SetHTML(html):
711      """Sets the page HTML.
712
713      The given HTML should not contain single quotes.
714      """
715      assert '\'' not in html
716      self._driver.execute_script('document.body.innerHTML = \'%s\'' % html)
717    SetHTML('<input type="checkbox">check</input>')
718    elem = self._driver.find_element_by_tag_name('input')
719    elem.send_keys(' ')
720    self.assertTrue(elem.is_selected())
721    elem.send_keys(' ')
722    self.assertFalse(elem.is_selected())
723
724    SetHTML('<input type="radio" name="g" checked>1</input>' +
725            '<input type="radio" name="g">2</input>')
726    elem1, elem2 = self._driver.find_elements_by_tag_name('input')
727    elem1.send_keys(Keys.RIGHT)
728    self.assertTrue(elem2.is_selected())
729    elem2.send_keys(Keys.LEFT)
730    self.assertFalse(elem2.is_selected())
731
732    SetHTML('<select><option>a</option><option>b</option></select>')
733    elem = self._driver.find_element_by_tag_name('select')
734    elem.send_keys('b')
735    self.assertEquals('b', elem.get_attribute('value'))
736
737    handler = 'javascript:document.title=\\x27success\\x27'
738    SetHTML('<input type="button" onclick="%s"></input>' % handler)
739    elem = self._driver.find_element_by_tag_name('input')
740    elem.send_keys(' ')
741    self.assertEquals('success', self._driver.title)
742
743
744class UrlBaseTest(ChromeDriverTest):
745  """Tests that the server can be configured for a different URL base."""
746
747  def setUp(self):
748    self._server2 = ChromeDriverLauncher(self.GetDriverPath(),
749                                         url_base='/wd/hub').Launch()
750
751  def tearDown(self):
752    self._server2.Kill()
753
754  def testCreatingSessionShouldRedirectToCorrectURL(self):
755    request_url = self._server2.GetUrl() + '/session'
756    response = SendRequest(request_url, method='POST',
757                           data='{"desiredCapabilities":{}}')
758    self.assertEquals(200, response.code)
759    self.session_url = response.geturl()  # TODO(jleyba): verify this URL?
760
761    data = json.loads(response.read())
762    self.assertTrue(isinstance(data, dict))
763    self.assertEquals(0, data['status'])
764
765    url_parts = urlparse.urlparse(self.session_url)[2].split('/')
766    self.assertEquals(5, len(url_parts))
767    self.assertEquals('', url_parts[0])
768    self.assertEquals('wd', url_parts[1])
769    self.assertEquals('hub', url_parts[2])
770    self.assertEquals('session', url_parts[3])
771    self.assertEquals(data['sessionId'], url_parts[4])
772
773
774# TODO(jleyba): Port this to WebDriver's own python test suite.
775class ElementEqualityTest(ChromeDriverTest):
776  """Tests that the server properly checks element equality."""
777
778  def setUp(self):
779    super(ElementEqualityTest, self).setUp()
780    self._driver = self.GetNewDriver()
781
782  def tearDown(self):
783    self._driver.quit()
784
785  def testElementEquality(self):
786    self._driver.get(self.GetTestDataUrl() + '/test_page.html')
787    body1 = self._driver.find_element_by_tag_name('body')
788    body2 = self._driver.execute_script('return document.body')
789
790    # TODO(jleyba): WebDriver's python bindings should expose a proper API
791    # for this.
792    result = body1._execute(Command.ELEMENT_EQUALS, {
793      'other': body2.id
794    })
795    self.assertTrue(result['value'])
796
797
798class LoggingTest(ChromeDriverTest):
799
800  def testLogging(self):
801    url = self.GetServer().GetUrl()
802    req = SendRequest(url + '/log', method='GET')
803    log = req.read()
804    self.assertTrue('INFO' in log, msg='INFO not in log: ' + log)
805
806
807class FileUploadControlTest(ChromeDriverTest):
808  """Tests dealing with file upload control."""
809
810  def setUp(self):
811    super(FileUploadControlTest, self).setUp()
812    self._driver = self.GetNewDriver()
813
814  # Fails on win - crbug.com/131782
815  def DISABLED_testSetFilePathToFileUploadControl(self):
816    """Verify a file path is set to the file upload control."""
817    self._driver.get(self.GetTestDataUrl() + '/upload.html')
818
819    tmp_file = tempfile.NamedTemporaryFile()
820
821    fileupload_single = self._driver.find_element_by_name('fileupload_single')
822    multiple = fileupload_single.get_attribute('multiple')
823    self.assertEqual('false', multiple)
824    fileupload_single.send_keys(tmp_file.name)
825    path = fileupload_single.get_attribute('value')
826    self.assertTrue(path.endswith(os.path.basename(tmp_file.name)))
827
828  def testSetMultipleFilePathsToFileuploadControlWithoutMultipleWillFail(self):
829    """Verify setting file paths to the file upload control without 'multiple'
830    attribute will fail."""
831    self._driver.get(self.GetTestDataUrl() + '/upload.html')
832
833    files = []
834    filepaths = []
835    for index in xrange(4):
836      tmp_file = tempfile.NamedTemporaryFile()
837      # We need to hold the file objects because the files will be deleted on
838      # GC.
839      files.append(tmp_file)
840      filepath = tmp_file.name
841      filepaths.append(filepath)
842
843    fileupload_single = self._driver.find_element_by_name('fileupload_single')
844    self.assertFalse(fileupload_single.get_attribute('multiple'))
845    self.assertRaises(WebDriverException, fileupload_single.send_keys,
846                      '\n'.join(filepaths))
847
848  def testSetMultipleFilePathsToFileUploadControl(self):
849    """Verify multiple file paths are set to the file upload control."""
850    self._driver.get(self.GetTestDataUrl() + '/upload.html')
851
852    files = []
853    filepaths = []
854    filenames = set()
855    for index in xrange(4):
856      tmp_file = tempfile.NamedTemporaryFile()
857      files.append(tmp_file)
858      filepath = tmp_file.name
859      filepaths.append(filepath)
860      filenames.add(os.path.basename(filepath))
861
862    fileupload_multi = self._driver.find_element_by_name('fileupload_multi')
863    multiple = fileupload_multi.get_attribute('multiple')
864    self.assertEqual('true', multiple)
865    fileupload_multi.send_keys('\n'.join(filepaths))
866
867    files_on_element = self._driver.execute_script(
868        'return document.getElementById("fileupload_multi").files;')
869    self.assertTrue(files_on_element)
870    self.assertEqual(4, len(files_on_element))
871    for f in files_on_element:
872      self.assertTrue(f['name'] in filenames)
873
874
875class FrameSwitchingTest(ChromeDriverTest):
876
877  def testGetWindowHandles(self):
878    driver = self.GetNewDriver({'chrome.switches': ['disable-popup-blocking']})
879    driver.get(self.GetTestDataUrl() + '/test_page.html')
880    driver.execute_script('window.popup = window.open("about:blank")')
881    self.assertEquals(2, len(driver.window_handles))
882    driver.execute_script('window.popup.close()')
883    self.assertEquals(1, len(driver.window_handles))
884
885  def testSwitchToSameWindow(self):
886    driver = self.GetNewDriver({'chrome.switches': ['disable-popup-blocking']})
887    driver.get(self.GetTestDataUrl() + '/test_page.html')
888    driver.switch_to_window(driver.window_handles[0])
889    self.assertEquals('test_page.html', driver.current_url.split('/')[-1])
890
891  def testClosedWindowThrows(self):
892    driver = self.GetNewDriver({'chrome.switches': ['disable-popup-blocking']})
893    driver.get(self.GetTestDataUrl() + '/test_page.html')
894    driver.execute_script('window.open("about:blank")')
895    driver.close()
896    self.assertRaises(WebDriverException, driver.close)
897
898  def testSwitchFromClosedWindow(self):
899    driver = self.GetNewDriver({'chrome.switches': ['disable-popup-blocking']})
900    driver.get(self.GetTestDataUrl() + '/test_page.html')
901    driver.execute_script('window.open("about:blank")')
902    old_window = driver.current_window_handle
903    driver.close()
904    driver.switch_to_window(driver.window_handles[0])
905    self.assertEquals('about:blank', driver.current_url)
906
907  def testSwitchToWindowWhileInSubframe(self):
908    driver = self.GetNewDriver({'chrome.switches': ['disable-popup-blocking']})
909    driver.get(self.GetTestDataUrl() + '/test_page.html')
910    driver.execute_script('window.open("about:blank")')
911    driver.switch_to_frame(0)
912    driver.switch_to_window(driver.window_handles[1])
913    self.assertEquals('about:blank', driver.current_url)
914
915  # Tests that the indexing is absolute and not based on index of frame in its
916  # parent element.
917  # See crbug.com/88685.
918  def testSwitchToFrameByIndex(self):
919    driver = self.GetNewDriver({'chrome.switches': ['disable-popup-blocking']})
920    driver.get(self.GetTestDataUrl() + '/switch_to_frame_by_index.html')
921    for i in range(3):
922      driver.switch_to_frame(i)
923      self.assertEquals(str(i), driver.current_url.split('?')[-1])
924      driver.switch_to_default_content()
925
926
927class AlertTest(ChromeDriverTest):
928
929  def testAlertOnLoadDoesNotHang(self):
930    driver = self.GetNewDriver()
931    self.assertRaises(WebDriverException, driver.get,
932                      self.GetTestDataUrl() + '/alert_on_load.html')
933    driver.switch_to_alert().accept()
934
935  def testAlertWhenTypingThrows(self):
936    driver = self.GetNewDriver()
937    driver.get(self.GetTestDataUrl() + '/alerts.html')
938    input_box = driver.find_element_by_name('onkeypress')
939    self.assertRaises(WebDriverException, input_box.send_keys, 'a')
940
941  def testAlertJustAfterTypingDoesNotThrow(self):
942    driver = self.GetNewDriver()
943    driver.get(self.GetTestDataUrl() + '/alerts.html')
944    driver.find_element_by_name('onkeyup').send_keys('a')
945    driver.switch_to_alert().accept()
946
947  def testAlertOnScriptDoesNotHang(self):
948    driver = self.GetNewDriver()
949    driver.get(self.GetTestDataUrl() + '/alerts.html')
950    self.assertRaises(WebDriverException, driver.execute_script, 'alert("ok")')
951
952  # See http://code.google.com/p/selenium/issues/detail?id=2671.
953  def testCanPerformJSBasedActionsThatCauseAlertsAtTheEnd(self):
954    driver = self.GetNewDriver()
955    driver.execute_script(
956        'var select = document.createElement("select");' +
957        'select.innerHTML = "<option>1</option><option>2</option>";' +
958        'select.addEventListener("change", function() { alert("hi"); });' +
959        'document.body.appendChild(select);')
960
961    # Shouldn't throw an exception, even though an alert appears mid-script.
962    driver.find_elements_by_tag_name('option')[-1].click()
963
964  def testMustHandleAlertFirst(self):
965    driver = self.GetNewDriver()
966    driver.get(self.GetTestDataUrl() + '/alerts.html')
967    input_box = driver.find_element_by_name('normal')
968    driver.execute_async_script('arguments[0](); window.alert("ok")')
969
970    self.assertRaises(WebDriverException, driver.execute_script, 'a = 1')
971
972    self.assertRaises(WebDriverException, input_box.send_keys, 'abc')
973
974    self.assertRaises(WebDriverException, driver.get,
975                      self.GetTestDataUrl() + '/test_page.html')
976
977    self.assertRaises(WebDriverException, driver.refresh)
978    self.assertRaises(WebDriverException, driver.back)
979    self.assertRaises(WebDriverException, driver.forward)
980    self.assertRaises(WebDriverException, driver.get_screenshot_as_base64)
981
982  def testCanHandleAlertInSubframe(self):
983    driver = self.GetNewDriver()
984    driver.get(self.GetTestDataUrl() + '/alerts.html')
985    driver.switch_to_frame('subframe')
986    driver.execute_async_script('arguments[0](); window.alert("ok")')
987    driver.switch_to_alert().accept()
988
989
990class WindowTest(ChromeDriverTest):
991  """Tests for WebDriver window commands."""
992
993  def setUp(self):
994    super(WindowTest, self).setUp()
995    self._driver = self.GetNewDriver()
996
997  def testSize(self):
998    size = self._driver.get_window_size()
999    self._driver.set_window_size(size['width'], size['height'])
1000    self.assertEquals(size, self._driver.get_window_size())
1001    self._driver.set_window_size(800, 600)
1002    self.assertEquals(800, self._driver.get_window_size()['width'])
1003    self.assertEquals(600, self._driver.get_window_size()['height'])
1004
1005  def testPosition(self):
1006    pos = self._driver.get_window_position()
1007    self._driver.set_window_position(pos['x'], pos['y'])
1008    self.assertEquals(pos, self._driver.get_window_position())
1009    self._driver.set_window_position(100, 200)
1010    self.assertEquals(100, self._driver.get_window_position()['x'])
1011    self.assertEquals(200, self._driver.get_window_position()['y'])
1012
1013  # Systems without window manager (Xvfb, Xvnc) do not implement maximization.
1014  @SkipIf(util.IsLinux())
1015  def testMaximize(self):
1016    old_size = self._driver.get_window_size()
1017    self._driver.maximize_window()
1018    new_size = self._driver.get_window_size()
1019    self.assertTrue(old_size['width'] <= new_size['width'])
1020    self.assertTrue(old_size['height'] <= new_size['height'])
1021
1022  def testWindowHandle(self):
1023    """Test specifying window handle."""
1024    self._driver.execute_script(
1025        'window.open("about:blank", "name", "height=200, width=200")')
1026    windows = self._driver.window_handles
1027    self.assertEquals(2, len(windows))
1028    self._driver.set_window_size(400, 300, windows[1])
1029    self.assertEquals(400, self._driver.get_window_size(windows[1])['width'])
1030    self.assertEquals(300, self._driver.get_window_size(windows[1])['height'])
1031    self.assertNotEquals(self._driver.get_window_size(windows[1]),
1032                         self._driver.get_window_size(windows[0]))
1033
1034  def testInvalidWindowHandle(self):
1035    """Tests specifying invalid handle."""
1036    invalid_handle = 'f1-120'
1037    self.assertRaises(WebDriverException, self._driver.set_window_size,
1038                      400, 300, invalid_handle)
1039    self.assertRaises(NoSuchWindowException, self._driver.get_window_size,
1040                      invalid_handle)
1041    self.assertRaises(NoSuchWindowException, self._driver.set_window_position,
1042                      1, 1, invalid_handle)
1043    self.assertRaises(NoSuchWindowException, self._driver.get_window_position,
1044                      invalid_handle)
1045
1046
1047class GeolocationTest(ChromeDriverTest):
1048  """Tests for WebDriver geolocation commands."""
1049
1050  def testGeolocation(self):
1051    """Tests the get and set geolocation commands."""
1052    driver = self.GetNewDriver()
1053    driver.get(self.GetTestDataUrl() + '/empty.html')
1054
1055    # TODO(kkania): Update the python bindings and get rid of these.
1056    driver.command_executor._commands.update({
1057        'getLoc': ('GET', '/session/$sessionId/location'),
1058        'setLoc': ('POST', '/session/$sessionId/location')
1059    })
1060    def getLocation():
1061      return driver.execute('getLoc')['value']
1062    def setLocation(location):
1063      driver.execute('setLoc', {'location': location})
1064    expected_location = {'latitude': 50, 'longitude': 50, 'altitude': 300}
1065    setLocation(expected_location)
1066    location = getLocation()
1067    self.assertEquals(expected_location, location)
1068
1069    driver.set_script_timeout(10)
1070    result = driver.execute_async_script("""
1071       var callback = arguments[0];
1072       window.navigator.geolocation.getCurrentPosition(
1073           function success(result) { callback(result.coords); },
1074           function fail(error) { callback(error.message); });""")
1075    self.assertEquals(expected_location['latitude'], result['latitude'])
1076    self.assertEquals(expected_location['longitude'], result['longitude'])
1077    self.assertEquals(expected_location['altitude'], result['altitude'])
1078
1079
1080class ExtensionTest(ChromeDriverTest):
1081
1082  INFOBAR_BROWSER_ACTION_EXTENSION = test_paths.TEST_DATA_PATH + \
1083      '/infobar_browser_action_extension'
1084  PAGE_ACTION_EXTENSION = test_paths.TEST_DATA_PATH + \
1085      '/page_action_extension'
1086  APP_SHELL = test_paths.TEST_DATA_PATH + \
1087      '/app_shell_extension'
1088
1089  def testExtensionInstallAndUninstall(self):
1090    driver = self.GetNewDriver()
1091    self.assertEquals(0, len(driver.get_installed_extensions()))
1092    ext = driver.install_extension(self.PAGE_ACTION_EXTENSION)
1093    extensions = driver.get_installed_extensions()
1094    self.assertEquals(1, len(extensions))
1095    self.assertEquals(ext.id, extensions[0].id)
1096    ext.uninstall()
1097    self.assertEquals(0, len(driver.get_installed_extensions()))
1098
1099  def testExtensionInfo(self):
1100    driver = self.GetNewDriver()
1101    ext = driver.install_extension(self.PAGE_ACTION_EXTENSION)
1102    self.assertEquals('Page action extension', ext.get_name())
1103    self.assertEquals('1.0', ext.get_version())
1104    self.assertEquals(32, len(ext.id))
1105    self.assertTrue(ext.is_enabled())
1106    ext.set_enabled(True)
1107    ext.set_enabled(False)
1108    self.assertFalse(ext.is_enabled())
1109    ext.set_enabled(True)
1110    self.assertTrue(ext.is_enabled())
1111
1112  def _testExtensionView(self, driver, view_handle, extension):
1113    """Tests that the given view supports basic WebDriver functionality."""
1114    driver.switch_to_window(view_handle)
1115    self.assertTrue(driver.execute_script('return true'))
1116    checkbox = driver.find_element_by_id('checkbox')
1117    checkbox.click()
1118    self.assertTrue(checkbox.is_selected())
1119    textfield = driver.find_element_by_id('textfield')
1120    textfield.send_keys('test')
1121    self.assertEquals('test', textfield.get_attribute('value'))
1122    self.assertEquals('test', driver.title)
1123    self.assertTrue(driver.current_url.endswith('view_checks.html'))
1124    self.assertTrue('Should be in page source' in driver.page_source)
1125    driver.close()
1126    def is_view_closed(driver):
1127      return len(filter(lambda view: view['handle'] == view_handle,
1128                        extension._get_views())) == 0
1129    WebDriverWait(driver, 10).until(is_view_closed)
1130
1131  # Mac extension infobars are currently broken: crbug.com/107573.
1132  @SkipIf(util.IsMac())
1133  def testInfobarView(self):
1134    driver = self.GetNewDriver({'chrome.switches':
1135                                ['enable-experimental-extension-apis']})
1136    ext = driver.install_extension(self.INFOBAR_BROWSER_ACTION_EXTENSION)
1137    driver.switch_to_window(ext.get_bg_page_handle())
1138    driver.set_script_timeout(10)
1139    driver.execute_async_script('waitForInfobar(arguments[0])')
1140    self._testExtensionView(driver, ext.get_infobar_handles()[0], ext)
1141
1142  def testBrowserActionPopupView(self):
1143    driver = self.GetNewDriver({'chrome.switches':
1144                                ['enable-experimental-extension-apis']})
1145    ext = driver.install_extension(self.INFOBAR_BROWSER_ACTION_EXTENSION)
1146    ext.click_browser_action()
1147    self._testExtensionView(driver, ext.get_popup_handle(), ext)
1148
1149  def testPageActionPopupView(self):
1150    driver = self.GetNewDriver()
1151    ext = driver.install_extension(self.PAGE_ACTION_EXTENSION)
1152    def is_page_action_visible(driver):
1153      return ext.is_page_action_visible()
1154    WebDriverWait(driver, 10).until(is_page_action_visible)
1155    ext.click_page_action()
1156    self._testExtensionView(driver, ext.get_popup_handle(), ext)
1157
1158  def testAppShellView(self):
1159    driver = self.GetNewDriver({'chrome.switches':
1160                                ['enable-experimental-extension-apis']})
1161    ext = driver.install_extension(self.APP_SHELL)
1162
1163    # Navigates to the new tab page to launch the app.
1164    driver.get('chrome:newtab')
1165    app = driver.find_element_by_xpath("//div[@title='App Shell']")
1166    app.click()
1167    def is_app_window_launched(driver):
1168      return ext.get_app_shell_handle() is not None
1169    WebDriverWait(driver, 10).until(is_app_window_launched)
1170    self._testExtensionView(driver, ext.get_app_shell_handle(), ext)
1171
1172
1173class BadJSTest(ChromeDriverTest):
1174  """Tests that ensure sites with hacky JS don't break ChromeDriver."""
1175
1176  def testFindElementDoesNotUseNativeFuncs(self):
1177    driver = self.GetNewDriver()
1178    driver.get(self.GetTestDataUrl() + '/bad_native_funcs.html')
1179    # This will throw an exception if any native funcs are used.
1180    driver.find_element_by_tag_name('body').find_elements_by_tag_name('div')
1181
1182
1183class ContentSettingsTest(ChromeDriverTest):
1184  """Tests that various types of content are allowed by default."""
1185
1186  def testPopups(self):
1187    driver = self.GetNewDriver()
1188    driver.get(self.GetTestDataUrl() + '/empty.html')
1189    driver.execute_script('window.open("about:blank")')
1190    self.assertEquals(2, len(driver.window_handles))
1191
1192  # Failing on win7: crbug.com/141231.
1193  @SkipIf(util.IsWin())
1194  def testPopupsCanBeResized(self):
1195    """Regression test for chromedriver issue 126."""
1196    driver = self.GetNewDriver()
1197    driver.get(self.GetTestDataUrl() + '/empty.html')
1198    driver.execute_script(
1199        'window.open("empty.html", "popup", "width=500,height=500")')
1200    driver.switch_to_window(driver.window_handles[1])
1201    size = driver.get_window_size()
1202    bigger_size = dict(map(lambda x: (x, size[x] + 100), size))
1203    smaller_size = dict(map(lambda x: (x, size[x] - 100), size))
1204    driver.set_window_size(bigger_size['width'], bigger_size['height'])
1205    self.assertEquals(bigger_size, driver.get_window_size())
1206    driver.set_window_size(smaller_size['width'], smaller_size['height'])
1207    self.assertEquals(smaller_size, driver.get_window_size())
1208
1209  def testGeolocation(self):
1210    driver = self.GetNewDriver()
1211    driver.get(self.GetTestDataUrl() + '/empty.html')
1212    driver.set_script_timeout(10)
1213    # Will timeout if infobar appears.
1214    driver.execute_async_script(
1215        'navigator.geolocation.getCurrentPosition(arguments[0], arguments[0]);')
1216
1217  def testMediaStream(self):
1218    driver = self.GetNewDriver()
1219    # Allowing camera/mic access by default only works for https sites.
1220    driver.get(self.GetHttpsTestDataUrl() + '/empty.html')
1221    driver.set_script_timeout(10)
1222    # Will timeout if infobar appears.
1223    driver.execute_async_script(
1224        'navigator.webkitGetUserMedia({audio:true, video:true},' +
1225        '                             arguments[0], arguments[0]);')
1226