OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 | |
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 | |
7 """Tests for ChromeDriver. | |
8 | |
9 If your test is testing a specific part of the WebDriver API, consider adding | |
10 it to the appropriate place in the WebDriver tree instead. | |
11 """ | |
12 | |
13 import hashlib | |
14 import os | |
15 import platform | |
16 import sys | |
17 import tempfile | |
18 import unittest | |
19 import urllib | |
20 import urllib2 | |
21 import urlparse | |
22 | |
23 from chromedriver_launcher import ChromeDriverLauncher | |
24 import chromedriver_paths | |
25 from gtest_text_test_runner import GTestTextTestRunner | |
26 | |
27 sys.path += [chromedriver_paths.SRC_THIRD_PARTY] | |
28 sys.path += [chromedriver_paths.PYTHON_BINDINGS] | |
29 | |
30 try: | |
31 import simplejson as json | |
32 except ImportError: | |
33 import json | |
34 | |
35 from selenium.common.exceptions import WebDriverException | |
36 from selenium.webdriver.remote.command import Command | |
37 from selenium.webdriver.remote.webdriver import WebDriver | |
38 from selenium.webdriver.common.keys import Keys | |
39 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities | |
40 | |
41 | |
42 def DataDir(): | |
43 """Returns the path to the data dir chrome/test/data.""" | |
44 return os.path.normpath( | |
45 os.path.join(os.path.dirname(__file__), os.pardir, "data")) | |
46 | |
47 | |
48 def GetFileURLForPath(path): | |
49 """Get file:// url for the given path. | |
50 Also quotes the url using urllib.quote(). | |
51 """ | |
52 abs_path = os.path.abspath(path) | |
53 if sys.platform == 'win32': | |
54 # Don't quote the ':' in drive letter ( say, C: ) on win. | |
55 # Also, replace '\' with '/' as expected in a file:/// url. | |
56 drive, rest = os.path.splitdrive(abs_path) | |
57 quoted_path = drive.upper() + urllib.quote((rest.replace('\\', '/'))) | |
58 return 'file:///' + quoted_path | |
59 else: | |
60 quoted_path = urllib.quote(abs_path) | |
61 return 'file://' + quoted_path | |
62 | |
63 | |
64 def IsWindows(): | |
65 return sys.platform == 'cygwin' or sys.platform.startswith('win') | |
66 | |
67 | |
68 def IsLinux(): | |
69 return sys.platform.startswith('linux') | |
70 | |
71 | |
72 def IsMac(): | |
73 return sys.platform.startswith('darwin') | |
74 | |
75 | |
76 class Request(urllib2.Request): | |
77 """Extends urllib2.Request to support all HTTP request types.""" | |
78 | |
79 def __init__(self, url, method=None, data=None): | |
80 """Initialise a new HTTP request. | |
81 | |
82 Arguments: | |
83 url: The full URL to send the request to. | |
84 method: The HTTP request method to use; defaults to 'GET'. | |
85 data: The data to send with the request as a string. Defaults to | |
86 None and is ignored if |method| is not 'POST' or 'PUT'. | |
87 """ | |
88 if method is None: | |
89 method = data is not None and 'POST' or 'GET' | |
90 elif method not in ('POST', 'PUT'): | |
91 data = None | |
92 self.method = method | |
93 urllib2.Request.__init__(self, url, data=data) | |
94 | |
95 def get_method(self): | |
96 """Returns the HTTP method used by this request.""" | |
97 return self.method | |
98 | |
99 | |
100 def SendRequest(url, method=None, data=None): | |
101 """Sends a HTTP request to the WebDriver server. | |
102 | |
103 Return values and exceptions raised are the same as those of | |
104 |urllib2.urlopen|. | |
105 | |
106 Arguments: | |
107 url: The full URL to send the request to. | |
108 method: The HTTP request method to use; defaults to 'GET'. | |
109 data: The data to send with the request as a string. Defaults to | |
110 None and is ignored if |method| is not 'POST' or 'PUT'. | |
111 | |
112 Returns: | |
113 A file-like object. | |
114 """ | |
115 request = Request(url, method=method, data=data) | |
116 request.add_header('Accept', 'application/json') | |
117 opener = urllib2.build_opener(urllib2.HTTPRedirectHandler()) | |
118 return opener.open(request) | |
119 | |
120 | |
121 class BasicTest(unittest.TestCase): | |
122 """Basic ChromeDriver tests.""" | |
123 | |
124 def setUp(self): | |
125 self._launcher = ChromeDriverLauncher() | |
126 | |
127 def tearDown(self): | |
128 self._launcher.Kill() | |
129 | |
130 def testShouldReturn403WhenSentAnUnknownCommandURL(self): | |
131 request_url = self._launcher.GetURL() + '/foo' | |
132 try: | |
133 SendRequest(request_url, method='GET') | |
134 self.fail('Should have raised a urllib.HTTPError for returned 403') | |
135 except urllib2.HTTPError, expected: | |
136 self.assertEquals(403, expected.code) | |
137 | |
138 def testShouldReturnHTTP405WhenSendingANonPostToTheSessionURL(self): | |
139 request_url = self._launcher.GetURL() + '/session' | |
140 try: | |
141 SendRequest(request_url, method='GET') | |
142 self.fail('Should have raised a urllib.HTTPError for returned 405') | |
143 except urllib2.HTTPError, expected: | |
144 self.assertEquals(405, expected.code) | |
145 self.assertEquals('POST', expected.hdrs['Allow']) | |
146 | |
147 def testShouldGetA404WhenAttemptingToDeleteAnUnknownSession(self): | |
148 request_url = self._launcher.GetURL() + '/session/unkown_session_id' | |
149 try: | |
150 SendRequest(request_url, method='DELETE') | |
151 self.fail('Should have raised a urllib.HTTPError for returned 404') | |
152 except urllib2.HTTPError, expected: | |
153 self.assertEquals(404, expected.code) | |
154 | |
155 def testShouldReturn204ForFaviconRequests(self): | |
156 request_url = self._launcher.GetURL() + '/favicon.ico' | |
157 # In python2.5, a 204 status code causes an exception. | |
158 if sys.version_info[0:2] == (2, 5): | |
159 try: | |
160 SendRequest(request_url, method='GET') | |
161 self.fail('Should have raised a urllib.HTTPError for returned 204') | |
162 except urllib2.HTTPError, expected: | |
163 self.assertEquals(204, expected.code) | |
164 else: | |
165 response = SendRequest(request_url, method='GET') | |
166 try: | |
167 self.assertEquals(204, response.code) | |
168 finally: | |
169 response.close() | |
170 | |
171 def testCanStartChromeDriverOnSpecificPort(self): | |
172 launcher = ChromeDriverLauncher(port=9520) | |
173 self.assertEquals(9520, launcher.GetPort()) | |
174 driver = WebDriver(launcher.GetURL(), DesiredCapabilities.CHROME) | |
175 driver.quit() | |
176 launcher.Kill() | |
177 | |
178 | |
179 class WebserverTest(unittest.TestCase): | |
180 """Tests the built-in ChromeDriver webserver.""" | |
181 | |
182 def testShouldNotServeFilesByDefault(self): | |
183 launcher = ChromeDriverLauncher() | |
184 try: | |
185 SendRequest(launcher.GetURL(), method='GET') | |
186 self.fail('Should have raised a urllib.HTTPError for returned 403') | |
187 except urllib2.HTTPError, expected: | |
188 self.assertEquals(403, expected.code) | |
189 finally: | |
190 launcher.Kill() | |
191 | |
192 def testCanServeFiles(self): | |
193 launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
194 request_url = launcher.GetURL() + '/' + os.path.basename(__file__) | |
195 SendRequest(request_url, method='GET') | |
196 launcher.Kill() | |
197 | |
198 | |
199 class NativeInputTest(unittest.TestCase): | |
200 """Native input ChromeDriver tests.""" | |
201 | |
202 def setUp(self): | |
203 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
204 self._capabilities = DesiredCapabilities.CHROME | |
205 self._capabilities['chrome.nativeEvents'] = True | |
206 | |
207 def tearDown(self): | |
208 self._launcher.Kill() | |
209 | |
210 def testCanStartWithNativeEvents(self): | |
211 driver = WebDriver(self._launcher.GetURL(), self._capabilities) | |
212 self.assertTrue(driver.capabilities.has_key('chrome.nativeEvents')) | |
213 self.assertTrue(driver.capabilities['chrome.nativeEvents']) | |
214 | |
215 # Flaky on windows. See crbug.com/80295. | |
216 def DISABLED_testSendKeysNative(self): | |
217 driver = WebDriver(self._launcher.GetURL(), self._capabilities) | |
218 driver.get(self._launcher.GetURL() + '/test_page.html') | |
219 # Find the text input. | |
220 q = driver.find_element_by_name('key_input_test') | |
221 # Send some keys. | |
222 q.send_keys('tokyo') | |
223 self.assertEqual(q.text, 'tokyo') | |
224 | |
225 # Needs to run on a machine with an IME installed. | |
226 def DISABLED_testSendKeysNativeProcessedByIME(self): | |
227 driver = WebDriver(self._launcher.GetURL(), self.capabilities) | |
228 driver.get(self._launcher.GetURL() + '/test_page.html') | |
229 q = driver.find_element_by_name('key_input_test') | |
230 # Send key combination to turn IME on. | |
231 q.send_keys(Keys.F7) | |
232 q.send_keys('toukyou') | |
233 # Now turning it off. | |
234 q.send_keys(Keys.F7) | |
235 self.assertEqual(q.value, "\xe6\x9d\xb1\xe4\xba\xac") | |
236 | |
237 | |
238 class DesiredCapabilitiesTest(unittest.TestCase): | |
239 | |
240 def setUp(self): | |
241 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
242 | |
243 def tearDown(self): | |
244 self._launcher.Kill() | |
245 | |
246 def testCustomSwitches(self): | |
247 switches = ['enable-file-cookie', 'homepage=about:memory'] | |
248 capabilities = {'chrome.switches': switches} | |
249 | |
250 driver = WebDriver(self._launcher.GetURL(), capabilities) | |
251 url = driver.current_url | |
252 self.assertTrue('memory' in url, | |
253 'URL does not contain with "memory":' + url) | |
254 driver.get('about:version') | |
255 self.assertNotEqual(-1, driver.page_source.find('enable-file-cookie')) | |
256 | |
257 def testBinary(self): | |
258 binary_path = ChromeDriverLauncher.LocateExe() | |
259 self.assertNotEquals(None, binary_path) | |
260 if IsWindows(): | |
261 chrome_name = 'chrome.exe' | |
262 elif IsMac(): | |
263 chrome_name = 'Google Chrome.app/Contents/MacOS/Google Chrome' | |
264 if not os.path.exists(os.path.join(binary_path, chrome_name)): | |
265 chrome_name = 'Chromium.app/Contents/MacOS/Chromium' | |
266 elif IsLinux(): | |
267 chrome_name = 'chrome' | |
268 else: | |
269 self.fail('Unrecognized platform: ' + sys.platform) | |
270 binary_path = os.path.join(os.path.dirname(binary_path), chrome_name) | |
271 self.assertTrue(os.path.exists(binary_path), | |
272 'Binary not found: ' + binary_path) | |
273 capabilities = {'chrome.binary': binary_path} | |
274 | |
275 driver = WebDriver(self._launcher.GetURL(), capabilities) | |
276 | |
277 | |
278 class CookieTest(unittest.TestCase): | |
279 """Cookie test for the json webdriver protocol""" | |
280 | |
281 def setUp(self): | |
282 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
283 self._driver = WebDriver(self._launcher.GetURL(), | |
284 DesiredCapabilities.CHROME) | |
285 | |
286 def tearDown(self): | |
287 self._driver.quit() | |
288 self._launcher.Kill() | |
289 | |
290 def testAddCookie(self): | |
291 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
292 cookie_dict = None | |
293 cookie_dict = self._driver.get_cookie("chromedriver_cookie_test") | |
294 cookie_dict = {} | |
295 cookie_dict["name"] = "chromedriver_cookie_test" | |
296 cookie_dict["value"] = "this is a test" | |
297 self._driver.add_cookie(cookie_dict) | |
298 cookie_dict = self._driver.get_cookie("chromedriver_cookie_test") | |
299 self.assertNotEqual(cookie_dict, None) | |
300 self.assertEqual(cookie_dict["value"], "this is a test") | |
301 | |
302 def testDeleteCookie(self): | |
303 self.testAddCookie(); | |
304 self._driver.delete_cookie("chromedriver_cookie_test") | |
305 cookie_dict = self._driver.get_cookie("chromedriver_cookie_test") | |
306 self.assertEqual(cookie_dict, None) | |
307 | |
308 | |
309 class ScreenshotTest(unittest.TestCase): | |
310 """Tests to verify screenshot retrieval""" | |
311 | |
312 REDBOX = "automation_proxy_snapshot/set_size.html" | |
313 | |
314 def setUp(self): | |
315 self._launcher = ChromeDriverLauncher() | |
316 self._driver = WebDriver(self._launcher.GetURL(), {}) | |
317 | |
318 def tearDown(self): | |
319 self._driver.quit() | |
320 self._launcher.Kill() | |
321 | |
322 def testScreenCaptureAgainstReference(self): | |
323 # Create a red square of 2000x2000 pixels. | |
324 url = GetFileURLForPath(os.path.join(DataDir(), | |
325 self.REDBOX)) | |
326 url += "?2000,2000" | |
327 self._driver.get(url) | |
328 s = self._driver.get_screenshot_as_base64(); | |
329 self._driver.get_screenshot_as_file("/tmp/foo.png") | |
330 h = hashlib.md5(s).hexdigest() | |
331 # Compare the PNG created to the reference hash. | |
332 self.assertEquals(h, '12c0ade27e3875da3d8866f52d2fa84f') | |
333 | |
334 | |
335 class SessionTest(unittest.TestCase): | |
336 """Tests dealing with WebDriver sessions.""" | |
337 | |
338 def setUp(self): | |
339 self._launcher = ChromeDriverLauncher() | |
340 | |
341 def tearDown(self): | |
342 self._launcher.Kill() | |
343 | |
344 def testCreatingSessionShouldRedirectToCorrectURL(self): | |
345 request_url = self._launcher.GetURL() + '/session' | |
346 response = SendRequest(request_url, method='POST', | |
347 data='{"desiredCapabilities": {}}') | |
348 self.assertEquals(200, response.code) | |
349 self.session_url = response.geturl() # TODO(jleyba): verify this URL? | |
350 | |
351 data = json.loads(response.read()) | |
352 self.assertTrue(isinstance(data, dict)) | |
353 self.assertEquals(0, data['status']) | |
354 | |
355 url_parts = urlparse.urlparse(self.session_url)[2].split('/') | |
356 self.assertEquals(3, len(url_parts)) | |
357 self.assertEquals('', url_parts[0]) | |
358 self.assertEquals('session', url_parts[1]) | |
359 self.assertEquals(data['sessionId'], url_parts[2]) | |
360 | |
361 def testShouldBeGivenCapabilitiesWhenStartingASession(self): | |
362 driver = WebDriver(self._launcher.GetURL(), {}) | |
363 capabilities = driver.capabilities | |
364 | |
365 self.assertEquals('chrome', capabilities['browserName']) | |
366 self.assertTrue(capabilities['javascriptEnabled']) | |
367 self.assertTrue(capabilities['takesScreenshot']) | |
368 self.assertTrue(capabilities['cssSelectorsEnabled']) | |
369 | |
370 # Value depends on what version the server is starting. | |
371 self.assertTrue('version' in capabilities) | |
372 self.assertTrue( | |
373 isinstance(capabilities['version'], unicode), | |
374 'Expected a %s, but was %s' % (unicode, | |
375 type(capabilities['version']))) | |
376 | |
377 system = platform.system() | |
378 if system == 'Linux': | |
379 self.assertEquals('linux', capabilities['platform'].lower()) | |
380 elif system == 'Windows': | |
381 self.assertEquals('windows', capabilities['platform'].lower()) | |
382 elif system == 'Darwin': | |
383 self.assertEquals('mac', capabilities['platform'].lower()) | |
384 else: | |
385 # No python on ChromeOS, so we won't have a platform value, but | |
386 # the server will know and return the value accordingly. | |
387 self.assertEquals('chromeos', capabilities['platform'].lower()) | |
388 driver.quit() | |
389 | |
390 def testSessionCreationDeletion(self): | |
391 driver = WebDriver(self._launcher.GetURL(), DesiredCapabilities.CHROME) | |
392 driver.quit() | |
393 | |
394 def testMultipleSessionCreationDeletion(self): | |
395 for i in range(10): | |
396 driver = WebDriver(self._launcher.GetURL(), DesiredCapabilities.CHROME) | |
397 driver.quit() | |
398 | |
399 def testSessionCommandsAfterSessionDeletionReturn404(self): | |
400 driver = WebDriver(self._launcher.GetURL(), DesiredCapabilities.CHROME) | |
401 session_id = driver.session_id | |
402 driver.quit() | |
403 try: | |
404 response = SendRequest(self._launcher.GetURL() + '/session/' + session_id, | |
405 method='GET') | |
406 self.fail('Should have thrown 404 exception') | |
407 except urllib2.HTTPError, expected: | |
408 self.assertEquals(404, expected.code) | |
409 | |
410 def testMultipleConcurrentSessions(self): | |
411 drivers = [] | |
412 for i in range(10): | |
413 drivers += [WebDriver(self._launcher.GetURL(), | |
414 DesiredCapabilities.CHROME)] | |
415 for driver in drivers: | |
416 driver.quit() | |
417 | |
418 | |
419 class MouseTest(unittest.TestCase): | |
420 """Mouse command tests for the json webdriver protocol""" | |
421 | |
422 def setUp(self): | |
423 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
424 self._driver = WebDriver(self._launcher.GetURL(), | |
425 DesiredCapabilities.CHROME) | |
426 | |
427 def tearDown(self): | |
428 self._driver.quit() | |
429 self._launcher.Kill() | |
430 | |
431 def testClickElementThatNeedsContainerScrolling(self): | |
432 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
433 self._driver.find_element_by_name('hidden_scroll').click() | |
434 self.assertTrue(self._driver.execute_script('return window.success')) | |
435 | |
436 def testClickElementThatNeedsIframeScrolling(self): | |
437 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
438 self._driver.switch_to_frame('iframe') | |
439 self._driver.find_element_by_name('hidden_scroll').click() | |
440 self.assertTrue(self._driver.execute_script('return window.success')) | |
441 | |
442 def testClickElementThatNeedsPageScrolling(self): | |
443 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
444 self._driver.find_element_by_name('far_away').click() | |
445 self.assertTrue(self._driver.execute_script('return window.success')) | |
446 | |
447 # TODO(kkania): Move this test to the webdriver repo. | |
448 def testClickDoesSelectOption(self): | |
449 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
450 option = self._driver.find_element_by_name('option') | |
451 self.assertFalse(option.is_selected()) | |
452 option.click() | |
453 self.assertTrue(option.is_selected()) | |
454 | |
455 def testClickDoesUseFirstClientRect(self): | |
456 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
457 self._driver.find_element_by_name('wrapped').click() | |
458 self.assertTrue(self._driver.execute_script('return window.success')) | |
459 | |
460 | |
461 class TypingTest(unittest.TestCase): | |
462 | |
463 def setUp(self): | |
464 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
465 self._driver = WebDriver(self._launcher.GetURL(), {}) | |
466 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
467 | |
468 def tearDown(self): | |
469 self._driver.quit() | |
470 self._launcher.Kill() | |
471 | |
472 # See http://crbug.com/85243. | |
473 def testCanSendKeysToDescendantOfEditingHost(self): | |
474 self._driver.find_element_by_name('editable_child').send_keys('moo') | |
475 text = self._driver.find_element_by_name('editable').text | |
476 self.assertEquals('mooeditable', text) | |
477 | |
478 | |
479 class UrlBaseTest(unittest.TestCase): | |
480 """Tests that the server can be configured for a different URL base.""" | |
481 | |
482 def setUp(self): | |
483 self._launcher = ChromeDriverLauncher(url_base='/wd/hub') | |
484 | |
485 def tearDown(self): | |
486 self._launcher.Kill() | |
487 | |
488 def testCreatingSessionShouldRedirectToCorrectURL(self): | |
489 request_url = self._launcher.GetURL() + '/session' | |
490 response = SendRequest(request_url, method='POST', | |
491 data='{"desiredCapabilities":{}}') | |
492 self.assertEquals(200, response.code) | |
493 self.session_url = response.geturl() # TODO(jleyba): verify this URL? | |
494 | |
495 data = json.loads(response.read()) | |
496 self.assertTrue(isinstance(data, dict)) | |
497 self.assertEquals(0, data['status']) | |
498 | |
499 url_parts = urlparse.urlparse(self.session_url)[2].split('/') | |
500 self.assertEquals(5, len(url_parts)) | |
501 self.assertEquals('', url_parts[0]) | |
502 self.assertEquals('wd', url_parts[1]) | |
503 self.assertEquals('hub', url_parts[2]) | |
504 self.assertEquals('session', url_parts[3]) | |
505 self.assertEquals(data['sessionId'], url_parts[4]) | |
506 | |
507 | |
508 # TODO(jleyba): Port this to WebDriver's own python test suite. | |
509 class ElementEqualityTest(unittest.TestCase): | |
510 """Tests that the server properly checks element equality.""" | |
511 | |
512 def setUp(self): | |
513 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
514 self._driver = WebDriver(self._launcher.GetURL(), {}) | |
515 | |
516 def tearDown(self): | |
517 self._driver.quit() | |
518 self._launcher.Kill() | |
519 | |
520 def testElementEquality(self): | |
521 self._driver.get(self._launcher.GetURL() + '/test_page.html') | |
522 body1 = self._driver.find_element_by_tag_name('body') | |
523 body2 = self._driver.execute_script('return document.body') | |
524 | |
525 # TODO(jleyba): WebDriver's python bindings should expose a proper API | |
526 # for this. | |
527 result = body1._execute(Command.ELEMENT_EQUALS, { | |
528 'other': body2.id | |
529 }) | |
530 self.assertTrue(result['value']) | |
531 | |
532 | |
533 class LoggingTest(unittest.TestCase): | |
534 | |
535 def setUp(self): | |
536 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
537 | |
538 def tearDown(self): | |
539 self._launcher.Kill() | |
540 | |
541 def testNoVerboseLogging(self): | |
542 self._driver = WebDriver(self._launcher.GetURL(), {}) | |
543 self._driver.execute_script('console.log("HI")') | |
544 request_url = self._launcher.GetURL() + '/log' | |
545 req = SendRequest(request_url, method='GET') | |
546 log = req.read() | |
547 self.assertTrue(':INFO:' not in log, ':INFO: in log: ' + log) | |
548 | |
549 def testVerboseLogging(self): | |
550 self._driver = WebDriver(self._launcher.GetURL(), {'chrome.verbose': True}) | |
551 self._driver.execute_script('console.log("HI")') | |
552 request_url = self._launcher.GetURL() + '/log' | |
553 req = SendRequest(request_url, method='GET') | |
554 log = req.read() | |
555 self.assertTrue(':INFO:' in log, ':INFO: not in log: ' + log) | |
556 | |
557 | |
558 """Chrome functional test section. All implementation tests of ChromeDriver | |
559 should go above. | |
560 | |
561 TODO(dyu): Move these tests out of here when pyauto has these capabilities. | |
562 """ | |
563 | |
564 | |
565 def GetPathForDataFile(relative_path): | |
566 """Returns the path for a test data file residing in this directory.""" | |
567 return os.path.join(os.path.dirname(__file__), relative_path) | |
568 | |
569 | |
570 class AutofillTest(unittest.TestCase): | |
571 AUTOFILL_EDIT_ADDRESS = 'chrome://settings/autofillEditAddress' | |
572 AUTOFILL_EDIT_CC = 'chrome://settings/autofillEditCreditCard' | |
573 | |
574 def setUp(self): | |
575 self._launcher = ChromeDriverLauncher() | |
576 | |
577 def tearDown(self): | |
578 self._launcher.Kill() | |
579 | |
580 def NewDriver(self): | |
581 return WebDriver(self._launcher.GetURL(), {}) | |
582 | |
583 def _SelectOptionXpath(self, value): | |
584 """Returns an xpath query used to select an item from a dropdown list. | |
585 | |
586 Args: | |
587 value: Option selected for the drop-down list field. | |
588 """ | |
589 return '//option[@value="%s"]' % value | |
590 | |
591 def testPostalCodeAndStateLabelsBasedOnCountry(self): | |
592 """Verify postal code and state labels based on selected country.""" | |
593 import simplejson | |
594 test_data = simplejson.loads( | |
595 open(GetPathForDataFile('state_zip_labels.txt')).read()) | |
596 | |
597 driver = self.NewDriver() | |
598 driver.get(self.AUTOFILL_EDIT_ADDRESS) | |
599 # Initial check of State and ZIP labels. | |
600 state_label = driver.find_element_by_id('state-label').text | |
601 self.assertEqual('State', state_label) | |
602 zip_label = driver.find_element_by_id('postal-code-label').text | |
603 self.assertEqual('ZIP code', zip_label) | |
604 | |
605 for country_code in test_data: | |
606 query = self._SelectOptionXpath(country_code) | |
607 driver.find_element_by_id('country').find_element_by_xpath(query).select() | |
608 # Compare postal labels. | |
609 actual_postal_label = driver.find_element_by_id( | |
610 'postal-code-label').text | |
611 expected_postal_label = test_data[country_code]['postalCodeLabel'] | |
612 self.assertEqual( | |
613 actual_postal_label, expected_postal_label, | |
614 'Postal code label does not match Country "%s"' % country_code) | |
615 # Compare state labels. | |
616 actual_state_label = driver.find_element_by_id('state-label').text | |
617 expected_state_label = test_data[country_code]['stateLabel'] | |
618 self.assertEqual( | |
619 actual_state_label, expected_state_label, | |
620 'State label does not match Country "%s"' % country_code) | |
621 | |
622 def testDisplayLineItemForEntriesWithNoCCNum(self): | |
623 """Verify Autofill creates a line item for CC entries with no CC number.""" | |
624 creditcard_data = {'CREDIT_CARD_NAME': 'Jane Doe', | |
625 'CREDIT_CARD_EXP_MONTH': '12', | |
626 'CREDIT_CARD_EXP_4_DIGIT_YEAR': '2014'} | |
627 | |
628 driver = self.NewDriver() | |
629 driver.get(self.AUTOFILL_EDIT_CC) | |
630 driver.find_element_by_id('name-on-card').send_keys( | |
631 creditcard_data['CREDIT_CARD_NAME']) | |
632 query_month = self._SelectOptionXpath( | |
633 creditcard_data['CREDIT_CARD_EXP_MONTH']) | |
634 query_year = self._SelectOptionXpath( | |
635 creditcard_data['CREDIT_CARD_EXP_4_DIGIT_YEAR']) | |
636 driver.find_element_by_id('expiration-month').find_element_by_xpath( | |
637 query_month).select() | |
638 driver.find_element_by_id('expiration-year').find_element_by_xpath( | |
639 query_year).select() | |
640 driver.find_element_by_id( | |
641 'autofill-edit-credit-card-apply-button').click() | |
642 # Refresh the page to ensure the UI is up-to-date. | |
643 driver.refresh() | |
644 list_entry = driver.find_element_by_class_name('autofill-list-item') | |
645 self.assertTrue(list_entry.is_displayed) | |
646 self.assertEqual(list_entry.text, | |
647 creditcard_data['CREDIT_CARD_NAME'], | |
648 'Saved CC line item not same as what was entered.') | |
649 | |
650 | |
651 class FileUploadControlTest(unittest.TestCase): | |
652 """Tests dealing with file upload control.""" | |
653 | |
654 def setUp(self): | |
655 self._launcher = ChromeDriverLauncher(root_path=os.path.dirname(__file__)) | |
656 self._driver = WebDriver(self._launcher.GetURL(), | |
657 DesiredCapabilities.CHROME) | |
658 | |
659 def tearDown(self): | |
660 self._driver.quit() | |
661 self._launcher.Kill() | |
662 | |
663 def testSetFilePathToFileUploadControl(self): | |
664 """Verify a file path is set to the file upload control.""" | |
665 self._driver.get(self._launcher.GetURL() + '/upload.html') | |
666 | |
667 file = tempfile.NamedTemporaryFile() | |
668 | |
669 fileupload_single = self._driver.find_element_by_name('fileupload_single') | |
670 multiple = fileupload_single.get_attribute('multiple') | |
671 self.assertEqual('false', multiple) | |
672 fileupload_single.send_keys(file.name) | |
673 path = fileupload_single.value | |
674 self.assertTrue(path.endswith(os.path.basename(file.name))) | |
675 | |
676 def testSetMultipleFilePathsToFileuploadControlWithoutMultipleWillFail(self): | |
677 """Verify setting file paths to the file upload control without 'multiple' | |
678 attribute will fail.""" | |
679 self._driver.get(self._launcher.GetURL() + '/upload.html') | |
680 | |
681 files = [] | |
682 filepaths = [] | |
683 for index in xrange(4): | |
684 file = tempfile.NamedTemporaryFile() | |
685 # We need to hold the file objects because the files will be deleted on | |
686 # GC. | |
687 files.append(file) | |
688 filepath = file.name | |
689 filepaths.append(filepath) | |
690 | |
691 fileupload_single = self._driver.find_element_by_name('fileupload_single') | |
692 multiple = fileupload_single.get_attribute('multiple') | |
693 self.assertEqual('false', multiple) | |
694 self.assertRaises(WebDriverException, fileupload_single.send_keys, | |
695 filepaths[0], filepaths[1], filepaths[2], filepaths[3]) | |
696 | |
697 def testSetMultipleFilePathsToFileUploadControl(self): | |
698 """Verify multiple file paths are set to the file upload control.""" | |
699 self._driver.get(self._launcher.GetURL() + '/upload.html') | |
700 | |
701 files = [] | |
702 filepaths = [] | |
703 filenames = set() | |
704 for index in xrange(4): | |
705 file = tempfile.NamedTemporaryFile() | |
706 files.append(file) | |
707 filepath = file.name | |
708 filepaths.append(filepath) | |
709 filenames.add(os.path.basename(filepath)) | |
710 | |
711 fileupload_multi = self._driver.find_element_by_name('fileupload_multi') | |
712 multiple = fileupload_multi.get_attribute('multiple') | |
713 self.assertEqual('true', multiple) | |
714 fileupload_multi.send_keys(filepaths[0], filepaths[1], filepaths[2], | |
715 filepaths[3]) | |
716 | |
717 files_on_element = self._driver.execute_script( | |
718 'return document.getElementById("fileupload_multi").files;') | |
719 self.assertTrue(files_on_element) | |
720 self.assertEqual(4, len(files_on_element)) | |
721 for f in files_on_element: | |
722 self.assertTrue(f['name'] in filenames) | |
723 | |
724 | |
725 if __name__ == '__main__': | |
726 unittest.main(module='chromedriver_tests', | |
727 testRunner=GTestTextTestRunner(verbosity=1)) | |
OLD | NEW |