OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 from datetime import datetime | |
5 import glob | |
6 import os | |
7 import re | |
8 | |
4 from telemetry import test | 9 from telemetry import test |
10 from telemetry.core.backends import png_bitmap | |
5 from telemetry.page import page_test | 11 from telemetry.page import page_test |
12 from telemetry.page import test_expectations | |
6 | 13 |
14 test_data_dir = os.path.abspath(os.path.join( | |
15 os.path.dirname(__file__), '..', '..', 'data', 'gpu')) | |
16 | |
17 generated_data_dir = os.path.join(test_data_dir, 'generated') | |
18 ref_image_dir = os.path.join(test_data_dir, 'gpu_reference') | |
Ken Russell (switch to Gerrit)
2013/09/06 00:35:35
These directories really need to be passed in from
| |
19 | |
20 test_harness_script = r""" | |
21 var domAutomationController = {}; | |
22 | |
23 domAutomationController._succeeded = false; | |
24 domAutomationController._finished = false; | |
25 | |
26 domAutomationController.setAutomationId = function(id) {} | |
27 | |
28 domAutomationController.send = function(msg) { | |
29 domAutomationController._finished = true; | |
30 | |
31 if(msg.toLowerCase() == "success") { | |
32 domAutomationController._succeeded = true; | |
33 } else { | |
34 domAutomationController._succeeded = false; | |
35 } | |
36 } | |
37 | |
38 window.domAutomationController = domAutomationController; | |
39 console.log("Harness injected."); | |
40 """ | |
7 | 41 |
8 class PixelTestFailure(Exception): | 42 class PixelTestFailure(Exception): |
9 pass | 43 pass |
10 | 44 |
45 def _DidTestSucceed(tab): | |
46 return tab.EvaluateJavaScript('domAutomationController._succeeded') | |
11 | 47 |
12 class PixelValidator(page_test.PageTest): | 48 class PixelValidator(page_test.PageTest): |
13 def __init__(self): | 49 def __init__(self): |
14 super(PixelValidator, self).__init__('ValidatePage') | 50 super(PixelValidator, self).__init__('ValidatePage') |
15 | 51 |
52 def CustomizeBrowserOptions(self, options): | |
53 options.AppendExtraBrowserArg('--enable-gpu-benchmarking') | |
54 | |
16 def ValidatePage(self, page, tab, results): | 55 def ValidatePage(self, page, tab, results): |
17 # TODO(bajones): Grab screenshot, compare to reference. | 56 if not _DidTestSucceed(tab): |
18 # page.reference_image | 57 raise page_test.Failure("Page indicated a failure") |
19 pass | |
20 | 58 |
59 if not tab.screenshot_supported: | |
60 raise page_test.Failure("Browser does not support screenshot capture") | |
61 | |
62 screenshot = tab.Screenshot(5) | |
63 | |
64 if not screenshot: | |
65 raise page_test.Failure("Could not capture screenshot") | |
66 | |
67 image_name = PixelValidator.UrlToImageName(page.url) | |
68 | |
69 ref_png = PixelValidator.GetReferenceImage(image_name, page.revision, | |
70 screenshot) | |
71 | |
72 # Test new snapshot against existing reference image | |
73 if not ref_png.IsEqual(screenshot, tolerance=2): | |
74 PixelValidator.WriteErrorImages(image_name, page.revision, screenshot, | |
75 ref_png) | |
76 raise page_test.Failure("Reference image did not match captured screen") | |
77 | |
78 @staticmethod | |
79 def UrlToImageName(url): | |
80 image_name = re.sub(r'^(http|https|file)://(/*)', '', url) | |
81 image_name = re.sub(r'\.\./', '', image_name) | |
82 image_name = re.sub(r'(\.|/|-)', '_', image_name) | |
83 return image_name | |
84 | |
85 @staticmethod | |
86 def DeleteOldReferenceImages(ref_image_path, cur_revision): | |
87 if not cur_revision: | |
88 return | |
89 | |
90 old_revisions = glob.glob(ref_image_path + "__rev_*.png") | |
91 for rev_path in old_revisions: | |
92 m = re.match(r'^.*__rev_(\d+)\.png$', rev_path) | |
93 if m and int(m.group(1)) < cur_revision: | |
94 print 'Found deprecated reference image. Deleting rev ' + m.group(1) | |
95 os.remove(rev_path) | |
96 | |
97 @staticmethod | |
98 def GetReferenceImage(image_name, cur_revision, screenshot): | |
99 if not cur_revision: | |
100 cur_revision = 0 | |
101 | |
102 image_path = os.path.join(ref_image_dir, image_name) | |
103 | |
104 PixelValidator.DeleteOldReferenceImages(image_path, cur_revision) | |
105 | |
106 image_path = image_path + '__rev_' + str(cur_revision) + '.png' | |
107 | |
108 try: | |
109 ref_png = png_bitmap.PngBitmap.FromFile(image_path) | |
110 except IOError: | |
111 ref_png = None | |
112 | |
113 if ref_png: | |
114 return ref_png | |
115 | |
116 print 'Reference image not found. Writing tab contents as reference.' | |
117 | |
118 PixelValidator.WriteImage(image_path, screenshot) | |
119 return screenshot | |
120 | |
121 @staticmethod | |
122 def WriteErrorImages(image_name, cur_revision, screenshot, ref_png): | |
123 capture_time = datetime.now() | |
124 full_image_name = image_name + '__rev_' + str(cur_revision) | |
125 full_image_name = full_image_name + capture_time.strftime("__%b%d_%H_%M_%S") | |
126 full_image_name = full_image_name + '.png' | |
127 | |
128 PixelValidator.WriteImage( | |
129 os.path.join(generated_data_dir, 'FAIL_' + full_image_name), screenshot) | |
130 | |
131 diff_png = screenshot.Diff(ref_png) | |
132 PixelValidator.WriteImage( | |
133 os.path.join(generated_data_dir, 'DIFF_' + full_image_name), diff_png) | |
134 | |
135 @staticmethod | |
136 def WriteImage(image_path, png_image): | |
137 output_dir = os.path.dirname(image_path) | |
138 if not os.path.exists(output_dir): | |
139 os.makedirs(output_dir) | |
140 | |
141 png_image.WriteFile(image_path) | |
21 | 142 |
22 class Pixel(test.Test): | 143 class Pixel(test.Test): |
23 enabled = False | 144 enabled = False |
24 test = PixelValidator | 145 test = PixelValidator |
25 page_set = 'page_sets/pixel_tests.json' | 146 page_set = 'page_sets/pixel_tests.json' |
147 | |
148 def CreateExpectations(self, page_set): | |
149 print page_set.pages | |
150 for page in page_set.pages: | |
151 print 'Injecting harness into ', page.url | |
152 page.script_to_evaluate_on_commit = test_harness_script | |
153 | |
154 return test_expectations.TestExpectations() | |
OLD | NEW |