1 #!/usr/bin/env python 2 3 # Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 4 # 5 # Redistribution and use in source and binary forms, with or without 6 # modification, are permitted provided that the following conditions 7 # are met: 8 # 9 # 1. Redistributions of source code must retain the above 10 # copyright notice, this list of conditions and the following 11 # disclaimer. 12 # 2. Redistributions in binary form must reproduce the above 13 # copyright notice, this list of conditions and the following 14 # disclaimer in the documentation and/or other materials 15 # provided with the distribution. 16 # 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY 18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 22 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 # SUCH DAMAGE. 29 30 import os 31 import re 32 import webkitpy.thirdparty.unittest2 as unittest 33 34 from webkitpy.common.host import Host 35 from webkitpy.common.system.outputcapture import OutputCapture 36 from webkitpy.common.webkit_finder import WebKitFinder 37 from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup 38 from webkitpy.w3c.test_converter import _W3CTestConverter 39 40 DUMMY_FILENAME = 'dummy.html' 41 DUMMY_PATH = 'dummy/testharness/path' 42 43 class W3CTestConverterTest(unittest.TestCase): 44 45 # FIXME: When we move to using a MockHost, this method should be removed, since 46 # then we can just pass in a dummy dir path 47 def fake_dir_path(self, dirname): 48 filesystem = Host().filesystem 49 webkit_root = WebKitFinder(filesystem).webkit_base() 50 return filesystem.abspath(filesystem.join(webkit_root, "LayoutTests", "css", dirname)) 51 52 def test_read_prefixed_property_list(self): 53 """ Tests that the current list of properties requiring the -webkit- prefix load correctly """ 54 55 # FIXME: We should be passing in a MockHost here ... 56 converter = _W3CTestConverter(DUMMY_PATH, DUMMY_FILENAME) 57 prop_list = converter.prefixed_properties 58 self.assertTrue(prop_list, 'No prefixed properties found') 59 60 def test_convert_for_webkit_nothing_to_convert(self): 61 """ Tests convert_for_webkit() using a basic test that has nothing to convert """ 62 63 test_html = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 64 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 65 <html xmlns="http://www.w3.org/1999/xhtml"> 66 <head> 67 <title>CSS Test: DESCRIPTION OF TEST</title> 68 <link rel="author" title="NAME_OF_AUTHOR" 69 href="mailto:EMAIL OR http://CONTACT_PAGE"/> 70 <link rel="help" href="RELEVANT_SPEC_SECTION"/> 71 <meta name="assert" content="TEST ASSERTION"/> 72 <style type="text/css"><![CDATA[ 73 CSS FOR TEST 74 ]]></style> 75 </head> 76 <body> 77 CONTENT OF TEST 78 </body> 79 </html> 80 """ 81 converter = _W3CTestConverter(DUMMY_PATH, DUMMY_FILENAME) 82 83 oc = OutputCapture() 84 oc.capture_output() 85 try: 86 converter.feed(test_html) 87 converter.close() 88 converted = converter.output() 89 finally: 90 oc.restore_output() 91 92 self.verify_no_conversion_happened(converted, test_html) 93 94 def test_convert_for_webkit_harness_only(self): 95 """ Tests convert_for_webkit() using a basic JS test that uses testharness.js only and has no prefixed properties """ 96 97 test_html = """<head> 98 <link href="/resources/testharness.css" rel="stylesheet" type="text/css"> 99 <script src="/resources/testharness.js"></script> 100 </head> 101 """ 102 fake_dir_path = self.fake_dir_path("harnessonly") 103 converter = _W3CTestConverter(fake_dir_path, DUMMY_FILENAME) 104 converter.feed(test_html) 105 converter.close() 106 converted = converter.output() 107 108 self.verify_conversion_happened(converted) 109 self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 1, 1) 110 self.verify_prefixed_properties(converted, []) 111 112 def test_convert_for_webkit_properties_only(self): 113 """ Tests convert_for_webkit() using a test that has 2 prefixed properties: 1 in a style block + 1 inline style """ 114 115 test_html = """<html> 116 <head> 117 <link href="/resources/testharness.css" rel="stylesheet" type="text/css"> 118 <script src="/resources/testharness.js"></script> 119 <style type="text/css"> 120 121 #block1 { @test0@: propvalue; } 122 123 </style> 124 </head> 125 <body> 126 <div id="elem1" style="@test1@: propvalue;"></div> 127 </body> 128 </html> 129 """ 130 fake_dir_path = self.fake_dir_path('harnessandprops') 131 converter = _W3CTestConverter(fake_dir_path, DUMMY_FILENAME) 132 test_content = self.generate_test_content(converter.prefixed_properties, 1, test_html) 133 134 oc = OutputCapture() 135 oc.capture_output() 136 try: 137 converter.feed(test_content[1]) 138 converter.close() 139 converted = converter.output() 140 finally: 141 oc.restore_output() 142 143 self.verify_conversion_happened(converted) 144 self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 1, 1) 145 self.verify_prefixed_properties(converted, test_content[0]) 146 147 def test_convert_for_webkit_harness_and_properties(self): 148 """ Tests convert_for_webkit() using a basic JS test that uses testharness.js and testharness.css and has 4 prefixed properties: 3 in a style block + 1 inline style """ 149 150 test_html = """<html> 151 <head> 152 <link href="/resources/testharness.css" rel="stylesheet" type="text/css"> 153 <script src="/resources/testharness.js"></script> 154 <style type="text/css"> 155 156 #block1 { @test0@: propvalue; } 157 #block2 { @test1@: propvalue; } 158 #block3 { @test2@: propvalue; } 159 160 </style> 161 </head> 162 <body> 163 <div id="elem1" style="@test3@: propvalue;"></div> 164 </body> 165 </html> 166 """ 167 fake_dir_path = self.fake_dir_path('harnessandprops') 168 converter = _W3CTestConverter(fake_dir_path, DUMMY_FILENAME) 169 170 oc = OutputCapture() 171 oc.capture_output() 172 try: 173 test_content = self.generate_test_content(converter.prefixed_properties, 2, test_html) 174 converter.feed(test_content[1]) 175 converter.close() 176 converted = converter.output() 177 finally: 178 oc.restore_output() 179 180 self.verify_conversion_happened(converted) 181 self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 1, 1) 182 self.verify_prefixed_properties(converted, test_content[0]) 183 184 def test_convert_test_harness_paths(self): 185 """ Tests convert_testharness_paths() with a test that uses all three testharness files """ 186 187 test_html = """<head> 188 <link href="/resources/testharness.css" rel="stylesheet" type="text/css"> 189 <script src="/resources/testharness.js"></script> 190 <script src="/resources/testharnessreport.js"></script> 191 </head> 192 """ 193 fake_dir_path = self.fake_dir_path('testharnesspaths') 194 converter = _W3CTestConverter(fake_dir_path, DUMMY_FILENAME) 195 196 oc = OutputCapture() 197 oc.capture_output() 198 try: 199 converter.feed(test_html) 200 converter.close() 201 converted = converter.output() 202 finally: 203 oc.restore_output() 204 205 self.verify_conversion_happened(converted) 206 self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 2, 1) 207 208 def test_convert_prefixed_properties(self): 209 """ Tests convert_prefixed_properties() file that has 20 properties requiring the -webkit- prefix: 210 10 in one style block + 5 in another style 211 block + 5 inline styles, including one with multiple prefixed properties. 212 The properties in the test content are in all sorts of wack formatting. 213 """ 214 215 test_html = """<html> 216 <style type="text/css"><![CDATA[ 217 218 .block1 { 219 width: 300px; 220 height: 300px 221 } 222 223 .block2 { 224 @test0@: propvalue; 225 } 226 227 .block3{@test1@: propvalue;} 228 229 .block4 { @test2@:propvalue; } 230 231 .block5{ @test3@ :propvalue; } 232 233 #block6 { @test4@ : propvalue; } 234 235 #block7 236 { 237 @test5@: propvalue; 238 } 239 240 #block8 { @test6@: propvalue; } 241 242 #block9:pseudo 243 { 244 245 @test7@: propvalue; 246 @test8@: propvalue propvalue propvalue;; 247 } 248 249 ]]></style> 250 </head> 251 <body> 252 <div id="elem1" style="@test9@: propvalue;"></div> 253 <div id="elem2" style="propname: propvalue; @test10@ : propvalue; propname:propvalue;"></div> 254 <div id="elem2" style="@test11@: propvalue; @test12@ : propvalue; @test13@ :propvalue;"></div> 255 <div id="elem3" style="@test14@:propvalue"></div> 256 </body> 257 <style type="text/css"><![CDATA[ 258 259 .block10{ @test15@: propvalue; } 260 .block11{ @test16@: propvalue; } 261 .block12{ @test17@: propvalue; } 262 #block13:pseudo 263 { 264 @test18@: propvalue; 265 @test19@: propvalue; 266 } 267 268 ]]></style> 269 </html> 270 """ 271 converter = _W3CTestConverter(DUMMY_PATH, DUMMY_FILENAME) 272 test_content = self.generate_test_content(converter.prefixed_properties, 20, test_html) 273 274 oc = OutputCapture() 275 oc.capture_output() 276 try: 277 converter.feed(test_content[1]) 278 converter.close() 279 converted = converter.output() 280 finally: 281 oc.restore_output() 282 283 self.verify_conversion_happened(converted) 284 self.verify_prefixed_properties(converted, test_content[0]) 285 286 def verify_conversion_happened(self, converted): 287 self.assertTrue(converted, "conversion didn't happen") 288 289 def verify_no_conversion_happened(self, converted, original): 290 self.assertEqual(converted[1], original, 'test should not have been converted') 291 292 def verify_test_harness_paths(self, converter, converted, test_path, num_src_paths, num_href_paths): 293 if isinstance(converted, basestring): 294 converted = BeautifulSoup(converted) 295 296 resources_dir = converter.path_from_webkit_root("LayoutTests", "resources") 297 298 # Verify the original paths are gone, and the new paths are present. 299 orig_path_pattern = re.compile('\"/resources/testharness') 300 self.assertEquals(len(converted.findAll(src=orig_path_pattern)), 0, 'testharness src path was not converted') 301 self.assertEquals(len(converted.findAll(href=orig_path_pattern)), 0, 'testharness href path was not converted') 302 303 new_relpath = os.path.relpath(resources_dir, test_path) 304 relpath_pattern = re.compile(new_relpath) 305 self.assertEquals(len(converted.findAll(src=relpath_pattern)), num_src_paths, 'testharness src relative path not correct') 306 self.assertEquals(len(converted.findAll(href=relpath_pattern)), num_href_paths, 'testharness href relative path not correct') 307 308 def verify_prefixed_properties(self, converted, test_properties): 309 self.assertEqual(len(set(converted[0])), len(set(test_properties)), 'Incorrect number of properties converted') 310 for test_prop in test_properties: 311 self.assertTrue((test_prop in converted[1]), 'Property ' + test_prop + ' not found in converted doc') 312 313 def generate_test_content(self, full_property_list, num_test_properties, html): 314 """Inserts properties requiring a -webkit- prefix into the content, replacing \'@testXX@\' with a property.""" 315 test_properties = [] 316 count = 0 317 while count < num_test_properties: 318 test_properties.append(full_property_list[count]) 319 count += 1 320 321 # Replace the tokens in the testhtml with the test properties. Walk backward 322 # through the list to replace the double-digit tokens first 323 index = len(test_properties) - 1 324 while index >= 0: 325 # Use the unprefixed version 326 test_prop = test_properties[index].replace('-webkit-', '') 327 # Replace the token 328 html = html.replace('@test' + str(index) + '@', test_prop) 329 index -= 1 330 331 return (test_properties, html) 332