1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch# Copyright 2014 The Chromium Authors. All rights reserved.
2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch# Use of this source code is governed by a BSD-style license that can be
3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch# found in the LICENSE file.
4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport json
6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport logging
7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport os
8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom distutils.version import LooseVersion
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom PIL import Image
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom common import cloud_bucket
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom common import ispy_utils
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass ISpyApi(object):
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  """The public API for interacting with ISpy."""
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def __init__(self, cloud_bucket):
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Initializes the utility class.
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      cloud_bucket: a BaseCloudBucket in which to the version file,
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          expectations and results are to be stored.
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._cloud_bucket = cloud_bucket
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._ispy = ispy_utils.ISpyUtils(self._cloud_bucket)
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._rebaselineable_cache = {}
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def UpdateExpectationVersion(self, chrome_version, version_file):
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Updates the most recent expectation version to the Chrome version.
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Should be called after generating a new set of expectations.
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version as a string of the form "31.0.123.4".
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      version_file: path to the version file in the cloud bucket. The version
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          file contains a json list of ordered Chrome versions for which
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          expectations exist.
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    insert_pos = 0
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    expectation_versions = []
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    try:
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      expectation_versions = self._GetExpectationVersionList(version_file)
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      if expectation_versions:
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        try:
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          version = self._GetExpectationVersion(
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              chrome_version, expectation_versions)
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          if version == chrome_version:
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            return
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          insert_pos = expectation_versions.index(version)
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        except:
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          insert_pos = len(expectation_versions)
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    except cloud_bucket.FileNotFoundError:
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      pass
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    expectation_versions.insert(insert_pos, chrome_version)
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    logging.info('Updating expectation version...')
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._cloud_bucket.UploadFile(
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        version_file, json.dumps(expectation_versions),
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        'application/json')
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def _GetExpectationVersion(self, chrome_version, expectation_versions):
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Returns the expectation version for the given Chrome version.
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version as a string of the form "31.0.123.4".
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      expectation_versions: Ordered list of Chrome versions for which
67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        expectations exist, as stored in the version file.
68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Returns:
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Expectation version string.
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    # Find the closest version that is not greater than the chrome version.
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    for version in expectation_versions:
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      if LooseVersion(version) <= LooseVersion(chrome_version):
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return version
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    raise Exception('No expectation exists for Chrome %s' % chrome_version)
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def _GetExpectationVersionList(self, version_file):
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Gets the list of expectation versions from google storage.
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      version_file: path to the version file in the cloud bucket. The version
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          file contains a json list of ordered Chrome versions for which
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          expectations exist.
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Returns:
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Ordered list of Chrome versions.
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    try:
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return json.loads(self._cloud_bucket.DownloadFile(version_file))
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    except:
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return []
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def _GetExpectationNameWithVersion(self, device_type, expectation,
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                     chrome_version, version_file):
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Get the expectation to be used with the current Chrome version.
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      device_type: string identifier for the device type.
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      expectation: name for the expectation to generate.
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version as a string of the form "31.0.123.4".
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Returns:
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Version as an integer.
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    version = self._GetExpectationVersion(
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        chrome_version, self._GetExpectationVersionList(version_file))
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return self._CreateExpectationName(device_type, expectation, version)
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def _CreateExpectationName(self, device_type, expectation, version):
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Create the full expectation name from the expectation and version.
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      device_type: string identifier for the device type, example: mako
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      expectation: base name for the expectation, example: google.com
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      version: expectation version, example: 31.0.23.1
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Returns:
119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Full expectation name as a string, example: mako:google.com(31.0.23.1)
120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return '%s:%s(%s)' % (device_type, expectation, version)
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def GenerateExpectation(self, device_type, expectation, chrome_version,
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                          version_file, screenshots):
125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Create an expectation for I-Spy.
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      device_type: string identifier for the device type.
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      expectation: name for the expectation to generate.
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version as a string of the form "31.0.123.4".
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      screenshots: a list of similar PIL.Images.
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    # https://code.google.com/p/chromedriver/issues/detail?id=463
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    expectation_with_version = self._CreateExpectationName(
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        device_type, expectation, chrome_version)
136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if self._ispy.ExpectationExists(expectation_with_version):
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      logging.warning(
138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          'I-Spy expectation \'%s\' already exists, overwriting.',
139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          expectation_with_version)
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    logging.info('Generating I-Spy expectation...')
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._ispy.GenerateExpectation(expectation_with_version, screenshots)
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def PerformComparison(self, test_run, device_type, expectation,
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                        chrome_version, version_file, screenshot):
145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Compare a screenshot with the given expectation in I-Spy.
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      test_run: name for the test run.
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      device_type: string identifier for the device type.
150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      expectation: name for the expectation to compare against.
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version as a string of the form "31.0.123.4".
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      screenshot: a PIL.Image to compare.
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    # https://code.google.com/p/chromedriver/issues/detail?id=463
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    logging.info('Performing I-Spy comparison...')
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._ispy.PerformComparison(
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        test_run,
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        self._GetExpectationNameWithVersion(
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            device_type, expectation, chrome_version, version_file),
160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        screenshot)
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def CanRebaselineToTestRun(self, test_run):
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Returns whether the test run has associated expectations.
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Returns:
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      True if RebaselineToTestRun() can be called for this test run.
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if test_run in self._rebaselineable_cache:
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return True
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return self._cloud_bucket.FileExists(
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ispy_utils.GetTestRunPath(test_run, 'rebaseline.txt'))
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def RebaselineToTestRun(self, test_run):
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Update the version file to use expectations associated with |test_run|.
175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      test_run: The name of the test run to rebaseline.
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    rebaseline_path = ispy_utils.GetTestRunPath(test_run, 'rebaseline.txt')
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    rebaseline_attrib = json.loads(
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        self._cloud_bucket.DownloadFile(rebaseline_path))
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self.UpdateExpectationVersion(
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        rebaseline_attrib['version'], rebaseline_attrib['version_file'])
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._cloud_bucket.RemoveFile(rebaseline_path)
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def _SetTestRunRebaselineable(self, test_run, chrome_version, version_file):
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Writes a JSON file containing the data needed to rebaseline.
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      test_run: The name of the test run to add the rebaseline file to.
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version that can be rebaselined to (must have
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        associated Expectations).
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      version_file: the path of the version file associated with the test run.
194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._rebaselineable_cache[test_run] = True
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._cloud_bucket.UploadFile(
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ispy_utils.GetTestRunPath(test_run, 'rebaseline.txt'),
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        json.dumps({
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            'version': chrome_version,
200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            'version_file': version_file}),
201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        'application/json')
202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  def PerformComparisonAndPrepareExpectation(self, test_run, device_type,
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                             expectation, chrome_version,
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                             version_file, screenshots):
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """Perform comparison and generate an expectation that can used later.
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    The test run web UI will have a button to set the Expectations generated for
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    this version as the expectation for comparison with later versions.
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Args:
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      test_run: The name of the test run to add the rebaseline file to.
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      device_type: string identifier for the device type.
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      chrome_version: the chrome version that can be rebaselined to (must have
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        associated Expectations).
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      version_file: the path of the version file associated with the test run.
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      screenshot: a list of similar PIL.Images.
218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    """
219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if not self.CanRebaselineToTestRun(test_run):
220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      self._SetTestRunRebaselineable(test_run, chrome_version, version_file)
221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    expectation_with_version = self._CreateExpectationName(
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        device_type, expectation, chrome_version)
223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._ispy.GenerateExpectation(expectation_with_version, screenshots)
224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._ispy.PerformComparison(
225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        test_run,
226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        self._GetExpectationNameWithVersion(
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            device_type, expectation, chrome_version, version_file),
228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        screenshots[-1])
229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
230