wait.py revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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
3# found in the LICENSE file.
4
5import re
6import time
7
8from telemetry.core import util
9from telemetry.page.actions import page_action
10
11class WaitAction(page_action.PageAction):
12  def __init__(self, attributes=None):
13    self.timeout = 60
14    super(WaitAction, self).__init__(attributes)
15
16  def RunsPreviousAction(self):
17    return (getattr(self, 'condition', None) == 'navigate' or
18            getattr(self, 'condition', None) == 'href_change')
19
20  def RunAction(self, page, tab, previous_action):
21    tab.ExecuteJavaScript(
22        'console.time("' + self.GetTimelineMarkerLabel() + '")')
23
24    if hasattr(self, 'seconds'):
25      time.sleep(self.seconds)
26
27    elif getattr(self, 'condition', None) == 'navigate':
28      if not previous_action:
29        raise page_action.PageActionFailed('You need to perform an action '
30                                           'before waiting for navigate.')
31      previous_action.WillRunAction(page, tab)
32      action_to_perform = lambda: previous_action.RunAction(page, tab, None)
33      tab.PerformActionAndWaitForNavigate(action_to_perform, self.timeout)
34
35    elif getattr(self, 'condition', None) == 'href_change':
36      if not previous_action:
37        raise page_action.PageActionFailed('You need to perform an action '
38                                           'before waiting for a href change.')
39      previous_action.WillRunAction(page, tab)
40      old_url = tab.EvaluateJavaScript('document.location.href')
41      previous_action.RunAction(page, tab, None)
42      util.WaitFor(lambda: tab.EvaluateJavaScript(
43          'document.location.href') != old_url, self.timeout)
44
45    elif getattr(self, 'condition', None) == 'element':
46      if hasattr(self, 'text'):
47        callback_code = 'function(element) { return element != null; }'
48        util.WaitFor(
49            lambda: util.FindElementAndPerformAction(
50                tab, self.text, callback_code), self.timeout)
51      elif hasattr(self, 'selector'):
52        util.WaitFor(lambda: tab.EvaluateJavaScript(
53             'document.querySelector("%s") != null' % re.escape(self.selector)),
54             self.timeout)
55      elif hasattr(self, 'xpath'):
56        code = ('document.evaluate("%s",'
57                                   'document,'
58                                   'null,'
59                                   'XPathResult.FIRST_ORDERED_NODE_TYPE,'
60                                   'null)'
61                  '.singleNodeValue' % re.escape(self.xpath))
62        util.WaitFor(lambda: tab.EvaluateJavaScript('%s != null' % code),
63             self.timeout)
64      else:
65        raise page_action.PageActionFailed(
66            'No element condition given to wait')
67    elif hasattr(self, 'javascript'):
68      util.WaitFor(lambda: tab.EvaluateJavaScript(self.javascript),
69                   self.timeout)
70    else:
71      raise page_action.PageActionFailed('No wait condition found')
72
73    tab.ExecuteJavaScript(
74        'console.timeEnd("' + self.GetTimelineMarkerLabel() + '")')
75
76  def GetTimelineMarkerLabel(self):
77    return 'WaitAction::RunAction'
78