| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/python | |
| 2 # Copyright (c) 2010 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. | |
| 5 | |
| 6 try: | |
| 7 import json | |
| 8 except ImportError: # < 2.6 | |
| 9 import simplejson as json | |
| 10 | |
| 11 import os | |
| 12 import optparse | |
| 13 import platform | |
| 14 import string | |
| 15 import subprocess | |
| 16 import sys | |
| 17 import time | |
| 18 import types | |
| 19 import unittest | |
| 20 import urllib2 | |
| 21 from selenium.common.exceptions import ErrorInResponseException | |
| 22 from selenium.common.exceptions import NoSuchElementException | |
| 23 from selenium.remote.webdriver import WebDriver | |
| 24 from selenium.remote.webdriver.webelement import WebElement | |
| 25 from urlparse import urlparse | |
| 26 | |
| 27 | |
| 28 if sys.version_info < (2,6): | |
| 29 # Subprocess.Popen.kill is not available prior to 2.6. | |
| 30 if platform.system() == 'Windows': | |
| 31 import win32api | |
| 32 else: | |
| 33 import signal | |
| 34 | |
| 35 | |
| 36 WEBDRIVER_EXE = os.path.abspath(os.path.join('.', 'chromedriver')) | |
| 37 if platform.system() == 'Windows': | |
| 38 WEBDRIVER_EXE = '%s.exe' % WEBDRIVER_EXE | |
| 39 WEBDRIVER_PORT = 8080 | |
| 40 WEBDRIVER_SERVER_URL = None | |
| 41 WEBDRIVER_PROCESS = None | |
| 42 | |
| 43 if not WEBDRIVER_SERVER_URL: | |
| 44 WEBDRIVER_SERVER_URL = 'http://localhost:%d' % WEBDRIVER_PORT | |
| 45 | |
| 46 class RemoteWebDriverTest(unittest.TestCase): | |
| 47 SEARCH = "http://www.google.com/webhp?hl=en" | |
| 48 NEWS = "http://www.google.com/news?hl=en" | |
| 49 | |
| 50 """Verifies that navigation to a specific page is correct by asserting on the | |
| 51 the reported URL. The function will not work with pages that redirect.""" | |
| 52 def navigate(self, url): | |
| 53 self.driver.get(url) | |
| 54 self.assertURL(url) | |
| 55 | |
| 56 def assertURL(self, url): | |
| 57 u = self.driver.get_current_url() | |
| 58 self.assertEqual(u, url) | |
| 59 | |
| 60 """A new instance of chrome driver is started for every test case""" | |
| 61 def setUp(self): | |
| 62 global WEBDRIVER_SERVER_URL | |
| 63 global WEBDRIVER_PROCESS | |
| 64 WEBDRIVER_PROCESS = subprocess.Popen([WEBDRIVER_EXE, | |
| 65 '--port=%d' % WEBDRIVER_PORT]) | |
| 66 if WEBDRIVER_PROCESS == None: | |
| 67 print "Chromium executable not found. The path used was: " | |
| 68 print WEBDRIVER_EXE | |
| 69 sys.exit(-1) | |
| 70 | |
| 71 time.sleep(5) | |
| 72 self.driver = WebDriver.WebDriver(WEBDRIVER_SERVER_URL, "chrome", "ANY") | |
| 73 self.assertTrue(self.driver) | |
| 74 | |
| 75 def tearDown(self): | |
| 76 global WEBDRIVER_PROCESS | |
| 77 self.driver.quit() | |
| 78 if WEBDRIVER_PROCESS: | |
| 79 if sys.version_info < (2,6): | |
| 80 # From http://stackoverflow.com/questions/1064335 | |
| 81 if platform.system() == 'Windows': | |
| 82 PROCESS_TERMINATE = 1 | |
| 83 handle = win32api.OpenProcess(PROCESS_TERMINATE, False, | |
| 84 WEBDRIVER_PROCESS.pid) | |
| 85 win32api.TerminateProcess(handle, -1) | |
| 86 win32api.CloseHandle(handle) | |
| 87 else: | |
| 88 os.kill(WEBDRIVER_PROCESS.pid, signal.SIGKILL) | |
| 89 else: | |
| 90 WEBDRIVER_PROCESS.kill() | |
| 91 WEBDRIVER_PROCESS = None | |
| 92 | |
| 93 """Preforms a string search ignoring case""" | |
| 94 def assertFind(self, text, search): | |
| 95 text = string.lower(text) | |
| 96 search = string.lower(search) | |
| 97 self.assertNotEqual(-1, string.find(text, search)) | |
| 98 | |
| 99 | |
| 100 class TestFindElement(RemoteWebDriverTest): | |
| 101 def testFindByName(self): | |
| 102 self.navigate(SEARCH) | |
| 103 # Find the Google search button. | |
| 104 q = self.driver.find_element_by_name("q") | |
| 105 self.assertTrue(isinstance(q, WebElement)) | |
| 106 # Trying looking for an element not on the page. | |
| 107 self.assertRaises(NoSuchElementException, | |
| 108 self.driver.find_elment_by_name, "q2") | |
| 109 # Try to find the Google search button using the multiple find method. | |
| 110 q = self.driver.find_elements_by_name("q") | |
| 111 self.assertTrue(isinstance(q, list)) | |
| 112 self.assertTrue(len(q), 1) | |
| 113 self.assertTrue(isinstance(q[0], WebElement)) | |
| 114 # Try finding something not on page, with multiple find an empty array | |
| 115 # should return and no exception thrown. | |
| 116 q = self.driver.find_elements_by_name("q2") | |
| 117 assertTrue(q == []) | |
| 118 # Find a hidden element on the page | |
| 119 q = self.driver.find_element_by_name("oq") | |
| 120 self.assertTrue(isinstance(q, WebElement)) | |
| 121 | |
| 122 def testFindElementById(self): | |
| 123 self.navigate(SEARCH) | |
| 124 # Find the padding for the logo near the search bar. | |
| 125 elem = self.driver.find_element_by_id("logocont") | |
| 126 self.assertTrue(isinstance(elem, WebElement)) | |
| 127 # Look for an ID not there. | |
| 128 self.assertRaises(NoSuchElementException, | |
| 129 self.driver.find_element_by_id, "logocont") | |
| 130 | |
| 131 def testFindElementById0WithTimeout(self): | |
| 132 self.set_implicit_wait(0) | |
| 133 self.navigate(SEARCH) | |
| 134 # Find the padding for the logo near the search bar. | |
| 135 elem = self.driver.find_element_by_id("logocont") | |
| 136 self.assertTrue(isinstance(elem, WebElement)) | |
| 137 self.set_implicit_wait(5000) | |
| 138 self.navigate(SEARCH) | |
| 139 # Look for an ID not there. | |
| 140 self.assertRaises(NoSuchElementException, | |
| 141 self.driver.find_element_by_id, "logocont") | |
| 142 | |
| 143 | |
| 144 class TestFindElement(RemoteWebDriverTest): | |
| 145 def testFindByName(self): | |
| 146 self.navigate(SEARCH) | |
| 147 # Find the Google search button. | |
| 148 q = self.driver.find_element_by_name("q") | |
| 149 self.assertTrue(isinstance(q, WebElement)) | |
| 150 # Trying looking for an element not on the page. | |
| 151 self.assertRaises(NoSuchElementException, | |
| 152 self.driver.find_elment_by_name, "q2") | |
| 153 # Try to find the Google search button using the multiple find method. | |
| 154 q = self.driver.find_elements_by_name("q") | |
| 155 self.assertTrue(isinstance(q, list)) | |
| 156 self.assertTrue(len(q), 1) | |
| 157 self.assertTrue(isinstance(q[0], WebElement)) | |
| 158 # Try finding something not on page, with multiple find an empty array | |
| 159 # should return and no exception thrown. | |
| 160 q = self.driver.find_elements_by_name("q2") | |
| 161 assertTrue(q == []) | |
| 162 # Find a hidden element on the page | |
| 163 q = self.driver.find_element_by_name("oq") | |
| 164 self.assertTrue(isinstance(q, WebElement)) | |
| 165 | |
| 166 def testFindElementById(self): | |
| 167 self.navigate(SEARCH) | |
| 168 # Find the padding for the logo near the search bar. | |
| 169 elem = self.driver.find_element_by_id("logocont") | |
| 170 self.assertTrue(isinstance(elem, WebElement)) | |
| 171 # Look for an ID not there. | |
| 172 self.assertRaises(NoSuchElementException, | |
| 173 self.driver.find_element_by_id, "logocont") | |
| 174 | |
| 175 | |
| 176 class TestJavaScriptExecution(RemoteWebDriverTest): | |
| 177 """ Test the execute javascript ability of the remote driver""" | |
| 178 def testNoModification(self): | |
| 179 self.driver.get("http://www.google.com") | |
| 180 title = self.driver.execute_script("return document.title") | |
| 181 self.assertEqual(title, self.driver.get_title()) | |
| 182 | |
| 183 def testModification(self): | |
| 184 self.driver.get("http://www.google.com") | |
| 185 title = self.driver.get_title() | |
| 186 self.assertFind(title, "google") | |
| 187 r = self.driver.execute_script("return document.Foo") | |
| 188 self.assertTrue(r == None) | |
| 189 self.driver.execute_script("document.Foo = \"Hello\"") | |
| 190 r = self.driver.execute_script("return document.Foo") | |
| 191 self.assertTrue(r == "Hello") | |
| 192 | |
| 193 def testComplexObjectFetch(self): | |
| 194 self.driver.get("http://www.google.com") | |
| 195 loc = self.driver.execute_script("return window.location") | |
| 196 self.assertTrue(type(loc) is types.DictType) | |
| 197 self.assertTrue(loc.has_key("hostname")) | |
| 198 self.assertFind(loc["hostname"], "google") | |
| 199 | |
| 200 def testJavascriptExeception(self): | |
| 201 self.driver.get("http://www.google.com") | |
| 202 self.assertRaises(ErrorInResponseException, self.driver.execute_script, | |
| 203 "return windows"); | |
| 204 | |
| 205 def testJavascriptWithNoReturn(self): | |
| 206 self.driver.get("http://www.google.com") | |
| 207 try: | |
| 208 ret = self.driver.execute_script("return window.foobar") | |
| 209 self.assertTrue(type(ret) is types.NoneType) | |
| 210 except: | |
| 211 self.assertTrue(False) | |
| 212 | |
| 213 | |
| 214 class TestNavigation(RemoteWebDriverTest): | |
| 215 def testNavigateToURL(self): | |
| 216 # No redirects are allowed on the google home page. | |
| 217 self.navigate(self.SEARCH) | |
| 218 | |
| 219 def testGoBackWithNoHistory(self): | |
| 220 # Go back one page with nothing to go back to. | |
| 221 self.assertRaises(ErrorInResponseException, self.driver.back) | |
| 222 | |
| 223 def testGoForwardWithNoHistory(self): | |
| 224 # Go forward with nothing to move forward to. | |
| 225 self.assertRaises(ErrorInResponseException, self.driver.forward) | |
| 226 | |
| 227 def testNavigation(self): | |
| 228 # Loads two pages into chrome's navigation history. | |
| 229 self.navigate(self.NEWS) | |
| 230 self.navigate(self.SEARCH) | |
| 231 | |
| 232 # Go back to news. | |
| 233 self.driver.back() | |
| 234 self.assertURL(self.NEWS) | |
| 235 | |
| 236 # Move forward to search. | |
| 237 self.driver.forward() | |
| 238 self.assertURL(self.SEARCH) | |
| 239 | |
| 240 # Verify refresh keeps us on the current page. | |
| 241 self.driver.refresh() | |
| 242 self.assertURL(self.SEARCH) | |
| 243 | |
| 244 # Go back to the previous URL and refresh making sure | |
| 245 # we dont change the page. | |
| 246 self.driver.back() | |
| 247 self.assertURL(self.NEWS) | |
| 248 self.driver.refresh() | |
| 249 self.assertURL(self.NEWS) | |
| 250 | |
| 251 def testGetTitle(self): | |
| 252 self.navigate(self.SEARCH) | |
| 253 title = self.driver.get_title() | |
| 254 # The google name must always be in the search title. | |
| 255 self.assertFind(title, u"google") | |
| 256 | |
| 257 def testGetSource(self): | |
| 258 self.navigate(self.SEARCH) | |
| 259 source = self.driver.get_page_source() | |
| 260 self.assertFind(source, u"document.body.style") # Basic javascript. | |
| 261 self.assertFind(source, u"feeling lucky") # Lucky button. | |
| 262 self.assertFind(source, u"google search") # Searh button. | |
| 263 | |
| 264 | |
| 265 if __name__ == '__main__': | |
| 266 parser = optparse.OptionParser('%prog [options]') | |
| 267 parser.add_option('-u', '--url', dest='url', action='store', | |
| 268 type='string', default=None, | |
| 269 help=('Specifies the URL of a remote WebDriver server to ' | |
| 270 'test against. If not specified, a server will be ' | |
| 271 'started on localhost according to the --exe and ' | |
| 272 '--port flags')) | |
| 273 parser.add_option('-e', '--exe', dest='exe', action='store', | |
| 274 type='string', default=None, | |
| 275 help=('Path to the WebDriver server executable that should ' | |
| 276 'be started for testing; This flag is ignored if ' | |
| 277 '--url is provided for a remote server.')) | |
| 278 parser.add_option('-p', '--port', dest='port', action='store', | |
| 279 type='int', default=8080, | |
| 280 help=('The port to start the WebDriver server executable ' | |
| 281 'on; This flag is ignored if --url is provided for a ' | |
| 282 'remote server.')) | |
| 283 | |
| 284 (options, args) = parser.parse_args() | |
| 285 # Strip out our flags so unittest.main() correct parses the remaining. | |
| 286 sys.argv = sys.argv[:1] | |
| 287 sys.argv.extend(args) | |
| 288 | |
| 289 if options.url: | |
| 290 WEBDRIVER_SERVER_URL = options.url | |
| 291 else: | |
| 292 if options.port: | |
| 293 WEBDRIVER_PORT = options.port | |
| 294 if options.exe: | |
| 295 WEBDRIVER_EXE = options.exe | |
| 296 if not os.path.exists(WEBDRIVER_EXE): | |
| 297 parser.error('WebDriver server executable not found:\n\t%s\n' | |
| 298 'Please specify a valid path with the --exe flag.' | |
| 299 % WEBDRIVER_EXE) | |
| 300 | |
| 301 unittest.main() | |
| OLD | NEW |