146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)# Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import logging
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport tempfile
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry import benchmark
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)from telemetry.core import bitmap
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import exceptions
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)from telemetry.core import util
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)from telemetry.core import video
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from telemetry.core.platform import tracing_category_filter
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)from telemetry.core.platform import tracing_options
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)from telemetry.timeline import model
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)from telemetry.unittest import tab_test_case
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def _IsDocumentVisible(tab):
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return not tab.EvaluateJavaScript('document.hidden || document.webkitHidden')
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FakePlatformBackend(object):
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  def __init__(self):
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    self.platform = FakePlatform()
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  def DidStartBrowser(self, _, _2):
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    pass
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  def WillCloseBrowser(self, _, _2):
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    pass
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class FakePlatform(object):
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def __init__(self):
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self._is_video_capture_running = False
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  #pylint: disable=W0613
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def StartVideoCapture(self, min_bitrate_mbps):
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self._is_video_capture_running = True
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def StopVideoCapture(self):
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self._is_video_capture_running = False
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return video.Video(tempfile.NamedTemporaryFile())
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  @property
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def is_video_capture_running(self):
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return self._is_video_capture_running
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TabTest(tab_test_case.TabTestCase):
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def testNavigateAndWaitForCompleteState(self):
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    self._tab.Navigate(self.UrlOfUnittestFile('blank.html'))
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._tab.WaitForDocumentReadyStateToBeComplete()
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def testNavigateAndWaitForInteractiveState(self):
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    self._tab.Navigate(self.UrlOfUnittestFile('blank.html'))
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testTabBrowserIsRightBrowser(self):
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertEquals(self._tab.browser, self._browser)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testRendererCrash(self):
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertRaises(exceptions.TabCrashException,
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      lambda: self._tab.Navigate('chrome://crash',
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 timeout=5))
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @benchmark.Enabled('has tabs')
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testActivateTab(self):
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    util.WaitFor(lambda: _IsDocumentVisible(self._tab), timeout=5)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_tab = self._browser.tabs.New()
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    new_tab.Navigate('about:blank')
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    util.WaitFor(lambda: _IsDocumentVisible(new_tab), timeout=5)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertFalse(_IsDocumentVisible(self._tab))
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._tab.Activate()
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    util.WaitFor(lambda: _IsDocumentVisible(self._tab), timeout=5)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertFalse(_IsDocumentVisible(new_tab))
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  def testTabUrl(self):
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    self.assertEquals(self._tab.url, 'about:blank')
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    url = self.UrlOfUnittestFile('blank.html')
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    self._tab.Navigate(url)
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    self.assertEquals(self._tab.url, url)
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def testIsTimelineRecordingRunningTab(self):
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self.assertFalse(self._tab.is_timeline_recording_running)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self._tab.StartTimelineRecording()
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self.assertTrue(self._tab.is_timeline_recording_running)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self._tab.StopTimelineRecording()
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self.assertFalse(self._tab.is_timeline_recording_running)
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  #pylint: disable=W0212
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def testIsVideoCaptureRunning(self):
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    original_platform_backend = self._tab.browser._platform_backend
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    try:
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self._tab.browser._platform_backend = FakePlatformBackend()
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self.assertFalse(self._tab.is_video_capture_running)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self._tab.StartVideoCapture(min_bitrate_mbps=2)
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self.assertTrue(self._tab.is_video_capture_running)
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self.assertIsNotNone(self._tab.StopVideoCapture())
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self.assertFalse(self._tab.is_video_capture_running)
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    finally:
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      self._tab.browser._platform_backend = original_platform_backend
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  @benchmark.Disabled('chromeos') # crbug.com/412713.
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  def testHighlight(self):
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    self.assertEquals(self._tab.url, 'about:blank')
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    options = tracing_options.TracingOptions()
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    options.enable_chrome_trace = True
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    self._browser.platform.tracing_controller.Start(
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        options, tracing_category_filter.CreateNoOverheadFilter())
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    self._tab.Highlight(bitmap.WEB_PAGE_TEST_ORANGE)
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    self._tab.ClearHighlight(bitmap.WEB_PAGE_TEST_ORANGE)
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    trace_data = self._browser.platform.tracing_controller.Stop()
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    timeline_model = model.TimelineModel(trace_data)
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    renderer_thread = timeline_model.GetRendererThreadFromTabId(
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        self._tab.id)
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    found_video_start_event = False
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    for event in renderer_thread.async_slices:
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      if event.name == '__ClearHighlight.video_capture_start':
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        found_video_start_event = True
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        break
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    self.assertTrue(found_video_start_event)
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @benchmark.Enabled('has tabs')
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  @benchmark.Disabled('chromeos') # crbug.com/412713.
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  def testGetRendererThreadFromTabId(self):
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    self.assertEquals(self._tab.url, 'about:blank')
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    # Create 3 tabs. The third tab is closed before we call
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    # tracing_controller.Start.
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    first_tab = self._tab
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab = self._browser.tabs.New()
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab.Navigate('about:blank')
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    third_tab = self._browser.tabs.New()
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    third_tab.Navigate('about:blank')
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    third_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    third_tab.Close()
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    options = tracing_options.TracingOptions()
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    options.enable_chrome_trace = True
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    self._browser.platform.tracing_controller.Start(
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        options, tracing_category_filter.CreateNoOverheadFilter())
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    first_tab.ExecuteJavaScript('console.time("first-tab-marker");')
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    first_tab.ExecuteJavaScript('console.timeEnd("first-tab-marker");')
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab.ExecuteJavaScript('console.time("second-tab-marker");')
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab.ExecuteJavaScript('console.timeEnd("second-tab-marker");')
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    trace_data = self._browser.platform.tracing_controller.Stop()
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    timeline_model = model.TimelineModel(trace_data)
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    # Assert that the renderer_thread of the first tab contains
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    # 'first-tab-marker'.
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    renderer_thread = timeline_model.GetRendererThreadFromTabId(
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        first_tab.id)
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    first_tab_markers = [
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        renderer_thread.IterAllSlicesOfName('first-tab-marker')]
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    self.assertEquals(1, len(first_tab_markers))
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    # Close second tab and assert that the renderer_thread of the second tab
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    # contains 'second-tab-marker'.
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab.Close()
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    renderer_thread = timeline_model.GetRendererThreadFromTabId(
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        second_tab.id)
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    second_tab_markers = [
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        renderer_thread.IterAllSlicesOfName('second-tab-marker')]
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    self.assertEquals(1, len(second_tab_markers))
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    # Third tab wasn't available when we start tracing, so there is no
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    # renderer_thread corresponding to it in the the trace.
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    self.assertIs(None, timeline_model.GetRendererThreadFromTabId(third_tab.id))
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GpuTabTest(tab_test_case.TabTestCase):
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @classmethod
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def CustomizeBrowserOptions(cls, options):
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  # Test flaky on mac: http://crbug.com/358664
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @benchmark.Disabled('android', 'mac')
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testScreenshot(self):
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if not self._tab.screenshot_supported:
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      logging.warning('Browser does not support screenshots, skipping test.')
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self.Navigate('green_rect.html')
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pixel_ratio = self._tab.EvaluateJavaScript('window.devicePixelRatio || 1')
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot = self._tab.Screenshot(5)
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert screenshot
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot.GetPixelColor(0 * pixel_ratio, 0 * pixel_ratio).AssertIsRGB(
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        0, 255, 0, tolerance=2)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot.GetPixelColor(31 * pixel_ratio, 31 * pixel_ratio).AssertIsRGB(
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        0, 255, 0, tolerance=2)
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot.GetPixelColor(32 * pixel_ratio, 32 * pixel_ratio).AssertIsRGB(
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        255, 255, 255, tolerance=2)
195