2 from __future__
import absolute_import
, unicode_literals
, print_function
10 def __init__(self
, topsrcdir
, test
, suite
, doc
, **kwargs
):
11 self
.topsrcdir
= topsrcdir
18 """Perform any validation required for suite-specific arguments"""
22 """Iterate over a list of (path, data) tuples corresponding to the files
24 yield (self
.test
, self
._get
_template
_contents
())
26 def _get_template_contents(self
, **kwargs
):
27 raise NotImplementedError
29 def update_manifest(self
):
30 """Perform any manifest updates required to register the added tests"""
31 raise NotImplementedError
34 class XpcshellCreator(Creator
):
35 template_body
= """/* Any copyright is dedicated to the Public Domain.
36 http://creativecommons.org/publicdomain/zero/1.0/ */
40 add_task(async function test_TODO() {
41 ok(true, "TODO: implement the test");
45 def _get_template_contents(self
):
46 return self
.template_body
48 def update_manifest(self
):
49 manifest_file
= os
.path
.join(os
.path
.dirname(self
.test
), "xpcshell.ini")
50 filename
= os
.path
.basename(self
.test
)
52 if not os
.path
.isfile(manifest_file
):
53 print('Could not open manifest file {}'.format(manifest_file
))
55 write_to_ini_file(manifest_file
, filename
)
58 class MochitestCreator(Creator
):
60 "mochitest-browser-chrome": "browser.template.txt",
61 "mochitest-plain": "plain%(doc)s.template.txt",
62 "mochitest-chrome": "chrome%(doc)s.template.txt",
65 def _get_template_contents(self
):
66 mochitest_templates
= os
.path
.abspath(
67 os
.path
.join(os
.path
.dirname(__file__
), 'mochitest', 'static')
69 template_file_name
= None
71 template_file_name
= self
.templates
.get(self
.suite
)
73 if template_file_name
is None:
74 print("Sorry, `addtest` doesn't currently know how to add {}".format(self
.suite
))
77 template_file_name
= template_file_name
% {"doc": self
.doc
}
79 template_file
= os
.path
.join(mochitest_templates
, template_file_name
)
80 if not os
.path
.isfile(template_file
):
81 print("Sorry, `addtest` doesn't currently know how to add {} with document type {}"
82 .format(self
.suite
, self
.doc
))
85 with
open(template_file
) as f
:
88 def update_manifest(self
):
89 # attempt to insert into the appropriate manifest
91 "mochitest-plain": "mochitest.ini",
92 "mochitest-chrome": "chrome.ini",
93 "mochitest-browser-chrome": "browser.ini"
95 manifest_file
= os
.path
.join(os
.path
.dirname(self
.test
), guessed_ini
)
96 filename
= os
.path
.basename(self
.test
)
98 if not os
.path
.isfile(manifest_file
):
99 print('Could not open manifest file {}'.format(manifest_file
))
102 write_to_ini_file(manifest_file
, filename
)
105 class WebPlatformTestsCreator(Creator
):
106 template_prefix
= """<!doctype html>
107 %(documentElement)s<meta charset=utf-8>
109 template_long_timeout
= "<meta name=timeout content=long>\n"
111 template_body_th
= """<title></title>
112 <script src=/resources/testharness.js></script>
113 <script src=/resources/testharnessreport.js></script>
119 template_body_reftest
= """<title></title>
120 <link rel=%(match)s href=%(ref)s>
123 template_body_reftest_wait
= """<script src="/common/reftest-wait.js"></script>
127 template_js_long_timeout
= "//META: timeout=long\n"
129 upstream_path
= os
.path
.join("testing", "web-platform", "tests")
130 local_path
= os
.path
.join("testing", "web-platform", "mozilla", "tests")
132 def __init__(self
, *args
, **kwargs
):
133 super(WebPlatformTestsCreator
, self
).__init
__(*args
, **kwargs
)
134 self
.reftest
= self
.suite
== "web-platform-tests-reftest"
137 def get_parser(cls
, parser
):
138 parser
.add_argument("--long-timeout", action
="store_true",
139 help="Test should be given a long timeout "
140 "(typically 60s rather than 10s, but varies depending on environment)")
141 parser
.add_argument("-m", "--reference", dest
="ref", help="Path to the reference file")
142 parser
.add_argument("--mismatch", action
="store_true",
143 help="Create a mismatch reftest")
144 parser
.add_argument("--wait", action
="store_true",
145 help="Create a reftest that waits until takeScreenshot() is called")
147 def check_args(self
):
148 if self
.wpt_type(self
.test
) is None:
149 print("""Test path %s is not in wpt directories:
150 testing/web-platform/tests for tests that may be shared
151 testing/web-platform/mozilla/tests for Gecko-only tests""" % self
.test
)
155 if self
.kwargs
["ref"]:
156 print("--ref only makes sense for a reftest")
159 if self
.kwargs
["mismatch"]:
160 print("--mismatch only makes sense for a reftest")
163 if self
.kwargs
["wait"]:
164 print("--wait only makes sense for a reftest")
167 # Set the ref to a url relative to the test
168 if self
.kwargs
["ref"]:
169 if self
.ref_path(self
.kwargs
["ref"]) is None:
170 print("--ref doesn't refer to a path inside web-platform-tests")
174 yield (self
.test
, self
._get
_template
_contents
())
176 if self
.reftest
and self
.kwargs
["ref"]:
177 ref_path
= self
.ref_path(self
.kwargs
["ref"])
178 yield (ref_path
, self
._get
_template
_contents
(reference
=True))
180 def _get_template_contents(self
, reference
=False):
181 args
= {"documentElement": "<html class=reftest-wait>\n"
182 if self
.kwargs
["wait"] else ""}
184 if self
.test
.rsplit(".", 1)[1] == "js":
185 template
= self
.template_js
186 if self
.kwargs
["long_timeout"]:
187 template
+= self
.template_js_long_timeout
189 template
= self
.template_prefix
% args
190 if self
.kwargs
["long_timeout"]:
191 template
+= self
.template_long_timeout
195 args
= {"match": "match" if not self
.kwargs
["mismatch"] else "mismatch",
196 "ref": (self
.ref_url(self
.kwargs
["ref"])
197 if self
.kwargs
["ref"] else '""')}
198 template
+= self
.template_body_reftest
% args
199 if self
.kwargs
["wait"]:
200 template
+= self
.template_body_reftest_wait
202 template
+= "<title></title>"
204 template
+= self
.template_body_th
208 def update_manifest(self
):
211 def src_rel_path(self
, path
):
215 abs_path
= os
.path
.normpath(os
.path
.abspath(path
))
216 return os
.path
.relpath(abs_path
, self
.topsrcdir
)
218 def wpt_type(self
, path
):
219 path
= self
.src_rel_path(path
)
220 if path
.startswith(self
.upstream_path
):
222 elif path
.startswith(self
.local_path
):
226 def ref_path(self
, path
):
227 # The ref parameter can be one of several things
228 # 1. An absolute path to a reference file
229 # 2. A path to a file relative to the topsrcdir
230 # 3. A path relative to the test file
231 # These are not unambiguous, so it's somewhat best effort
233 if os
.path
.isabs(path
):
234 path
= os
.path
.normpath(path
)
235 if not path
.startswith(self
.topsrcdir
):
236 # Path is an absolute URL relative to the tests root
237 if path
.startswith("/_mozilla/"):
238 base
= self
.local_path
239 path
= path
[len("/_mozilla/"):]
241 base
= self
.upstream_path
243 path
= path
.replace("/", os
.sep
)
244 return os
.path
.join(base
, path
)
246 return self
.src_rel_path(path
)
248 if self
.wpt_type(path
) is not None:
251 test_rel_path
= self
.src_rel_path(
252 os
.path
.join(os
.path
.dirname(self
.test
), path
))
253 if self
.wpt_type(test_rel_path
) is not None:
255 # Returning None indicates that the path wasn't valid
257 def ref_url(self
, path
):
258 ref_path
= self
.ref_path(path
)
262 if path
[0] == "/" and len(path
) < len(ref_path
):
263 # This is an absolute url
266 # Othewise it's a file path
267 wpt_type_ref
= self
.wpt_type(ref_path
)
268 wpt_type_test
= self
.wpt_type(self
.test
)
269 if wpt_type_ref
== wpt_type_test
:
270 return os
.path
.relpath(ref_path
, os
.path
.dirname(self
.test
))
272 # If we have a local test referencing an upstream ref,
273 # or vice-versa use absolute paths
274 if wpt_type_ref
== "upstream":
275 rel_path
= os
.path
.relpath(ref_path
, self
.upstream_path
)
277 elif wpt_type_ref
== "local":
278 rel_path
= os
.path
.relpath(ref_path
, self
.local_path
)
279 url_base
= "/_mozilla/"
282 return url_base
+ rel_path
.replace(os
.path
.sep
, "/")
285 # Insert a new test in the right place within a given manifest file
286 def write_to_ini_file(manifest_file
, filename
):
287 # Insert a new test in the right place within a given manifest file
288 manifest
= manifestparser
.TestManifest(manifests
=[manifest_file
])
291 if any(t
['name'] == filename
for t
in manifest
.tests
):
292 print("{} is already in the manifest.".format(filename
))
295 for test
in manifest
.tests
:
296 if test
.get('name') > filename
:
297 insert_before
= test
.get('name')
300 with
open(manifest_file
, "r") as f
:
301 contents
= f
.readlines()
303 filename
= '[{}]\n'.format(filename
)
305 if not insert_before
:
306 contents
.append(filename
)
308 insert_before
= '[{}]'.format(insert_before
)
309 for i
in range(len(contents
)):
310 if contents
[i
].startswith(insert_before
):
311 contents
.insert(i
, filename
)
314 with io
.open(manifest_file
, "w", newline
='\n') as f
:
315 f
.write("".join(contents
))
318 TEST_CREATORS
= {"mochitest": MochitestCreator
,
319 "web-platform-tests": WebPlatformTestsCreator
,
320 "xpcshell": XpcshellCreator
}
323 def creator_for_suite(suite
):
324 if suite
.split("-")[0] == "mochitest":
325 base_suite
= "mochitest"
327 base_suite
= suite
.rsplit("-", 1)[0]
328 return TEST_CREATORS
.get(base_suite
)