8 def __init__(self
, topsrcdir
, test
, suite
, doc
, **kwargs
):
9 self
.topsrcdir
= topsrcdir
16 """Perform any validation required for suite-specific arguments"""
20 """Iterate over a list of (path, data) tuples corresponding to the files
22 yield (self
.test
, self
._get
_template
_contents
())
24 def _get_template_contents(self
, **kwargs
):
25 raise NotImplementedError
27 def update_manifest(self
):
28 """Perform any manifest updates required to register the added tests"""
29 raise NotImplementedError
32 class XpcshellCreator(Creator
):
33 template_body
= """/* Any copyright is dedicated to the Public Domain.
34 http://creativecommons.org/publicdomain/zero/1.0/ */
38 add_task(async function test_TODO() {
39 ok(true, "TODO: implement the test");
43 def _get_template_contents(self
):
44 return self
.template_body
46 def update_manifest(self
):
47 update_toml_or_ini("xpcshell", self
.test
)
50 class MochitestCreator(Creator
):
52 "mochitest-browser-chrome": "browser.template.txt",
53 "mochitest-plain": "plain%(doc)s.template.txt",
54 "mochitest-chrome": "chrome%(doc)s.template.txt",
57 def _get_template_contents(self
):
58 mochitest_templates
= os
.path
.abspath(
59 os
.path
.join(os
.path
.dirname(__file__
), "mochitest", "static")
61 template_file_name
= None
63 template_file_name
= self
.templates
.get(self
.suite
)
65 if template_file_name
is None:
67 "Sorry, `addtest` doesn't currently know how to add {}".format(
73 template_file_name
= template_file_name
% {"doc": self
.doc
}
75 template_file
= os
.path
.join(mochitest_templates
, template_file_name
)
76 if not os
.path
.isfile(template_file
):
78 "Sorry, `addtest` doesn't currently know how to add {} with document type {}".format( # NOQA: E501
84 with
open(template_file
) as f
:
87 def update_manifest(self
):
88 # attempt to insert into the appropriate manifest
90 "mochitest-plain": "mochitest",
91 "mochitest-chrome": "chrome",
92 "mochitest-browser-chrome": "browser",
95 update_toml_or_ini(guessed_prefix
, self
.test
)
98 class WebPlatformTestsCreator(Creator
):
99 template_prefix
= """<!doctype html>
100 %(documentElement)s<meta charset=utf-8>
102 template_long_timeout
= "<meta name=timeout content=long>\n"
104 template_body_th
= """<title></title>
105 <script src=/resources/testharness.js></script>
106 <script src=/resources/testharnessreport.js></script>
112 template_body_reftest
= """<title></title>
113 <link rel=%(match)s href=%(ref)s>
116 template_body_reftest_wait
= """<script src="/common/reftest-wait.js"></script>
120 template_js_long_timeout
= "//META: timeout=long\n"
122 upstream_path
= os
.path
.join("testing", "web-platform", "tests")
123 local_path
= os
.path
.join("testing", "web-platform", "mozilla", "tests")
125 def __init__(self
, *args
, **kwargs
):
126 super(WebPlatformTestsCreator
, self
).__init
__(*args
, **kwargs
)
127 self
.reftest
= self
.suite
== "web-platform-tests-reftest"
130 def get_parser(cls
, parser
):
134 help="Test should be given a long timeout "
135 "(typically 60s rather than 10s, but varies depending on environment)",
138 "-m", "--reference", dest
="ref", help="Path to the reference file"
141 "--mismatch", action
="store_true", help="Create a mismatch reftest"
146 help="Create a reftest that waits until takeScreenshot() is called",
149 def check_args(self
):
150 if self
.wpt_type(self
.test
) is None:
152 """Test path %s is not in wpt directories:
153 testing/web-platform/tests for tests that may be shared
154 testing/web-platform/mozilla/tests for Gecko-only tests"""
160 if self
.kwargs
["ref"]:
161 print("--ref only makes sense for a reftest")
164 if self
.kwargs
["mismatch"]:
165 print("--mismatch only makes sense for a reftest")
168 if self
.kwargs
["wait"]:
169 print("--wait only makes sense for a reftest")
172 # Set the ref to a url relative to the test
173 if self
.kwargs
["ref"]:
174 if self
.ref_path(self
.kwargs
["ref"]) is None:
175 print("--ref doesn't refer to a path inside web-platform-tests")
179 yield (self
.test
, self
._get
_template
_contents
())
181 if self
.reftest
and self
.kwargs
["ref"]:
182 ref_path
= self
.ref_path(self
.kwargs
["ref"])
183 yield (ref_path
, self
._get
_template
_contents
(reference
=True))
185 def _get_template_contents(self
, reference
=False):
187 "documentElement": "<html class=reftest-wait>\n"
188 if self
.kwargs
["wait"]
192 if self
.test
.rsplit(".", 1)[1] == "js":
193 template
= self
.template_js
194 if self
.kwargs
["long_timeout"]:
195 template
+= self
.template_js_long_timeout
197 template
= self
.template_prefix
% args
198 if self
.kwargs
["long_timeout"]:
199 template
+= self
.template_long_timeout
204 "match": "match" if not self
.kwargs
["mismatch"] else "mismatch",
206 self
.ref_url(self
.kwargs
["ref"])
207 if self
.kwargs
["ref"]
211 template
+= self
.template_body_reftest
% args
212 if self
.kwargs
["wait"]:
213 template
+= self
.template_body_reftest_wait
215 template
+= "<title></title>"
217 template
+= self
.template_body_th
221 def update_manifest(self
):
224 def src_rel_path(self
, path
):
228 abs_path
= os
.path
.normpath(os
.path
.abspath(path
))
229 return os
.path
.relpath(abs_path
, self
.topsrcdir
)
231 def wpt_type(self
, path
):
232 path
= self
.src_rel_path(path
)
233 if path
.startswith(self
.upstream_path
):
235 elif path
.startswith(self
.local_path
):
239 def ref_path(self
, path
):
240 # The ref parameter can be one of several things
241 # 1. An absolute path to a reference file
242 # 2. A path to a file relative to the topsrcdir
243 # 3. A path relative to the test file
244 # These are not unambiguous, so it's somewhat best effort
246 if os
.path
.isabs(path
):
247 path
= os
.path
.normpath(path
)
248 if not path
.startswith(self
.topsrcdir
):
249 # Path is an absolute URL relative to the tests root
250 if path
.startswith("/_mozilla/"):
251 base
= self
.local_path
252 path
= path
[len("/_mozilla/") :]
254 base
= self
.upstream_path
256 path
= path
.replace("/", os
.sep
)
257 return os
.path
.join(base
, path
)
259 return self
.src_rel_path(path
)
261 if self
.wpt_type(path
) is not None:
264 test_rel_path
= self
.src_rel_path(
265 os
.path
.join(os
.path
.dirname(self
.test
), path
)
267 if self
.wpt_type(test_rel_path
) is not None:
269 # Returning None indicates that the path wasn't valid
271 def ref_url(self
, path
):
272 ref_path
= self
.ref_path(path
)
276 if path
[0] == "/" and len(path
) < len(ref_path
):
277 # This is an absolute url
280 # Othewise it's a file path
281 wpt_type_ref
= self
.wpt_type(ref_path
)
282 wpt_type_test
= self
.wpt_type(self
.test
)
283 if wpt_type_ref
== wpt_type_test
:
284 return os
.path
.relpath(ref_path
, os
.path
.dirname(self
.test
))
286 # If we have a local test referencing an upstream ref,
287 # or vice-versa use absolute paths
288 if wpt_type_ref
== "upstream":
289 rel_path
= os
.path
.relpath(ref_path
, self
.upstream_path
)
291 elif wpt_type_ref
== "local":
292 rel_path
= os
.path
.relpath(ref_path
, self
.local_path
)
293 url_base
= "/_mozilla/"
296 return url_base
+ rel_path
.replace(os
.path
.sep
, "/")
299 # Insert a new test in the right place
300 def update_toml_or_ini(manifest_prefix
, testpath
):
301 basedir
= os
.path
.dirname(testpath
)
302 manifest_file
= os
.path
.join(basedir
, manifest_prefix
+ ".toml")
303 if not os
.path
.isfile(manifest_file
):
304 manifest_file
= os
.path
.join(basedir
, manifest_prefix
+ ".ini")
305 if not os
.path
.isfile(manifest_file
):
306 print("Could not open manifest file {}".format(manifest_file
))
308 filename
= os
.path
.basename(testpath
)
309 write_to_manifest_file(manifest_file
, filename
)
312 # Insert a new test in the right place within a given manifest file
313 def write_to_manifest_file(manifest_file
, filename
):
314 use_toml
= manifest_file
.endswith(".toml")
315 manifest
= manifestparser
.TestManifest(manifests
=[manifest_file
], use_toml
=use_toml
)
318 if any(t
["name"] == filename
for t
in manifest
.tests
):
319 print("{} is already in the manifest.".format(filename
))
322 for test
in manifest
.tests
:
323 if test
.get("name") > filename
:
324 insert_before
= test
.get("name")
327 with
open(manifest_file
, "r") as f
:
328 contents
= f
.readlines()
330 entry_line
= '["{}"]\n' if use_toml
else "[{}]"
331 filename
= (entry_line
+ "\n").format(filename
)
333 if not insert_before
:
334 contents
.append(filename
)
336 insert_before
= entry_line
.format(insert_before
)
337 for i
in range(len(contents
)):
338 if contents
[i
].startswith(insert_before
):
339 contents
.insert(i
, filename
)
342 with io
.open(manifest_file
, "w", newline
="\n") as f
:
343 f
.write("".join(contents
))
347 "mochitest": MochitestCreator
,
348 "web-platform-tests": WebPlatformTestsCreator
,
349 "xpcshell": XpcshellCreator
,
353 def creator_for_suite(suite
):
354 if suite
.split("-")[0] == "mochitest":
355 base_suite
= "mochitest"
357 base_suite
= suite
.rsplit("-", 1)[0]
358 return TEST_CREATORS
.get(base_suite
)