| Index: tools/perf/page_sets/maps_earth.py
|
| diff --git a/tools/perf/page_sets/maps_earth.py b/tools/perf/page_sets/maps_earth.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7ca0fc4c607b2d254fda72ddd50c8cae4584c88f
|
| --- /dev/null
|
| +++ b/tools/perf/page_sets/maps_earth.py
|
| @@ -0,0 +1,217 @@
|
| +# Copyright 2015 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.
|
| +
|
| +import logging
|
| +
|
| +from telemetry.page import page
|
| +from telemetry.page import page_set
|
| +
|
| +
|
| +_MOVE_GOOGLE_MAPS_JS = """
|
| +/**
|
| + * Issues/dispatches keyboard event to target element.
|
| + * @param {element} target Target element.
|
| + * @param {string} eventType One of 'keyup', 'keydown', 'keypress'.
|
| + * @param {number} keyCode Key code.
|
| + */
|
| +function issueKeyEvent(target, eventType, keyCode) {
|
| + var event = document.createEventObject ?
|
| + document.createEventObject() : document.createEvent('Events');
|
| +
|
| + if (event.initEvent) {
|
| + event.initEvent(eventType, true, true);
|
| + }
|
| +
|
| + event.keyCode = keyCode;
|
| + event.which = keyCode;
|
| +
|
| + target.dispatchEvent ?
|
| + target.dispatchEvent(event) : target.fireEvent('on' + eventType, event);
|
| +}
|
| +
|
| +// Map keyboard shortcut to key code mapping.
|
| +var MAP_KEYBOARD = {
|
| + LEFT: 37,
|
| + UP: 38,
|
| + RIGHT: 39,
|
| + DOWN: 40,
|
| + ZOOM_IN: 187,
|
| + ZOOM_OUT: 189
|
| +};
|
| +
|
| +// The scene canvas is the first one on the page apparently. The 2nd one is the
|
| +// minimap. I'd rely on the canvas ordering instead of the class since Tactile's
|
| +// obfuscating classes soon.
|
| +var sceneCanvas = document.querySelector('canvas');
|
| +
|
| +/**
|
| + * Moves Google maps.
|
| + * @param {string} action Action defined in MAP_KEYBOARD.
|
| + * @param {number} duration_msecs Duration (in ms) of the action.
|
| + */
|
| +function moveMap(action, duration_msecs) {
|
| + keycode = MAP_KEYBOARD[action];
|
| + issueKeyEvent(sceneCanvas, 'keydown', keycode);
|
| + setTimeout(function() {issueKeyEvent(sceneCanvas, 'keyup', keycode);},
|
| + duration_msecs);
|
| +}
|
| +
|
| +/**
|
| + * Creates and dispatches mouse event.
|
| + * @param {object} target DOM element to dispatch event to.
|
| + * @param {string} eventType Mouse event, one of 'mousedown', 'mouseup',
|
| + * 'mousemove' event.
|
| + * @param {number} x clientX position.
|
| + * @param {number} y clientY position.
|
| + * @param {number} delay Milliseconds delay to dispatch the event.
|
| + */
|
| +function dispatchMouseEvent(target, eventType, x, y, delay) {
|
| + setTimeout(function() {
|
| + /* TODO(deanliao): investigate why the new MouseEvent creator won't work.
|
| + var button = eventType == 'mouseup' ? -1 : 0;
|
| + var event = new MouseEvent(
|
| + eventType,
|
| + {clientX: x,
|
| + clientY: y,
|
| + button: button});
|
| + */
|
| +
|
| + var event = document.createEvent('MouseEvents');
|
| + var detail = eventType == 'mousemove' ? 0 : 1;
|
| + event.initMouseEvent(eventType, true, true, window,
|
| + detail, x, y, x, y);
|
| +
|
| + target.dispatchEvent(event);
|
| +
|
| + }, delay);
|
| +}
|
| +
|
| +
|
| +/**
|
| + * Drag-n-drops mouse linearly for a while.
|
| + * @param {object} target DOM element to dispatch event to.
|
| + * @param {number} startX Starting clientX position.
|
| + * @param {number} startY Starting clientY position.
|
| + * @param {number} endX Starting clientX position.
|
| + * @param {number} endY Starting clientY position.
|
| + * @param {number} duration Drag for milliseconds.
|
| + */
|
| +function linearMouseDragDrop(target, startX, startY, endX, endY, duration) {
|
| + var interval = 10;
|
| + var numSteps = Math.floor(duration / interval) - 1;
|
| + var deltaX = (endX - startX) / numSteps;
|
| + var deltaY = (endY - startY) / numSteps;
|
| + var x = startX;
|
| + var y = startY;
|
| + var delay = 0;
|
| + dispatchMouseEvent(target, 'mousedown', x, y, delay);
|
| + for (i = 1; i < numSteps; i++) {
|
| + x = Math.floor(startX + i * deltaX);
|
| + y = Math.floor(startY + i * deltaY);
|
| + delay += interval;
|
| + dispatchMouseEvent(target, 'mousemove', x, y, delay);
|
| + }
|
| + dispatchMouseEvent(target, 'mouseup', endX, endY, delay + interval);
|
| +}
|
| +"""
|
| +
|
| +
|
| +class MapsEarthPage(page.Page):
|
| + """Page for surfing Google Maps with Earth layer."""
|
| +
|
| + _MAP_MODE_SWITCHER = '.widget-minimap-shim-button'
|
| + _START_END_COORD = {
|
| + 'LEFT': (700, 380, 20, 380),
|
| + 'RIGHT': (20, 380, 700, 380),
|
| + 'UP': (500, 600, 500, 20),
|
| + 'DOWN': (500, 20, 500, 600)}
|
| +
|
| + def __init__(self, parent_page_set, url, page_name, map_load_wait_secs=10,
|
| + drag_duration_ms=500):
|
| + super(MapsEarthPage, self).__init__(
|
| + url=url,
|
| + page_set=parent_page_set,
|
| + name=page_name)
|
| + self._map_load_wait_sec = map_load_wait_secs
|
| + self._drag_duration_ms = drag_duration_ms
|
| +
|
| + def CanRunOnBrowser(self, browser_info):
|
| + if not browser_info.HasWebGLSupport():
|
| + logging.warning('Browser does not support webgl, skipping test')
|
| + return False
|
| + return True
|
| +
|
| + def RunNavigateSteps(self, action_runner):
|
| + super(MapsEarthPage, self).RunNavigateSteps(action_runner)
|
| + logging.info('Wait for Google Maps mode switcher')
|
| + action_runner.WaitForElement(selector=self._MAP_MODE_SWITCHER)
|
| + logging.info('Loaded. Wait for %d more seconds...' %
|
| + self._map_load_wait_sec)
|
| + action_runner.Wait(self._map_load_wait_sec)
|
| + self.PrepareInteraction(action_runner)
|
| +
|
| + def MouseDrag(self, action_runner, direction, duration_ms):
|
| + """Drags mouse on the map.
|
| +
|
| + Args:
|
| + action_runner: Telemetry action runner.
|
| + direction: Drag direction. One of 'UP', 'DOWN', 'LEFT', 'RIGHT'.
|
| + duration_ms: Duration of the drag.
|
| + """
|
| + if direction not in self._START_END_COORD:
|
| + logging.error('Invalid direction %r. Should be one of %r', direction,
|
| + self._START_END_COORD.keys())
|
| + return
|
| + start_end_coord = ', '.join(
|
| + str(x) for x in self._START_END_COORD[direction])
|
| + js = 'linearMouseDragDrop(sceneCanvas, %s, %d);' % (start_end_coord,
|
| + duration_ms)
|
| + logging.info('MouseDrag %s for %d ms. Execute %s', direction, duration_ms,
|
| + js)
|
| + action_runner.ExecuteJavaScript(js)
|
| + action_runner.Wait(duration_ms / 1000.0 + 0.2)
|
| +
|
| + def RunPageInteractions(self, action_runner):
|
| + logging.info('RunPageInteractions')
|
| + for action in ['DOWN', 'LEFT', 'LEFT', 'UP', 'RIGHT', 'RIGHT', 'UP',
|
| + 'LEFT', 'LEFT', 'UP', 'RIGHT', 'RIGHT', 'UP', 'LEFT',
|
| + 'LEFT']:
|
| + self.MouseDrag(action_runner, action, self._drag_duration_ms)
|
| +
|
| + # TODO(deanliao): figure out why keyboard event doesn't work.
|
| + # for action in
|
| + # logging.info('moveMap ' + action)
|
| + # action_runner.ExecuteJavaScript(
|
| + # "moveMap('%s', %d);" % (action, self._KEYDOWN_MSEC))
|
| + # action_runner.Wait(self._ACTION_INTERVAL_SECS)
|
| +
|
| + def PrepareInteraction(self, action_runner):
|
| + action_runner.ExecuteJavaScript(_MOVE_GOOGLE_MAPS_JS)
|
| + logging.info('_MOVE_GOOGLE_MAPS_JS injected.')
|
| +
|
| +
|
| +class MapsEarthPageSet(page_set.PageSet):
|
| + """Page set for Google Maps with Earth layer."""
|
| +
|
| + def __init__(self):
|
| + super(MapsEarthPageSet, self).__init__(
|
| + archive_data_file='data/maps_earth.json',
|
| + bucket=page_set.PUBLIC_BUCKET)
|
| +
|
| + self.AddUserStory(
|
| + MapsEarthPage(
|
| + self,
|
| + 'https://www.google.com/maps/@37.7502889,-122.4791582,15z',
|
| + 'Maps.SanFrancisco',
|
| + map_load_wait_secs=3,
|
| + drag_duration_ms=1500))
|
| +
|
| + # Temporary disable Earth test as it doesn't run smooth yet.
|
| + # self.AddUserStory(
|
| + # MapsEarthPage(
|
| + # self,
|
| + # 'https://goo.gl/maps/NRtaW',
|
| + # 'Maps.SanFranciscoEarth',
|
| + # map_load_wait_secs=10,
|
| + # drag_duration_ms=2000))
|
|
|