OLD | NEW |
---|---|
(Empty) | |
1 # Copyright (c) 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 import json | |
6 import logging | |
7 import os | |
8 import time | |
9 from distutils.version import LooseVersion | |
10 from PIL import Image | |
11 | |
12 from ..common import cloud_bucket | |
13 from ..common import ispy_utils | |
14 | |
15 | |
16 class ChromeUtils(object): | |
17 """A utility for using ISpy with Chrome.""" | |
18 | |
19 def __init__(self, cloud_bucket, version_file, screenshot_func): | |
20 """Initializes the utility class. | |
21 | |
22 Args: | |
23 cloud_bucket: a BaseCloudBucket in which to the version file, | |
24 expectations and results are to be stored. | |
25 version_file: path to the version file in the cloud bucket. The version | |
26 file contains a json list of ordered Chrome versions for which | |
27 expectations exist. | |
28 screenshot_func: a function that returns a PIL.Image. | |
29 """ | |
30 self._cloud_bucket = cloud_bucket | |
31 self._version_file = version_file | |
32 self._screenshot_func = screenshot_func | |
33 self._ispy = ispy_utils.ISpyUtils(self._cloud_bucket) | |
34 with open( | |
35 os.path.join(os.path.dirname(__file__), 'wait_on_ajax.js'), 'r') as f: | |
36 self._wait_for_unchanging_dom_script = f.read() | |
37 | |
38 def UpdateExpectationVersion(self, chrome_version): | |
39 """Updates the most recent expectation version to the Chrome version. | |
40 | |
41 Should be called after generating a new set of expectations. | |
42 | |
43 Args: | |
44 chrome_version: the chrome version as a string of the form "31.0.123.4". | |
45 """ | |
46 insert_pos = 0 | |
47 expectation_versions = [] | |
48 try: | |
49 expectation_versions = self._GetExpectationVersionList() | |
50 if expectation_versions: | |
51 try: | |
52 version = self._GetExpectationVersion( | |
53 chrome_version, expectation_versions) | |
54 if version == chrome_version: | |
55 return | |
56 insert_pos = expectation_versions.index(version) | |
57 except: | |
58 insert_pos = len(expectation_versions) | |
59 except cloud_bucket.FileNotFoundError: | |
60 pass | |
61 expectation_versions.insert(insert_pos, chrome_version) | |
62 logging.info('Updating expectation version...') | |
63 self._cloud_bucket.UploadFile( | |
64 self._version_file, json.dumps(expectation_versions), | |
65 'application/json') | |
66 | |
67 def _GetExpectationVersion(self, chrome_version, expectation_versions): | |
68 """Returns the expectation version for the given Chrome version. | |
69 | |
70 Args: | |
71 chrome_version: the chrome version as a string of the form "31.0.123.4". | |
72 expectation_versions: Ordered list of Chrome versions for which | |
73 expectations exist, as stored in the version file. | |
74 | |
75 Returns: | |
76 Expectation version string. | |
77 """ | |
78 # Find the closest version that is not greater than the chrome version. | |
79 for version in expectation_versions: | |
80 if LooseVersion(version) <= LooseVersion(chrome_version): | |
81 return version | |
82 raise Exception('No expectation exists for Chrome %s' % chrome_version) | |
83 | |
84 def _GetExpectationVersionList(self): | |
85 """Gets the list of expectation versions from google storage.""" | |
86 return json.loads(self._cloud_bucket.DownloadFile(self._version_file)) | |
87 | |
88 def _GetExpectationNameWithVersion(self, device_type, expectation, | |
89 chrome_version): | |
90 """Get the expectation to be used with the current Chrome version. | |
91 | |
92 Args: | |
93 device_type: string identifier for the device type. | |
94 expectation: name for the expectation to generate. | |
95 chrome_version: the chrome version as a string of the form "31.0.123.4". | |
96 | |
97 Returns: | |
98 Version as an integer. | |
99 """ | |
100 version = self._GetExpectationVersion( | |
101 chrome_version, self._GetExpectationVersionList()) | |
102 return self._CreateExpectationName(device_type, expectation, version) | |
103 | |
104 def _CreateExpectationName(self, device_type, expectation, version): | |
105 """Create the full expectation name from the expectation and version. | |
frankf
2013/11/06 23:47:26
Provide examples for all args and return value
craigdh
2013/11/07 00:06:16
Done.
| |
106 | |
107 Args: | |
108 device_type: string identifier for the device type. | |
109 expectation: name for the expectation to generate. | |
110 version: expectation version. | |
111 | |
112 Returns: | |
113 Full expectation name as a string. | |
114 """ | |
115 return '%s:%s(%s)' % (device_type, expectation, version) | |
116 | |
117 def GenerateExpectation(self, device_type, expectation, chrome_version): | |
118 """Take screenshots and store as an expectation in I-Spy. | |
119 | |
120 Args: | |
121 device_type: string identifier for the device type. | |
122 expectation: name for the expectation to generate. | |
123 chrome_version: the chrome version as a string of the form "31.0.123.4". | |
124 """ | |
125 # https://code.google.com/p/chromedriver/issues/detail?id=463 | |
126 time.sleep(1) | |
127 expectation_with_version = self._CreateExpectationName( | |
128 device_type, expectation, chrome_version) | |
129 if self._ispy.ExpectationExists(expectation_with_version): | |
130 logging.warning( | |
131 'I-Spy expectation \'%s\' already exists, overwriting.', | |
132 expectation_with_version) | |
133 screenshots = [self._screenshot_func() for _ in range(8)] | |
134 logging.info('Generating I-Spy expectation...') | |
135 self._ispy.GenerateExpectation(expectation_with_version, screenshots) | |
136 | |
137 def PerformComparison(self, test_run, device_type, expectation, | |
138 chrome_version): | |
139 """Take a screenshot and compare it with the given expectation in I-Spy. | |
140 | |
141 Args: | |
142 test_run: name for the test run. | |
143 device_type: string identifier for the device type. | |
144 expectation: name for the expectation to compare against. | |
145 chrome_version: the chrome version as a string of the form "31.0.123.4". | |
146 """ | |
147 # https://code.google.com/p/chromedriver/issues/detail?id=463 | |
148 time.sleep(1) | |
149 screenshot = self._screenshot_func() | |
150 logging.info('Performing I-Spy comparison...') | |
151 self._ispy.PerformComparison( | |
152 test_run, | |
153 self._GetExpectationNameWithVersion( | |
154 device_type, expectation, chrome_version), | |
155 screenshot) | |
156 | |
157 def WaitForUnchangingDOM(self, driver): | |
158 """Waits for the DOM to stop changing. | |
159 | |
160 Args: | |
161 driver: a chromedriver driver instance. | |
162 """ | |
163 try: | |
164 driver.execute_async_script(self._wait_for_unchanging_dom_script) | |
165 except exceptions.TimeoutException: | |
166 logging.warning('Timed out waiting for DOM to stop changing') | |
167 | |
OLD | NEW |