Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """The testing Environment class.""" | 5 """The testing Environment class. |
| 6 | |
| 7 It holds the WebsiteTest instances, provides them with credentials, | |
| 8 provides clean browser environment, runs the tests, and gathers the | |
| 9 results. | |
| 10 """ | |
| 6 | 11 |
| 7 import os | 12 import os |
| 8 import shutil | 13 import shutil |
| 9 import time | 14 import time |
| 10 from xml.etree import ElementTree | 15 from xml.etree import ElementTree |
| 11 | 16 |
| 12 from selenium import webdriver | 17 from selenium import webdriver |
| 13 from selenium.webdriver.chrome.options import Options | 18 from selenium.webdriver.chrome.options import Options |
| 14 | 19 |
| 15 | 20 |
| 16 # Message strings to look for in chrome://password-manager-internals | 21 # Message strings to look for in chrome://password-manager-internals. |
| 17 MESSAGE_ASK = "Message: Decision: ASK the user" | 22 MESSAGE_ASK = "Message: Decision: ASK the user" |
| 18 MESSAGE_SAVE = "Message: Decision: SAVE the password" | 23 MESSAGE_SAVE = "Message: Decision: SAVE the password" |
| 19 | 24 |
| 20 | 25 INTERNALS_PAGE_URL = "chrome://password-manager-internals/" |
| 21 class TestResult: | |
| 22 """Stores the information related to a test result. """ | |
| 23 def __init__(self, name, test_type, successful, message): | |
| 24 """Creates a new TestResult. | |
| 25 | |
| 26 Args: | |
| 27 name: The tested website name. | |
| 28 test_type: The test type. | |
| 29 successful: Whether or not the test was successful. | |
| 30 message: The error message of the test. | |
| 31 """ | |
| 32 self.name = name | |
| 33 self.test_type = test_type | |
| 34 self.successful = successful | |
| 35 self.message = message | |
| 36 | |
| 37 | 26 |
| 38 class Environment: | 27 class Environment: |
| 39 """Sets up the testing Environment. """ | 28 """Sets up the testing Environment. """ |
| 40 | 29 |
| 41 def __init__(self, chrome_path, chromedriver_path, profile_path, | 30 def __init__(self, chrome_path, chromedriver_path, profile_path, |
| 42 passwords_path, enable_automatic_password_saving): | 31 passwords_path, enable_automatic_password_saving): |
| 43 """Creates a new testing Environment. | 32 """Creates a new testing Environment, starts Chromedriver. |
| 44 | 33 |
| 45 Args: | 34 Args: |
| 46 chrome_path: The chrome binary file. | 35 chrome_path: The chrome binary file. |
| 47 chromedriver_path: The chromedriver binary file. | 36 chromedriver_path: The chromedriver binary file. |
| 48 profile_path: The chrome testing profile folder. | 37 profile_path: The chrome testing profile folder. |
| 49 passwords_path: The usernames and passwords file. | 38 passwords_path: The usernames and passwords file. |
| 50 enable_automatic_password_saving: If True, the passwords are going to be | 39 enable_automatic_password_saving: If True, the passwords are going to be |
| 51 saved without showing the prompt. | 40 saved without showing the prompt. |
| 52 | 41 |
| 53 Raises: | 42 Raises: |
| 54 Exception: An exception is raised if |profile_path| folder could not be | 43 Exception: An exception is raised if |profile_path| folder could not be |
| 55 removed. | 44 removed. |
| 56 """ | 45 """ |
| 57 | 46 |
| 58 # Cleaning the chrome testing profile folder. | 47 # Cleaning the chrome testing profile folder. |
| 59 if os.path.exists(profile_path): | 48 if os.path.exists(profile_path): |
| 60 shutil.rmtree(profile_path) | 49 shutil.rmtree(profile_path) |
| 50 | |
| 61 options = Options() | 51 options = Options() |
| 62 self.enable_automatic_password_saving = enable_automatic_password_saving | |
| 63 if enable_automatic_password_saving: | 52 if enable_automatic_password_saving: |
| 64 options.add_argument("enable-automatic-password-saving") | 53 options.add_argument("enable-automatic-password-saving") |
| 65 # Chrome path. | 54 # TODO(vabr): show_prompt is used in WebsiteTest for asserting that |
| 55 # Chrome set-up corresponds to the test type. Remove that knowledge | |
| 56 # about Environment from the WebsiteTest. | |
| 57 self.show_prompt = not enable_automatic_password_saving | |
| 66 options.binary_location = chrome_path | 58 options.binary_location = chrome_path |
| 67 # Chrome testing profile path. | |
| 68 options.add_argument("user-data-dir=%s" % profile_path) | 59 options.add_argument("user-data-dir=%s" % profile_path) |
| 69 | 60 |
| 70 # The webdriver. It's possible to choose the port the service is going to | 61 # The webdriver. It's possible to choose the port the service is going to |
| 71 # run on. If it's left to 0, a free port will be found. | 62 # run on. If it's left to 0, a free port will be found. |
| 72 self.driver = webdriver.Chrome(chromedriver_path, 0, options) | 63 self.driver = webdriver.Chrome(chromedriver_path, 0, options) |
| 73 # The password internals window. | 64 |
| 65 # Password internals page tab/window handle. | |
| 74 self.internals_window = self.driver.current_window_handle | 66 self.internals_window = self.driver.current_window_handle |
| 75 if passwords_path: | 67 |
| 76 # An xml tree filled with logins and passwords. | 68 # An xml tree filled with logins and passwords. |
| 77 self.passwords_tree = ElementTree.parse(passwords_path).getroot() | 69 self.passwords_tree = ElementTree.parse(passwords_path).getroot() |
|
msramek
2015/03/27 11:37:06
This can throw IOError or ParseError. Why don't we
vabr (Chromium)
2015/03/27 12:14:43
This is intentional. The tests cannot be run, and
| |
| 78 else: | 70 |
| 79 raise Exception("Error: |passwords_path| needs to be provided if" | 71 self.website_window = self._OpenNewTab() |
| 80 "|chrome_path| is provided, otherwise the tests could not be run") | 72 |
| 81 # Password internals page. | |
| 82 self.internals_page = "chrome://password-manager-internals/" | |
| 83 # The Website window. | |
| 84 self.website_window = None | |
| 85 # The WebsiteTests list. | |
| 86 self.websitetests = [] | 73 self.websitetests = [] |
| 74 | |
| 87 # Map messages to the number of their appearance in the log. | 75 # Map messages to the number of their appearance in the log. |
| 88 self.message_count = { MESSAGE_ASK: 0, MESSAGE_SAVE: 0 } | 76 self.message_count = { MESSAGE_ASK: 0, MESSAGE_SAVE: 0 } |
| 89 # The tests needs two tabs to work. A new tab is opened with the first | 77 |
| 90 # GoTo. This is why we store here whether or not it's the first time to | 78 # A list of (test_name, test_type, test_success, failure_log). |
| 91 # execute GoTo. | |
| 92 self.first_go_to = True | |
| 93 # List of all tests results. | |
| 94 self.tests_results = [] | 79 self.tests_results = [] |
| 95 | 80 |
| 96 def AddWebsiteTest(self, websitetest): | 81 def AddWebsiteTest(self, websitetest): |
| 97 """Adds a WebsiteTest to the testing Environment. | 82 """Adds a WebsiteTest to the testing Environment. |
| 98 | 83 |
| 99 TODO(vabr): Currently, this is only called at most once for each | 84 TODO(vabr): Currently, this is only called at most once for each |
| 100 Environment instance. That is because to run all tests efficiently in | 85 Environment instance. That is because to run all tests efficiently in |
| 101 parallel, each test gets its own process spawned (outside of Python). | 86 parallel, each test gets its own process spawned (outside of Python). |
| 102 That makes sense, but then we should flatten the hierarchy of calls | 87 That makes sense, but then we should flatten the hierarchy of calls |
| 103 and consider making the 1:1 relation of environment to tests more | 88 and consider making the 1:1 relation of environment to tests more |
| 104 explicit. | 89 explicit. |
| 105 | 90 |
| 106 Args: | 91 Args: |
| 107 websitetest: The WebsiteTest instance to be added. | 92 websitetest: The WebsiteTest instance to be added. |
| 108 """ | 93 """ |
| 109 websitetest.environment = self | 94 websitetest.environment = self |
| 110 # TODO(vabr): Make driver a property of WebsiteTest. | 95 # TODO(vabr): Make driver a property of WebsiteTest. |
| 111 websitetest.driver = self.driver | 96 websitetest.driver = self.driver |
| 112 if not websitetest.username: | 97 if not websitetest.username: |
| 113 username_tag = ( | 98 username_tag = (self.passwords_tree.find( |
| 114 self.passwords_tree.find( | 99 ".//*[@name='%s']/username" % websitetest.name)) |
| 115 ".//*[@name='%s']/username" % websitetest.name)) | |
| 116 websitetest.username = username_tag.text | 100 websitetest.username = username_tag.text |
| 117 if not websitetest.password: | 101 if not websitetest.password: |
| 118 password_tag = ( | 102 password_tag = (self.passwords_tree.find( |
| 119 self.passwords_tree.find( | 103 ".//*[@name='%s']/password" % websitetest.name)) |
| 120 ".//*[@name='%s']/password" % websitetest.name)) | |
| 121 websitetest.password = password_tag.text | 104 websitetest.password = password_tag.text |
| 122 self.websitetests.append(websitetest) | 105 self.websitetests.append(websitetest) |
| 123 | 106 |
| 124 def ClearCache(self, clear_passwords): | 107 def _ClearBrowserDataInit(self): |
| 125 """Clear the browser cookies. If |clear_passwords| is true, clear all the | 108 """Opens and resets the chrome://settings/clearBrowserData dialog. |
| 126 saved passwords too. | 109 |
| 110 It unchecks all checkboxes, and sets the time range to the "beginning of | |
| 111 time". | |
| 112 """ | |
| 113 | |
| 114 self.driver.get("chrome://settings/clearBrowserData") | |
| 115 self.driver.switch_to_frame("settings") | |
| 116 | |
| 117 time_range_selector = "#clear-browser-data-time-period" | |
| 118 # TODO(vabr): Wait until time_range_selector is displayed instead. | |
| 119 time.sleep(2) | |
| 120 set_time_range = ( | |
| 121 "var range = document.querySelector('{0}');".format( | |
| 122 time_range_selector) + | |
| 123 "range.value = 4" # 4 == the beginning of time | |
| 124 ) | |
| 125 self.driver.execute_script(set_time_range) | |
| 126 | |
| 127 all_cboxes_selector = ( | |
| 128 "#clear-data-checkboxes > * > * >[type=\"checkbox\"]") | |
|
msramek
2015/03/27 11:37:07
Nit: Why not just
#clear-data-checkboxes [type="c
vabr (Chromium)
2015/03/27 12:14:43
Agreed and done.
(Learning CSS selectors on the fl
| |
| 129 uncheck_all = ( | |
| 130 "var checkboxes = document.querySelectorAll('{0}');".format( | |
| 131 all_cboxes_selector ) + | |
| 132 "for (var i = 0; i < checkboxes.length; ++i) {" | |
| 133 " if (checkboxes[i].checked)" | |
|
msramek
2015/03/27 11:37:06
Nit:
checkboxes[i].checked = false
vabr (Chromium)
2015/03/27 12:14:43
Done.
| |
| 134 " checkboxes[i].click();" | |
| 135 "}" | |
| 136 ) | |
| 137 self.driver.execute_script(uncheck_all) | |
| 138 | |
| 139 def _ClearDataForCheckbox(self, selector): | |
| 140 """Causes the data associated with |selector| to be cleared. | |
| 141 | |
| 142 Opens chrome://settings/clearBrowserData, unchecks all checkboxes, then | |
| 143 checks the one described by |selector|, then clears the corresponding | |
| 144 browsing data for the full time range. | |
| 127 | 145 |
| 128 Args: | 146 Args: |
| 129 clear_passwords : Clear all the passwords if the bool value is true. | 147 selector: describes the checkbox through which to delete the data. |
| 130 """ | 148 """ |
| 131 self.driver.get("chrome://settings/clearBrowserData") | 149 |
| 132 self.driver.switch_to_frame("settings") | 150 self._ClearBrowserDataInit() |
| 133 script = ( | 151 check_cookies_and_submit = ( |
| 134 "if (!document.querySelector('#delete-cookies-checkbox').checked)" | 152 "var cbox = document.querySelector('{0}');".format(selector) + |
| 135 " document.querySelector('#delete-cookies-checkbox').click();" | 153 "if (!cbox.checked)" |
|
msramek
2015/03/27 11:37:07
Nit:
document.querySelector().checked = true
vabr (Chromium)
2015/03/27 12:14:43
Done.
| |
| 154 " cbox.click();" | |
| 155 "document.querySelector('#clear-browser-data-commit').click();" | |
| 136 ) | 156 ) |
| 137 negation = "" | 157 self.driver.execute_script(check_cookies_and_submit) |
| 138 if clear_passwords: | 158 |
| 139 negation = "!" | 159 def _EnablePasswordSaving(self): |
| 140 script += ( | 160 """Make sure that password manager is enabled.""" |
| 141 "if (%sdocument.querySelector('#delete-passwords-checkbox').checked)" | 161 |
| 142 " document.querySelector('#delete-passwords-checkbox').click();" | |
| 143 % negation) | |
| 144 script += "document.querySelector('#clear-browser-data-commit').click();" | |
| 145 self.driver.execute_script(script) | |
| 146 time.sleep(2) | |
| 147 # Every time we do something to the cache let's enable password saving. | |
| 148 # TODO(melandory): We should check why it's off in a first place. | 162 # TODO(melandory): We should check why it's off in a first place. |
| 149 # TODO(melandory): Investigate, maybe there is no need to enable it that | 163 # TODO(melandory): Investigate, maybe there is no need to enable it that |
| 150 # often. | 164 # often. |
| 151 self.EnablePasswordsSaving() | |
| 152 | |
| 153 def EnablePasswordsSaving(self): | |
| 154 self.driver.get("chrome://settings") | 165 self.driver.get("chrome://settings") |
| 155 self.driver.switch_to_frame("settings") | 166 self.driver.switch_to_frame("settings") |
| 156 script = "document.getElementById('advanced-settings-expander').click();" | 167 script = "document.getElementById('advanced-settings-expander').click();" |
| 157 self.driver.execute_script(script) | 168 self.driver.execute_script(script) |
| 169 # TODO(vabr): Wait until element is displayed instead. | |
| 158 time.sleep(2) | 170 time.sleep(2) |
| 159 script = ( | 171 script = ( |
| 160 "if (!document.querySelector('#password-manager-enabled').checked)" | 172 "if (!document.querySelector('#password-manager-enabled').checked)" |
|
msramek
2015/03/27 11:37:06
Nit: As above.
vabr (Chromium)
2015/03/27 12:14:43
Done.
| |
| 161 "{ document.querySelector('#password-manager-enabled').click();}") | 173 "{ document.querySelector('#password-manager-enabled').click();}") |
| 162 self.driver.execute_script(script) | 174 self.driver.execute_script(script) |
| 163 time.sleep(2) | 175 time.sleep(2) |
| 164 | 176 |
| 165 def OpenTabAndGoToInternals(self, url): | 177 def _OpenNewTab(self): |
| 166 """If there is no |self.website_window|, opens a new tab and navigates to | 178 """Open a new tab, and loads the internals page in the old tab. |
| 167 |url| in the new tab. Navigates to the passwords internals page in the | |
| 168 first tab. Raises an exception otherwise. | |
| 169 | 179 |
| 170 Args: | 180 Returns: |
| 171 url: Url to go to in the new tab. | 181 A handle to the new tab. |
| 182 """ | |
| 172 | 183 |
| 173 Raises: | 184 number_old_tabs = len(self.driver.window_handles) |
| 174 Exception: An exception is raised if |self.website_window| already | |
| 175 exists. | |
| 176 """ | |
| 177 if self.website_window: | |
| 178 raise Exception("Error: The window was already opened.") | |
| 179 | |
| 180 self.driver.get("chrome://newtab") | |
| 181 # There is no straightforward way to open a new tab with chromedriver. | 185 # There is no straightforward way to open a new tab with chromedriver. |
| 182 # One work-around is to go to a website, insert a link that is going | 186 # One work-around is to go to a website, insert a link that is going |
| 183 # to be opened in a new tab, click on it. | 187 # to be opened in a new tab, and click on it. |
| 188 self.driver.get("about:blank") | |
| 184 a = self.driver.execute_script( | 189 a = self.driver.execute_script( |
| 185 "var a = document.createElement('a');" | 190 "var a = document.createElement('a');" |
| 186 "a.target = '_blank';" | 191 "a.target = '_blank';" |
| 187 "a.href = arguments[0];" | 192 "a.href = 'about:blank';" |
| 188 "a.innerHTML = '.';" | 193 "a.innerHTML = '.';" |
| 189 "document.body.appendChild(a);" | 194 "document.body.appendChild(a);" |
| 190 "return a;", | 195 "return a;") |
| 191 url) | 196 a.click() |
| 197 while number_old_tabs == len(self.driver.window_handles): | |
| 198 time.sleep(1) # Wait until the new tab is opened. | |
| 192 | 199 |
| 193 a.click() | 200 new_tab = self.driver.window_handles[-1] |
| 194 time.sleep(1) | 201 self.driver.get(INTERNALS_PAGE_URL) |
| 202 self.driver.switch_to_window(new_tab) | |
| 203 return new_tab | |
| 195 | 204 |
| 196 self.website_window = self.driver.window_handles[-1] | 205 def _DidStringAppearUntilTimeout(self, strings, timeout): |
| 197 self.driver.get(self.internals_page) | 206 """Checks whether some of |strings| appeared in the current page. |
| 198 self.driver.switch_to_window(self.website_window) | |
| 199 | 207 |
| 200 def SwitchToInternals(self): | 208 Waits for up to |timeout| seconds until at least one of |strings| is |
| 201 """Switches from the Website window to internals tab.""" | 209 shown in the current page. Updates self.message_count with the current |
| 202 self.driver.switch_to_window(self.internals_window) | 210 number of occurrences of the shown string. Assumes that at most |
| 203 | 211 one of |strings| is newly shown. |
| 204 def SwitchFromInternals(self): | |
| 205 """Switches from internals tab to the Website window.""" | |
| 206 self.driver.switch_to_window(self.website_window) | |
| 207 | |
| 208 def _DidMessageAppearUntilTimeout(self, log_message, timeout): | |
| 209 """Checks whether the save password prompt is shown. | |
| 210 | 212 |
| 211 Args: | 213 Args: |
| 212 log_message: Log message to look for in the password internals. | 214 strings: A list of strings to look for. |
| 213 timeout: There is some delay between the login and the password | 215 timeout: If any such string does not appear within the first |timeout| |
| 214 internals update. The method checks periodically during the first | 216 seconds, it is considered a no-show. |
| 215 |timeout| seconds if the internals page reports the prompt being | |
| 216 shown. If the prompt is not reported shown within the first | |
| 217 |timeout| seconds, it is considered not shown at all. | |
| 218 | 217 |
| 219 Returns: | 218 Returns: |
| 220 True if the save password prompt is shown. | 219 True if one of |strings| is observed until |timeout|, False otherwise. |
| 221 False otherwise. | |
| 222 """ | 220 """ |
| 221 | |
| 223 log = self.driver.find_element_by_css_selector("#log-entries") | 222 log = self.driver.find_element_by_css_selector("#log-entries") |
| 224 count = log.text.count(log_message) | 223 while timeout: |
|
msramek
2015/03/27 11:37:06
Why don't we just sleep for |timeout| and then cou
vabr (Chromium)
2015/03/27 12:14:43
No, but in the case when they appear, they mostly
| |
| 224 for string in strings: | |
| 225 count = log.text.count(string) | |
| 226 if count > self.message_count[string]: | |
| 227 self.message_count[string] = count | |
| 228 return True | |
| 229 time.sleep(1) | |
| 230 timeout -= 1 | |
| 231 return False | |
| 225 | 232 |
| 226 if count > self.message_count[log_message]: | 233 def CheckForNewString(self, strings, string_should_show_up, error): |
| 227 self.message_count[log_message] = count | 234 """Checks that |strings| show up on the internals page as it should. |
| 228 return True | |
| 229 elif timeout > 0: | |
| 230 time.sleep(1) | |
| 231 return self._DidMessageAppearUntilTimeout(log_message, timeout - 1) | |
| 232 else: | |
| 233 return False | |
| 234 | 235 |
| 235 def CheckForNewMessage(self, log_message, message_should_show_up, | 236 Switches to the internals page and looks for a new instances of |strings| |
| 236 error_message, timeout=15): | 237 being shown up there. It checks that |string_should_show_up| is true if |
| 237 """Detects whether the save password prompt is shown. | 238 and only if at leas one string from |strings| shows up, and throws an |
| 239 Exception if that check fails. | |
| 238 | 240 |
| 239 Args: | 241 Args: |
| 240 log_message: Log message to look for in the password internals. The | 242 strings: A list of strings to look for in the internals page. |
| 241 only valid values are the constants MESSAGE_* defined at the | 243 string_should_show_up: Whether or not at least one string from |strings| |
| 242 beginning of this file. | 244 is expected to be shown. |
| 243 message_should_show_up: Whether or not the message is expected to be | 245 error: Error message for the exception. |
| 244 shown. | |
| 245 error_message: Error message for the exception. | |
| 246 timeout: There is some delay between the login and the password | |
| 247 internals update. The method checks periodically during the first | |
| 248 |timeout| seconds if the internals page reports the prompt being | |
| 249 shown. If the prompt is not reported shown within the first | |
| 250 |timeout| seconds, it is considered not shown at all. | |
| 251 | 246 |
| 252 Raises: | 247 Raises: |
| 253 Exception: An exception is raised in case the result does not match the | 248 Exception: (See above.) |
| 254 expectation | |
| 255 """ | 249 """ |
| 256 if (self._DidMessageAppearUntilTimeout(log_message, timeout) != | |
| 257 message_should_show_up): | |
| 258 raise Exception(error_message) | |
| 259 | 250 |
| 260 def AllTests(self, prompt_test): | 251 self.driver.switch_to_window(self.internals_window) |
| 261 """Runs the tests on all the WebsiteTests. | 252 try: |
| 253 if (self._DidStringAppearUntilTimeout(strings, 15) != | |
| 254 string_should_show_up): | |
| 255 raise Exception(error) | |
| 256 finally: | |
| 257 self.driver.switch_to_window(self.website_window) | |
| 262 | 258 |
| 263 TODO(vabr): Currently, "all tests" always means one. | 259 def DeleteCookies(self): |
| 260 """Deletes cookies via the settings page.""" | |
| 261 | |
| 262 self._ClearDataForCheckbox("#delete-cookies-checkbox") | |
| 263 | |
| 264 def RunTestsOnSites(self, test_type): | |
| 265 """Runs the specified test on the known websites. | |
| 266 | |
| 267 Also saves the test results in the environment. Note that test types | |
| 268 differ in their requirements on whether the save password prompt | |
| 269 should be displayed. Make sure that such requirements are consistent | |
| 270 with the enable_automatic_password_saving argument passed to |self| | |
| 271 on construction. | |
| 264 | 272 |
| 265 Args: | 273 Args: |
| 266 prompt_test: If True, tests caring about showing the save-password | 274 test_type: A test identifier understood by WebsiteTest.run_test(). |
| 267 prompt are going to be run, otherwise tests which don't care about | 275 """ |
| 268 the prompt are going to be run. | |
| 269 | 276 |
| 270 Raises: | 277 self.DeleteCookies() |
| 271 Exception: An exception is raised if the tests fail. | 278 self._ClearDataForCheckbox("#delete-passwords-checkbox") |
| 272 """ | 279 self._EnablePasswordSaving() |
| 273 if prompt_test: | |
| 274 self.PromptTestList(self.websitetests) | |
| 275 else: | |
| 276 self.TestList(self.websitetests) | |
| 277 | 280 |
| 278 def Test(self, tests, prompt_test): | |
| 279 """Runs the tests on websites named in |tests|. | |
| 280 | |
| 281 Args: | |
| 282 tests: A list of the names of the WebsiteTests that are going to be | |
| 283 tested. | |
| 284 prompt_test: If True, tests caring about showing the save-password | |
| 285 prompt are going to be run, otherwise tests which don't care about | |
| 286 the prompt are going to be executed. | |
| 287 | |
| 288 Raises: | |
| 289 Exception: An exception is raised if the tests fail. | |
| 290 """ | |
| 291 websitetests = [] | |
| 292 for websitetest in self.websitetests: | 281 for websitetest in self.websitetests: |
| 293 if websitetest.name in tests: | |
| 294 websitetests.append(websitetest) | |
| 295 | |
| 296 if prompt_test: | |
| 297 self.PromptTestList(websitetests) | |
| 298 else: | |
| 299 self.TestList(websitetests) | |
| 300 | |
| 301 def TestList(self, websitetests): | |
| 302 """Runs the tests on the websites in |websitetests|. | |
| 303 | |
| 304 Args: | |
| 305 websitetests: A list of WebsiteTests that are going to be tested. | |
| 306 | |
| 307 Raises: | |
| 308 Exception: An exception is raised if the tests fail. | |
| 309 """ | |
| 310 self.ClearCache(True) | |
| 311 | |
| 312 for websitetest in websitetests: | |
| 313 successful = True | 282 successful = True |
| 314 error = "" | 283 error = "" |
| 315 try: | 284 try: |
| 316 websitetest.was_run = True | 285 websitetest.RunTest(test_type) |
| 317 websitetest.WrongLoginTest() | |
| 318 websitetest.SuccessfulLoginTest() | |
| 319 self.ClearCache(False) | |
| 320 websitetest.SuccessfulLoginWithAutofilledPasswordTest() | |
| 321 self.ClearCache(True) | |
| 322 websitetest.SuccessfulLoginTest() | |
| 323 self.ClearCache(True) | |
| 324 except Exception as e: | 286 except Exception as e: |
| 325 successful = False | 287 successful = False |
| 326 error = e.message | 288 error = e.message |
| 327 self.tests_results.append(TestResult(websitetest.name, "normal", | 289 self.tests_results.append( |
| 328 successful, error)) | 290 (websitetest.name, test_type, successful, error)) |
| 329 | |
| 330 | |
| 331 def PromptTestList(self, websitetests): | |
| 332 """Runs the prompt tests on the websites in |websitetests|. | |
| 333 | |
| 334 Args: | |
| 335 websitetests: A list of WebsiteTests that are going to be tested. | |
| 336 | |
| 337 Raises: | |
| 338 Exception: An exception is raised if the tests fail. | |
| 339 """ | |
| 340 self.ClearCache(True) | |
| 341 | |
| 342 for websitetest in websitetests: | |
| 343 successful = True | |
| 344 error = "" | |
| 345 try: | |
| 346 websitetest.was_run = True | |
| 347 websitetest.PromptTest() | |
| 348 except Exception as e: | |
| 349 successful = False | |
| 350 error = e.message | |
| 351 self.tests_results.append(TestResult(websitetest.name, "prompt", | |
| 352 successful, error)) | |
| 353 | 291 |
| 354 def Quit(self): | 292 def Quit(self): |
| 355 """Closes the tests.""" | 293 """Shuts down the driver.""" |
| 356 # Close the webdriver. | 294 |
| 357 self.driver.quit() | 295 self.driver.quit() |
| OLD | NEW |