Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 import logging | |
| 5 | 4 |
| 6 from telemetry.page import test_expectations | 5 from telemetry.page import test_expectations |
| 7 from telemetry.page.actions import all_page_actions | |
| 8 from telemetry.page.actions import interact | 6 from telemetry.page.actions import interact |
| 9 from telemetry.page.actions import navigate | 7 from telemetry.page.actions import action_runner |
| 10 from telemetry.page.actions import page_action | |
| 11 | |
| 12 | |
| 13 def _GetActionFromData(action_data): | |
| 14 action_name = action_data['action'] | |
| 15 action = all_page_actions.FindClassWithName(action_name) | |
| 16 if not action: | |
| 17 logging.critical('Could not find an action named %s.', action_name) | |
| 18 logging.critical('Check the page set for a typo and check the error ' | |
| 19 'log for possible Python loading/compilation errors.') | |
| 20 raise Exception('Action "%s" not found.' % action_name) | |
| 21 return action(action_data) | |
| 22 | |
| 23 | |
| 24 def GetSubactionFromData(page, subaction_data, interactive): | |
| 25 subaction_name = subaction_data['action'] | |
| 26 if hasattr(page, subaction_name): | |
| 27 return GetCompoundActionFromPage(page, subaction_name, interactive) | |
| 28 else: | |
| 29 return [_GetActionFromData(subaction_data)] | |
| 30 | |
| 31 | |
| 32 def GetCompoundActionFromPage(page, action_name, interactive=False): | |
| 33 if interactive: | |
| 34 return [interact.InteractAction()] | |
| 35 | |
| 36 if not action_name: | |
| 37 return [] | |
| 38 | |
| 39 action_data_list = getattr(page, action_name) | |
| 40 if not isinstance(action_data_list, list): | |
| 41 action_data_list = [action_data_list] | |
| 42 | |
| 43 action_list = [] | |
| 44 for subaction_data in action_data_list: | |
| 45 for _ in xrange(subaction_data.get('repeat', 1)): | |
| 46 action_list += GetSubactionFromData(page, subaction_data, interactive) | |
| 47 return action_list | |
| 48 | 8 |
| 49 | 9 |
| 50 class Failure(Exception): | 10 class Failure(Exception): |
| 51 """Exception that can be thrown from PageMeasurement to indicate an | 11 """Exception that can be thrown from PageMeasurement to indicate an |
| 52 undesired but designed-for problem.""" | 12 undesired but designed-for problem.""" |
| 53 pass | 13 pass |
| 54 | 14 |
| 55 | 15 |
| 56 class PageTest(object): | 16 class PageTest(object): |
| 57 """A class styled on unittest.TestCase for creating page-specific tests.""" | 17 """A class styled on unittest.TestCase for creating page-specific tests.""" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 """Override to add test-specific options to the BrowserOptions object""" | 138 """Override to add test-specific options to the BrowserOptions object""" |
| 179 pass | 139 pass |
| 180 | 140 |
| 181 def CustomizeBrowserOptionsForPageSet(self, page_set, options): | 141 def CustomizeBrowserOptionsForPageSet(self, page_set, options): |
| 182 """Set options required for this page set. | 142 """Set options required for this page set. |
| 183 | 143 |
| 184 These options will be used every time the browser is started while running | 144 These options will be used every time the browser is started while running |
| 185 this page set. They may, however, be further modified by | 145 this page set. They may, however, be further modified by |
| 186 CustomizeBrowserOptionsForSinglePage or by the profiler. | 146 CustomizeBrowserOptionsForSinglePage or by the profiler. |
| 187 """ | 147 """ |
| 188 for page in page_set: | 148 for page in page_set.pages: |
| 189 if not self.CanRunForPage(page): | 149 if not self.CanRunForPage(page): |
| 190 return | 150 return |
| 191 interactive = options and options.interactive | 151 #TODO(nednguyen): Remove CustomizeBrowserOptionsForPageSet from actions |
| 192 for action in GetCompoundActionFromPage( | 152 page_set.AddCustomizeBrowserOptions(options) |
| 193 page, self._action_name_to_run, interactive): | |
| 194 action.CustomizeBrowserOptionsForPageSet(options) | |
| 195 | 153 |
| 196 def CustomizeBrowserOptionsForSinglePage(self, page, options): | 154 def CustomizeBrowserOptionsForSinglePage(self, page, options): |
| 197 """Set options specific to the test and the given page. | 155 """Set options specific to the test and the given page. |
| 198 | 156 |
| 199 This will be called with the current page when the browser is (re)started. | 157 This will be called with the current page when the browser is (re)started. |
| 200 Changing options at this point only makes sense if the browser is being | 158 Changing options at this point only makes sense if the browser is being |
| 201 restarted for each page. | 159 restarted for each page. |
| 202 """ | 160 """ |
| 203 interactive = options and options.interactive | 161 page.AddCustomizeBrowserOptions(options) |
| 204 for action in GetCompoundActionFromPage( | |
| 205 page, self._action_name_to_run, interactive): | |
| 206 action.CustomizeBrowserOptionsForSinglePage(options) | |
| 207 | 162 |
| 208 def WillStartBrowser(self, browser): | 163 def WillStartBrowser(self, browser): |
| 209 """Override to manipulate the browser environment before it launches.""" | 164 """Override to manipulate the browser environment before it launches.""" |
| 210 pass | 165 pass |
| 211 | 166 |
| 212 def DidStartBrowser(self, browser): | 167 def DidStartBrowser(self, browser): |
| 213 """Override to customize the browser right after it has launched.""" | 168 """Override to customize the browser right after it has launched.""" |
| 214 pass | 169 pass |
| 215 | 170 |
| 216 def CanRunForPage(self, page): # pylint: disable=W0613 | 171 def CanRunForPage(self, page): # pylint: disable=W0613 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 create a new tab for every page, return browser.tabs.New().""" | 239 create a new tab for every page, return browser.tabs.New().""" |
| 285 return browser.tabs[0] | 240 return browser.tabs[0] |
| 286 | 241 |
| 287 def ValidatePageSet(self, page_set): | 242 def ValidatePageSet(self, page_set): |
| 288 """Override to examine the page set before the test run. Useful for | 243 """Override to examine the page set before the test run. Useful for |
| 289 example to validate that the pageset can be used with the test.""" | 244 example to validate that the pageset can be used with the test.""" |
| 290 pass | 245 pass |
| 291 | 246 |
| 292 def Run(self, page, tab, results): | 247 def Run(self, page, tab, results): |
| 293 interactive = self.options and self.options.interactive | 248 interactive = self.options and self.options.interactive |
| 294 compound_action = GetCompoundActionFromPage( | 249 runner = action_runner.ActionRunner(page, tab, self) |
| 295 page, self._action_name_to_run, interactive) | |
| 296 self.WillRunActions(page, tab) | 250 self.WillRunActions(page, tab) |
| 297 self._RunCompoundAction(page, tab, compound_action) | 251 if interactive: |
| 252 runner.RunAction(interact.InteractAction()) | |
| 253 else: | |
| 254 compound_action = getattr(page, self._action_name_to_run) | |
|
nduca
2014/03/05 03:00:57
compound_action -> run_method?
| |
| 255 compound_action(runner) | |
| 298 self.DidRunActions(page, tab) | 256 self.DidRunActions(page, tab) |
| 299 self._test_method(page, tab, results) | 257 self._test_method(page, tab, results) |
| 300 | 258 |
| 301 def _RunCompoundAction(self, page, tab, actions, run_setup_methods=True): | |
| 302 for i, action in enumerate(actions): | |
| 303 prev_action = actions[i - 1] if i > 0 else None | |
| 304 next_action = actions[i + 1] if i < len(actions) - 1 else None | |
| 305 | |
| 306 if (action.RunsPreviousAction() and | |
| 307 next_action and next_action.RunsPreviousAction()): | |
| 308 raise page_action.PageActionFailed('Consecutive actions cannot both ' | |
| 309 'have RunsPreviousAction() == True.') | |
| 310 | |
| 311 if not (next_action and next_action.RunsPreviousAction()): | |
| 312 action.WillRunAction(page, tab) | |
| 313 if run_setup_methods: | |
| 314 self.WillRunAction(page, tab, action) | |
| 315 try: | |
| 316 action.RunAction(page, tab, prev_action) | |
| 317 finally: | |
| 318 if run_setup_methods: | |
| 319 self.DidRunAction(page, tab, action) | |
| 320 | |
| 321 # Note that we must not call util.CloseConnections here. Many tests | |
| 322 # navigate to a URL in the first action and then wait for a condition | |
| 323 # in the second action. Calling util.CloseConnections here often | |
| 324 # aborts resource loads performed by the page. | |
| 325 | |
| 326 def RunNavigateSteps(self, page, tab): | 259 def RunNavigateSteps(self, page, tab): |
| 327 """Navigates the tab to the page URL attribute. | 260 """Navigates the tab to the page URL attribute. |
| 328 | 261 |
| 329 Runs the 'navigate_steps' page attribute as a compound action. | 262 Runs the 'navigate_steps' page attribute as a compound action. |
| 330 """ | 263 """ |
| 331 navigate_actions = GetCompoundActionFromPage(page, 'navigate_steps') | 264 if hasattr(page, 'navigate_steps'): |
| 332 if not any(isinstance(action, navigate.NavigateAction) | 265 runner = action_runner.ActionRunner(page, tab, None) |
| 333 for action in navigate_actions): | 266 page.navigate_steps(runner) |
|
nduca
2014/03/05 03:00:57
method_name -> MethodName
and maybe just call thi
| |
| 334 raise page_action.PageActionFailed( | |
| 335 'No NavigateAction in navigate_steps') | |
| 336 | |
| 337 self._RunCompoundAction(page, tab, navigate_actions, False) | |
| 338 | 267 |
| 339 def IsExiting(self): | 268 def IsExiting(self): |
| 340 return self._exit_requested | 269 return self._exit_requested |
| 341 | 270 |
| 342 def RequestExit(self): | 271 def RequestExit(self): |
| 343 self._exit_requested = True | 272 self._exit_requested = True |
| 344 | 273 |
| 345 @property | 274 @property |
| 346 def action_name_to_run(self): | 275 def action_name_to_run(self): |
| 347 return self._action_name_to_run | 276 return self._action_name_to_run |
| OLD | NEW |