1# Copyright (c) 2013 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
5from telemetry.core import exceptions
6from telemetry.page.actions import page_action
7
8class TapElementAction(page_action.PageAction):
9  """Page action that dispatches a custom 'tap' event at an element.
10
11  For pages that don't respond to 'click' events, this action offers
12  an alternative to ClickElementAction.
13
14  Configuration options:
15    find_element_expression: a JavaScript expression that should yield
16                             the element to tap.
17    wait_for_event: an event name that will be listened for on the Document.
18  """
19  def __init__(self, attributes=None):
20    super(TapElementAction, self).__init__(attributes)
21
22  def RunAction(self, page, tab, previous_action):
23    def DoTap():
24      assert hasattr(self, 'find_element_expression')
25      event = 'new CustomEvent("tap", {bubbles: true})'
26      code = '(%s).dispatchEvent(%s)' % (self.find_element_expression, event)
27      try:
28        tab.ExecuteJavaScript(code)
29      except exceptions.EvaluateException:
30        raise page_action.PageActionFailed(
31            'Cannot find element with code ' + self.find_element_javascript)
32
33    if hasattr(self, 'wait_for_event'):
34      code = ('document.addEventListener("%s", '
35              'function(){window.__tap_event_finished=true})')
36      tab.ExecuteJavaScript(code % self.wait_for_event)
37      DoTap()
38      tab.WaitForJavaScriptExpression('window.__tap_event_finished', 60)
39    else:
40      DoTap()
41