Commit b5034ea8 authored by dominikg@chromium.org's avatar dominikg@chromium.org

Telemetry: Clean up tap and click_element gestures.

The tap and click_element page actions have a very similar purpose but use a very
different implementation. This patch renames click_element to javascript_click
to indicate that it is not using synthetic gestures as tap does. It also replaces
click_element with tap inside smoothness measurements, so we exercise the entire
input stack. In other places we keep click_element (now javascript_click) because
tap's functionality isn't always sufficient (click elements outside of the view;
clicking on very small elements causes Chrome to magnify the element first).
Further, tap now supports all ways to select an element that click_element
supported (by text, xpath etc).

This CL also removes the tap_element page action, which was only used inside
smoothness for the pica page set. This case is currently broken and adamk@ said
he'd re-implement it using synthetic gestures if needed.

BUG=339233

Review URL: https://codereview.chromium.org/181483002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255355 0039d316-1c4b-4281-b951-d872f2087c98
parent ec4c5839
......@@ -11,9 +11,9 @@
{ "action": "wait", "condition": "element", "xpath": "id(\"attach\")" }
],
"endure": [
{ "action": "click_element", "xpath": "id(\"attach\")" },
{ "action": "javascript_click", "xpath": "id(\"attach\")" },
{ "action": "wait", "seconds": 0.5 },
{ "action": "click_element", "xpath": "id(\"detach\")" },
{ "action": "javascript_click", "xpath": "id(\"detach\")" },
{ "action": "wait", "seconds": 0.5 }
]
}
......
......@@ -16,28 +16,28 @@
{ "action": "javascript", "expression": "(function() { var elem = document.createElement('meta');elem.name='viewport';elem.content='initial-scale=1';document.body.appendChild(elem); })();" }
],
"endure": [
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" },
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" },
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" },
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" }
]
......
......@@ -15,13 +15,13 @@
],
"endure": [
{
"action": "click_element",
"action": "javascript_click",
"xpath": "//span[@email]"
},
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "seconds": 1 },
{
"action": "click_element",
"action": "javascript_click",
"selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#inbox\"]"
},
{ "action": "wait", "condition": "href_change" },
......
......@@ -15,13 +15,13 @@
],
"endure": [
{
"action": "click_element",
"action": "javascript_click",
"selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#sent\"]"
},
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "seconds": 1 },
{
"action": "click_element",
"action": "javascript_click",
"selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#inbox\"]"
},
{ "action": "wait", "condition": "href_change" },
......
......@@ -20,7 +20,7 @@
{ "action": "compose_click" },
{ "action": "wait", "seconds": 1 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"oh\"][data-tooltip=\"Discard draft\"]" },
{ "action": "click_element", "selector": "div[class~=\"oh\"][data-tooltip=\"Discard draft\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"oh\"][data-tooltip=\"Discard draft\"]" },
{ "action": "wait", "seconds": 1 }
]
}
......
......@@ -12,18 +12,18 @@
"navigate_steps": [
{ "action": "navigate" },
{ "action": "wait", "condition": "element", "selector": "img[alt=\"Expand all\"]" },
{ "action": "click_element", "selector": "img[alt=\"Expand all\"]" },
{ "action": "javascript_click", "selector": "img[alt=\"Expand all\"]" },
{ "action": "wait", "seconds": 5 },
{ "action": "wait", "condition": "element", "selector": "img[alt=\"Collapse all\"]" },
{ "action": "click_element", "selector": "img[alt=\"Collapse all\"]" },
{ "action": "javascript_click", "selector": "img[alt=\"Collapse all\"]" },
{ "action": "wait", "seconds": 1 }
],
"endure": [
{ "action": "wait", "condition": "element", "selector": "img[alt=\"Expand all\"]" },
{ "action": "click_element", "selector": "img[alt=\"Expand all\"]" },
{ "action": "javascript_click", "selector": "img[alt=\"Expand all\"]" },
{ "action": "wait", "seconds": 1 },
{ "action": "wait", "condition": "element", "selector": "img[alt=\"Collapse all\"]" },
{ "action": "click_element", "selector": "img[alt=\"Collapse all\"]" },
{ "action": "javascript_click", "selector": "img[alt=\"Collapse all\"]" },
{ "action": "wait", "seconds": 1 }
]
}
......
......@@ -12,11 +12,11 @@
],
"endure": [
{ "action": "wait", "condition": "element", "selector": "button[id=\"online\"]:not(disabled)" },
{ "action": "click_element", "selector": "button[id=\"online\"]:not(disabled)" },
{ "action": "javascript_click", "selector": "button[id=\"online\"]:not(disabled)" },
{ "action": "wait", "condition": "element", "xpath": "id(\"state\")[text()=\"online\"]" },
{ "action": "wait", "seconds": 1 },
{ "action": "wait", "condition": "element", "selector": "button[id=\"offline\"]:not(disabled)" },
{ "action": "click_element", "selector": "button[id=\"offline\"]:not(disabled)" },
{ "action": "javascript_click", "selector": "button[id=\"offline\"]:not(disabled)" },
{ "action": "wait", "condition": "element", "xpath": "id(\"state\")[text()=\"offline\"]" }
]
}
......
......@@ -152,7 +152,7 @@
"navigate_steps": [
{ "action": "navigate" },
{ "action": "wait", "condition": "element", "text": "Other Answers (1 - 20 of 149)" },
{ "action": "click_element", "text": "Other Answers (1 - 20 of 149)" }
{ "action": "javascript_click", "text": "Other Answers (1 - 20 of 149)" }
]
},
{
......
......@@ -159,10 +159,10 @@
},
"toggle_drawer": [
{
"action": "click_element",
"selector": "#menu-button"
},
{ "action": "wait", "seconds": 1 }
"action": "tap",
"selector": "#menu-button",
"wait_after": { "seconds": 1 }
}
]
},
{
......
......@@ -8,12 +8,7 @@
"navigate_steps" : [
{ "action": "navigate" },
{ "action": "wait", "javascript": "window.__web_components_ready" }
],
"smoothness": {
"action": "tap_element",
"find_element_expression": "document.querySelector('pi-app').$.Topics.$.topics.$.container.querySelector('.item > .card')",
"wait_for_event": "polymer-pages-animation-end"
}
]
}
]
}
......@@ -15,10 +15,10 @@
{ "action": "wait", "condition": "element", "selector": "span[guidedhelpid=\"posts_tab_profile\"][class*=\"s6U8x\"]" }
],
"endure": [
{ "action": "click_element", "selector": "span[guidedhelpid=\"posts_tab_profile\"]" },
{ "action": "javascript_click", "selector": "span[guidedhelpid=\"posts_tab_profile\"]" },
{ "action": "wait", "condition": "element", "selector": "span[guidedhelpid=\"posts_tab_profile\"][class*=\"s6U8x\"]" },
{ "action": "wait", "seconds": 5 },
{ "action": "click_element", "selector": "span[guidedhelpid=\"photos_tab_profile\"]" },
{ "action": "javascript_click", "selector": "span[guidedhelpid=\"photos_tab_profile\"]" },
{ "action": "wait", "condition": "element", "selector": "span[guidedhelpid=\"photos_tab_profile\"][class*=\"s6U8x\"]" },
{ "action": "wait", "seconds": 5 }
]
......
......@@ -14,31 +14,31 @@
],
"stress_memory": [
{ "action": "scroll" },
{ "action": "click_element", "text": "Next" },
{ "action": "javascript_click", "text": "Next" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Next" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Next" },
{ "action": "javascript_click", "text": "Next" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Next" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Next" },
{ "action": "javascript_click", "text": "Next" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Previous" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Previous" },
{ "action": "javascript_click", "text": "Previous" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Previous" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Previous" },
{ "action": "javascript_click", "text": "Previous" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Previous" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Previous" },
{ "action": "javascript_click", "text": "Previous" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Images" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Images" },
{ "action": "javascript_click", "text": "Images" },
{ "action": "wait", "condition": "href_change" },
{ "action": "wait", "condition": "element", "text": "Images" }
]
......@@ -56,9 +56,9 @@
"scrollable_element_function": "function(callback) { gmonkey.load('2.0', function(api) { callback(api.getScrollableElement()); }); }"
},
"stress_memory": [
{ "action": "click_element", "selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#starred\"]" },
{ "action": "javascript_click", "selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#starred\"]" },
{ "action": "wait", "condition": "href_change" },
{ "action": "click_element", "selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#inbox\"]" },
{ "action": "javascript_click", "selector": "a[href=\"https://mail.google.com/mail/u/0/?shva=1#inbox\"]" },
{ "action": "wait", "condition": "href_change" }
]
},
......@@ -78,28 +78,28 @@
"scrollable_element_function": "function(callback) { callback(document.getElementById('scrolltimedeventswk')); }"
},
"stress_memory": [
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" },
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" },
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navForward\"]" },
{ "action": "click_element", "selector": "div[class~=\"navForward\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navForward\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" },
{ "action": "click_element", "selector": "div[class~=\"navBack\"]" },
{ "action": "javascript_click", "selector": "div[class~=\"navBack\"]" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "selector": "div[class~=\"navBack\"]" }
]
......@@ -137,19 +137,19 @@
"scroll_is_infinite": true
},
"stress_memory": [
{ "action": "click_element", "text": "Home" },
{ "action": "javascript_click", "text": "Home" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "text": "Profile" },
{ "action": "click_element", "text": "Profile" },
{ "action": "javascript_click", "text": "Profile" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "text": "Explore" },
{ "action": "click_element", "text": "Explore" },
{ "action": "javascript_click", "text": "Explore" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "text": "Events" },
{ "action": "click_element", "text": "Events" },
{ "action": "javascript_click", "text": "Events" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "text": "Communities" },
{ "action": "click_element", "text": "Communities" },
{ "action": "javascript_click", "text": "Communities" },
{ "action": "wait", "seconds": 2 },
{ "action": "wait", "condition": "element", "text": "Home" }
]
......@@ -172,16 +172,16 @@
{ "action": "wait", "condition": "element", "text": "accessibility" }
],
"stress_memory": [
{ "action": "click_element", "text": "accessibility" },
{ "action": "javascript_click", "text": "accessibility" },
{ "action": "wait", "condition": "navigate" },
{ "action": "scroll" },
{ "action": "click_element", "text": "advanced" },
{ "action": "javascript_click", "text": "advanced" },
{ "action": "wait", "condition": "navigate" },
{ "action": "scroll" },
{ "action": "click_element", "text": "beginner" },
{ "action": "javascript_click", "text": "beginner" },
{ "action": "wait", "condition": "navigate" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Home" },
{ "action": "javascript_click", "text": "Home" },
{ "action": "wait", "condition": "navigate" }
]
},
......@@ -195,13 +195,13 @@
],
"stress_memory": [
{ "action": "scroll" },
{ "action": "click_element", "selector": "a[href=\"http://en.blog.wordpress.com/2012/08/30/new-themes-able-and-sight/\"]" },
{ "action": "javascript_click", "selector": "a[href=\"http://en.blog.wordpress.com/2012/08/30/new-themes-able-and-sight/\"]" },
{ "action": "wait", "condition": "navigate" },
{ "action": "scroll" },
{ "action": "click_element", "text": "Features" },
{ "action": "javascript_click", "text": "Features" },
{ "action": "wait", "condition": "navigate" },
{ "action": "scroll" },
{ "action": "click_element", "text": "News" },
{ "action": "javascript_click", "text": "News" },
{ "action": "wait", "condition": "navigate" },
{ "action": "scroll" }
]
......@@ -220,17 +220,17 @@
"scroll_is_infinite": true
},
"stress_memory": [
{ "action": "click_element", "text": "About" },
{ "action": "javascript_click", "text": "About" },
{ "action": "wait", "condition": "navigate" },
{ "action": "click_element", "text": "The Audacity of Hope" },
{ "action": "javascript_click", "text": "The Audacity of Hope" },
{ "action": "wait", "condition": "navigate" },
{ "action": "click_element", "text": "Back to Barack Obama's Timeline" },
{ "action": "javascript_click", "text": "Back to Barack Obama's Timeline" },
{ "action": "wait", "condition": "navigate" },
{ "action": "click_element", "text": "About" },
{ "action": "javascript_click", "text": "About" },
{ "action": "wait", "condition": "navigate" },
{ "action": "click_element", "text": "Elected to U.S. Senate" },
{ "action": "javascript_click", "text": "Elected to U.S. Senate" },
{ "action": "wait", "condition": "navigate" },
{ "action": "click_element", "text": "Home" },
{ "action": "javascript_click", "text": "Home" },
{ "action": "wait", "condition": "navigate" }
]
},
......
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
......@@ -46,6 +46,6 @@ class ClickElementAction(page_action.PageAction):
'Cannot find element with xpath ' + self.xpath)
else:
raise page_action.PageActionFailed(
'No condition given to click_element')
'No condition given to javascript_click')
DoClick()
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from telemetry.page.actions import click_element
from telemetry.page.actions import javascript_click
from telemetry.page.actions import wait
from telemetry.unittest import tab_test_case
......@@ -15,7 +15,7 @@ class ClickElementActionTest(tab_test_case.TabTestCase):
'/page_with_link.html')
data = {'selector': 'a[id="clickme"]'}
i = click_element.ClickElementAction(data)
i = javascript_click.ClickElementAction(data)
data = {'condition': 'href_change'}
j = wait.WaitAction(data)
j.RunAction(None, self._tab, i)
......@@ -31,7 +31,7 @@ class ClickElementActionTest(tab_test_case.TabTestCase):
'/page_with_link.html')
data = {'selector': 'a[id=\'clickme\']'}
i = click_element.ClickElementAction(data)
i = javascript_click.ClickElementAction(data)
data = {'condition': 'href_change'}
j = wait.WaitAction(data)
j.RunAction(None, self._tab, i)
......@@ -47,7 +47,7 @@ class ClickElementActionTest(tab_test_case.TabTestCase):
'/page_with_link.html')
data = {'text': 'Click me'}
i = click_element.ClickElementAction(data)
i = javascript_click.ClickElementAction(data)
data = {'condition': 'href_change'}
j = wait.WaitAction(data)
j.RunAction(None, self._tab, i)
......@@ -63,7 +63,7 @@ class ClickElementActionTest(tab_test_case.TabTestCase):
'/page_with_link.html')
data = {'xpath': '//a[@id="clickme"]'}
i = click_element.ClickElementAction(data)
i = javascript_click.ClickElementAction(data)
data = {'condition': 'href_change'}
j = wait.WaitAction(data)
j.RunAction(None, self._tab, i)
......
......@@ -31,8 +31,8 @@
function TapAction(opt_callback) {
var self = this;
this.beginMeasuringHook = function() {}
this.endMeasuringHook = function() {}
this.beginMeasuringHook = function() {};
this.endMeasuringHook = function() {};
this.callback_ = opt_callback;
}
......@@ -43,10 +43,6 @@
// ensures this method will be called after the document is loaded.
this.element_ = this.options_.element_;
requestAnimationFrame(this.startPass_.bind(this));
};
TapAction.prototype.startPass_ = function() {
this.beginMeasuringHook();
var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
......@@ -54,6 +50,10 @@
rect.left + rect.width * this.options_.left_position_percentage_;
var position_top =
rect.top + rect.height * this.options_.top_position_percentage_;
if (position_left < 0 || position_left >= window.innerWidth ||
position_top < 0 || position_top >= window.innerHeight) {
throw new Error('Tap position is off-screen');
}
chrome.gpuBenchmarking.tap(position_left, position_top,
this.onGestureComplete_.bind(this),
this.options_.duration_ms_,
......
......@@ -2,10 +2,16 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
from telemetry.core import util
from telemetry.page.actions.gesture_action import GestureAction
from telemetry.page.actions import page_action
def _EscapeSelector(selector):
return selector.replace('\'', '\\\'')
class TapAction(GestureAction):
def __init__(self, attributes=None):
super(TapAction, self).__init__(attributes)
......@@ -28,6 +34,36 @@ class TapAction(GestureAction):
window.__tapAction = new __TapAction(%s);"""
% (done_callback))
def HasElementSelector(self):
return (hasattr(self, 'element_function') or hasattr(self, 'selector') or
hasattr(self, 'text') or hasattr(self, 'xpath'))
def TapSelectedElement(self, tab, js_cmd):
assert self.HasElementSelector()
if hasattr(self, 'text'):
callback_code = 'function(element) { %s }' % js_cmd
util.FindElementAndPerformAction(tab, self.text, callback_code)
else:
if hasattr(self, 'element_function'):
element_function = self.element_function
elif hasattr(self, 'selector'):
element_cmd = ('document.querySelector(\'' +
_EscapeSelector(self.selector) + '\')')
element_function = 'function(callback) { callback(%s); }' % element_cmd
elif hasattr(self, 'xpath'):
element_cmd = ('document.evaluate("%s",'
'document,'
'null,'
'XPathResult.FIRST_ORDERED_NODE_TYPE,'
'null)'
'.singleNodeValue' % re.escape(self.xpath))
element_function = 'function(callback) { callback(%s); }' % element_cmd
else:
assert False
tab.ExecuteJavaScript('(%s)(function(element) { %s });' %
(element_function, js_cmd))
def RunGesture(self, page, tab, previous_action):
left_position_percentage = 0.5
top_position_percentage = 0.5
......@@ -39,20 +75,8 @@ class TapAction(GestureAction):
top_position_percentage = self.top_position_percentage
if hasattr(self, 'duration_ms'):
duration_ms = self.duration_ms
if hasattr(self, 'element_function'):
tab.ExecuteJavaScript("""
(%s)(function(element) { window.__tapAction.start(
{ element: element,
left_position_percentage: %s,
top_position_percentage: %s,
duration_ms: %s,
gesture_source_type: %s })
});""" % (self.element_function,
left_position_percentage,
top_position_percentage,
duration_ms,
gesture_source_type))
else:
if not self.HasElementSelector():
tab.ExecuteJavaScript("""
window.__tapAction.start(
{ element: document.body,
......@@ -64,6 +88,19 @@ class TapAction(GestureAction):
top_position_percentage,
duration_ms,
gesture_source_type))
else:
js_cmd = ("""
window.__tapAction.start(
{ element: element,
left_position_percentage: %s,
top_position_percentage: %s,
duration_ms: %s,
gesture_source_type: %s });"""
% (left_position_percentage,
top_position_percentage,
duration_ms,
gesture_source_type))
self.TapSelectedElement(tab, js_cmd)
tab.WaitForJavaScriptExpression('window.__tapActionDone', 60)
......
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from telemetry.core import exceptions
from telemetry.page.actions import page_action
class TapElementAction(page_action.PageAction):
"""Page action that dispatches a custom 'tap' event at an element.
For pages that don't respond to 'click' events, this action offers
an alternative to ClickElementAction.
Configuration options:
find_element_expression: a JavaScript expression that should yield
the element to tap.
wait_for_event: an event name that will be listened for on the Document.
"""
def __init__(self, attributes=None):
super(TapElementAction, self).__init__(attributes)
def RunAction(self, page, tab, previous_action):
def DoTap():
assert hasattr(self, 'find_element_expression')
event = 'new CustomEvent("tap", {bubbles: true})'
code = '(%s).dispatchEvent(%s)' % (self.find_element_expression, event)
try:
tab.ExecuteJavaScript(code)
except exceptions.EvaluateException:
raise page_action.PageActionFailed(
'Cannot find element with code ' + self.find_element_javascript)
if hasattr(self, 'wait_for_event'):
code = ('document.addEventListener("%s", '
'function(){window.__tap_event_finished=true})')
tab.ExecuteJavaScript(code % self.wait_for_event)
DoTap()
tab.WaitForJavaScriptExpression('window.__tap_event_finished', 60)
else:
DoTap()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment