1 # Copyright 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 5 """Runs a Google Maps pixel test. 6 Performs several common navigation actions on the map (pan, zoom, rotate) then 7 captures a screenshot and compares selected pixels against expected values""" 8 9 import json 10 import optparse 11 import os 12 13 import cloud_storage_test_base 14 import maps_expectations 15 16 from telemetry import benchmark 17 from telemetry.core import bitmap 18 from telemetry.core import util 19 from telemetry.page import page 20 from telemetry.page import page_set 21 from telemetry.page import page_test 22 23 class _MapsValidator(cloud_storage_test_base.ValidatorBase): 24 def CustomizeBrowserOptions(self, options): 25 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') 26 27 def ValidateAndMeasurePage(self, page, tab, results): 28 # TODO: This should not be necessary, but it's not clear if the test is 29 # failing on the bots in it's absence. Remove once we can verify that it's 30 # safe to do so. 31 _MapsValidator.SpinWaitOnRAF(tab, 3) 32 33 if not tab.screenshot_supported: 34 raise page_test.Failure('Browser does not support screenshot capture') 35 screenshot = tab.Screenshot(5) 36 if not screenshot: 37 raise page_test.Failure('Could not capture screenshot') 38 39 dpr = tab.EvaluateJavaScript('window.devicePixelRatio') 40 expected = self._ReadPixelExpectations(page) 41 self._ValidateScreenshotSamples( 42 page.display_name, screenshot, expected, dpr) 43 44 @staticmethod 45 def SpinWaitOnRAF(tab, iterations, timeout = 60): 46 waitScript = r""" 47 window.__spinWaitOnRAFDone = false; 48 var iterationsLeft = %d; 49 50 function spin() { 51 iterationsLeft--; 52 if (iterationsLeft == 0) { 53 window.__spinWaitOnRAFDone = true; 54 return; 55 } 56 window.requestAnimationFrame(spin); 57 } 58 window.requestAnimationFrame(spin); 59 """ % iterations 60 61 def IsWaitComplete(): 62 return tab.EvaluateJavaScript('window.__spinWaitOnRAFDone') 63 64 tab.ExecuteJavaScript(waitScript) 65 util.WaitFor(IsWaitComplete, timeout) 66 67 def _ReadPixelExpectations(self, page): 68 expectations_path = os.path.join(page._base_dir, page.pixel_expectations) 69 with open(expectations_path, 'r') as f: 70 json_contents = json.load(f) 71 return json_contents 72 73 74 class MapsPage(page.Page): 75 def __init__(self, page_set, base_dir): 76 super(MapsPage, self).__init__( 77 url='http://localhost:10020/tracker.html', 78 page_set=page_set, 79 base_dir=base_dir, 80 name='Maps.maps_002') 81 self.pixel_expectations = 'data/maps_002_expectations.json' 82 83 def RunNavigateSteps(self, action_runner): 84 action_runner.NavigateToPage(self) 85 action_runner.WaitForJavaScriptCondition( 86 'window.testDone', timeout_in_seconds=180) 87 88 89 class Maps(cloud_storage_test_base.TestBase): 90 """Google Maps pixel tests.""" 91 test = _MapsValidator 92 93 def CreateExpectations(self, page_set): 94 return maps_expectations.MapsExpectations() 95 96 def CreatePageSet(self, options): 97 page_set_path = os.path.join( 98 util.GetChromiumSrcDir(), 'content', 'test', 'gpu', 'page_sets') 99 ps = page_set.PageSet(archive_data_file='data/maps.json', 100 make_javascript_deterministic=False, 101 file_path=page_set_path, 102 bucket=page_set.PUBLIC_BUCKET) 103 ps.AddPage(MapsPage(ps, ps.base_dir)) 104 return ps 105