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 |