| Index: content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
|
| diff --git a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..43c63ebc018387f7e8687925e53d620524a93770
|
| --- /dev/null
|
| +++ b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
|
| @@ -0,0 +1,135 @@
|
| +# Copyright 2017 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
|
| +import os
|
| +import random
|
| +
|
| +from gpu_tests import gpu_integration_test
|
| +from gpu_tests import path_util
|
| +from gpu_tests import screenshot_sync_expectations
|
| +
|
| +from telemetry.util import image_util
|
| +from telemetry.util import rgba_color
|
| +
|
| +data_path = os.path.join(
|
| + path_util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu')
|
| +
|
| +class ScreenshotSyncIntegrationTest(gpu_integration_test.GpuIntegrationTest):
|
| + """Tests that screenshots are properly synchronized with the frame on
|
| + which they were requested.
|
| + """
|
| +
|
| + # We store a deep copy of the original browser finder options in
|
| + # order to be able to restart the browser multiple times, with a
|
| + # different set of command line arguments each time.
|
| + _original_finder_options = None
|
| +
|
| + # We keep track of the set of command line arguments used to launch
|
| + # the browser most recently in order to figure out whether we need
|
| + # to relaunch it, if a new pixel test requires a different set of
|
| + # arguments.
|
| + _last_launched_browser_args = set()
|
| +
|
| + @classmethod
|
| + def Name(cls):
|
| + """The name by which this test is invoked on the command line."""
|
| + return 'screenshot_sync'
|
| +
|
| + @classmethod
|
| + def setUpClass(cls):
|
| + super(cls, ScreenshotSyncIntegrationTest).setUpClass()
|
| + cls._original_finder_options = cls._finder_options.Copy()
|
| + cls.CustomizeBrowserArgs([])
|
| + cls.StartBrowser()
|
| + cls.SetStaticServerDirs([data_path])
|
| +
|
| + @classmethod
|
| + def CustomizeBrowserArgs(cls, browser_args):
|
| + if not browser_args:
|
| + browser_args = []
|
| + cls._finder_options = cls._original_finder_options.Copy()
|
| + browser_options = cls._finder_options.browser_options
|
| + # All tests receive the following options. They aren't recorded in
|
| + # the _last_launched_browser_args.
|
| + #
|
| + # --test-type=gpu is used only to suppress the "Google API Keys are missing"
|
| + # infobar, which causes flakiness in tests.
|
| + browser_options.AppendExtraBrowserArgs(['--test-type=gpu'])
|
| + # Append the new arguments.
|
| + browser_options.AppendExtraBrowserArgs(browser_args)
|
| + cls._last_launched_browser_args = set(browser_args)
|
| + cls.SetBrowserOptions(cls._finder_options)
|
| +
|
| + @classmethod
|
| + def RestartBrowserIfNecessaryWithArgs(cls, browser_args):
|
| + if not browser_args:
|
| + browser_args = []
|
| + if set(browser_args) != cls._last_launched_browser_args:
|
| + logging.info('Restarting browser with arguments: ' + str(browser_args))
|
| + cls.StopBrowser()
|
| + cls.CustomizeBrowserArgs(browser_args)
|
| + cls.StartBrowser()
|
| + cls.tab = cls.browser.tabs[0]
|
| +
|
| + @classmethod
|
| + def _CreateExpectations(cls):
|
| + return screenshot_sync_expectations.ScreenshotSyncExpectations()
|
| +
|
| + @classmethod
|
| + def GenerateGpuTests(cls, options):
|
| + yield('ScreenshotSync_SWRasterWithCanvas',
|
| + 'screenshot_sync_canvas.html',
|
| + ('--disable-gpu-rasterization'))
|
| + yield('ScreenshotSync_SWRasterWithDivs',
|
| + 'screenshot_sync_divs.html',
|
| + ('--disable-gpu-rasterization'))
|
| + yield('ScreenshotSync_GPURasterWithCanvas',
|
| + 'screenshot_sync_canvas.html',
|
| + ('--force-gpu-rasterization'))
|
| + yield('ScreenshotSync_GPURasterWithDivs',
|
| + 'screenshot_sync_divs.html',
|
| + ('--force-gpu-rasterization'))
|
| +
|
| + def _Navigate(self, test_path):
|
| + url = self.UrlOfStaticFilePath(test_path)
|
| + # It's crucial to use the action_runner, rather than the tab's
|
| + # Navigate method directly. It waits for the document ready state
|
| + # to become interactive or better, avoiding critical race
|
| + # conditions.
|
| + self.tab.action_runner.Navigate(url)
|
| +
|
| + def _CheckColorMatchAtLocation(self, expectedRGB, screenshot, x, y):
|
| + pixel_value = image_util.GetPixelColor(screenshot, x, y)
|
| + if not expectedRGB.IsEqual(pixel_value):
|
| + error_message = ('Color mismatch at (%d, %d): expected (%d, %d, %d), ' +
|
| + 'got (%d, %d, %d)') % (
|
| + x, y, expectedRGB.r, expectedRGB.g, expectedRGB.b,
|
| + pixel_value.r, pixel_value.g, pixel_value.b)
|
| + self.fail(error_message)
|
| +
|
| + def _CheckScreenshot(self):
|
| + canvasRGB = rgba_color.RgbaColor(random.randint(0, 255),
|
| + random.randint(0, 255),
|
| + random.randint(0, 255),
|
| + 255)
|
| + tab = self.tab
|
| + tab.EvaluateJavaScript("window.draw(%d, %d, %d);" % (
|
| + canvasRGB.r, canvasRGB.g, canvasRGB.b))
|
| + screenshot = tab.Screenshot(5)
|
| + start_x = 10
|
| + start_y = 0
|
| + outer_size = 256
|
| + skip = 10
|
| + for y in range(start_y, outer_size, skip):
|
| + for x in range(start_x, outer_size, skip):
|
| + self._CheckColorMatchAtLocation(canvasRGB, screenshot, x, y)
|
| +
|
| + def RunActualGpuTest(self, test_path, *args):
|
| + browser_arg = args[0]
|
| + self.RestartBrowserIfNecessaryWithArgs([browser_arg])
|
| + self._Navigate(test_path)
|
| + repetitions = 20
|
| + for _ in range(0, repetitions):
|
| + self._CheckScreenshot()
|
|
|