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 manifest_file
= os
.path
.join(os
.path
.dirname(self
.test
), "xpcshell.ini")
48 filename
= os
.path
.basename(self
.test
)
50 if not os
.path
.isfile(manifest_file
):
51 print("Could not open manifest file {}".format(manifest_file
))
53 write_to_ini_file(manifest_file
, filename
)
56 class MochitestCreator(Creator
):
58 "mochitest-browser-chrome": "browser.template.txt",
59 "mochitest-plain": "plain%(doc)s.template.txt",
60 "mochitest-chrome": "chrome%(doc)s.template.txt",
63 def _get_template_contents(self
):
64 mochitest_templates
= os
.path
.abspath(
65 os
.path
.join(os
.path
.dirname(__file__
), "mochitest", "static")
67 template_file_name
= None
69 template_file_name
= self
.templates
.get(self
.suite
)
71 if template_file_name
is None:
73 "Sorry, `addtest` doesn't currently know how to add {}".format(
79 template_file_name
= template_file_name
% {"doc": self
.doc
}
81 template_file
= os
.path
.join(mochitest_templates
, template_file_name
)
82 if not os
.path
.isfile(template_file
):
84 "Sorry, `addtest` doesn't currently know how to add {} with document type {}".format( # NOQA: E501
90 with
open(template_file
) as f
:
93 def update_manifest(self
):
94 # attempt to insert into the appropriate manifest
96 "mochitest-plain": "mochitest.ini",
97 "mochitest-chrome": "chrome.ini",
98 "mochitest-browser-chrome": "browser.ini",
100 manifest_file
= os
.path
.join(os
.path
.dirname(self
.test
), guessed_ini
)
101 filename
= os
.path
.basename(self
.test
)
103 if not os
.path
.isfile(manifest_file
):
104 print("Could not open manifest file {}".format(manifest_file
))
107 write_to_ini_file(manifest_file
, filename
)
110 class WebPlatformTestsCreator(Creator
):
111 template_prefix
= """<!doctype html>
112 %(documentElement)s<meta charset=utf-8>
114 template_long_timeout
= "<meta name=timeout content=long>\n"
116 template_body_th
= """<title></title>
117 <script src=/resources/testharness.js></script>
118 <script src=/resources/testharnessreport.js></script>
124 template_body_reftest
= """<title></title>
125 <link rel=%(match)s href=%(ref)s>
128 template_body_reftest_wait
= """<script src="/common/reftest-wait.js"></script>
132 template_js_long_timeout
= "//META: timeout=long\n"
134 upstream_path
= os
.path
.join("testing", "web-platform", "tests")
135 local_path
= os
.path
.join("testing", "web-platform", "mozilla", "tests")
137 def __init__(self
, *args
, **kwargs
):
138 super(WebPlatformTestsCreator
, self
).__init
__(*args
, **kwargs
)
139 self
.reftest
= self
.suite
== "web-platform-tests-reftest"
142 def get_parser(cls
, parser
):
146 help="Test should be given a long timeout "
147 "(typically 60s rather than 10s, but varies depending on environment)",
150 "-m", "--reference", dest
="ref", help="Path to the reference file"
153 "--mismatch", action
="store_true", help="Create a mismatch reftest"
158 help="Create a reftest that waits until takeScreenshot() is called",
161 def check_args(self
):
162 if self
.wpt_type(self
.test
) is None:
164 """Test path %s is not in wpt directories:
165 testing/web-platform/tests for tests that may be shared
166 testing/web-platform/mozilla/tests for Gecko-only tests"""
172 if self
.kwargs
["ref"]:
173 print("--ref only makes sense for a reftest")
176 if self
.kwargs
["mismatch"]:
177 print("--mismatch only makes sense for a reftest")
180 if self
.kwargs
["wait"]:
181 print("--wait only makes sense for a reftest")
184 # Set the ref to a url relative to the test
185 if self
.kwargs
["ref"]:
186 if self
.ref_path(self
.kwargs
["ref"]) is None:
187 print("--ref doesn't refer to a path inside web-platform-tests")
191 yield (self
.test
, self
._get
_template
_contents
())
193 if self
.reftest
and self
.kwargs
["ref"]:
194 ref_path
= self
.ref_path(self
.kwargs
["ref"])
195 yield (ref_path
, self
._get
_template
_contents
(reference
=True))
197 def _get_template_contents(self
, reference
=False):
199 "documentElement": "<html class=reftest-wait>\n"
200 if self
.kwargs
["wait"]
204 if self
.test
.rsplit(".", 1)[1] == "js":
205 template
= self
.template_js
206 if self
.kwargs
["long_timeout"]:
207 template
+= self
.template_js_long_timeout
209 template
= self
.template_prefix
% args
210 if self
.kwargs
["long_timeout"]:
211 template
+= self
.template_long_timeout
216 "match": "match" if not self
.kwargs
["mismatch"] else "mismatch",
218 self
.ref_url(self
.kwargs
["ref"])
219 if self
.kwargs
["ref"]
223 template
+= self
.template_body_reftest
% args
224 if self
.kwargs
["wait"]:
225 template
+= self
.template_body_reftest_wait
227 template
+= "<title></title>"
229 template
+= self
.template_body_th
233 def update_manifest(self
):
236 def src_rel_path(self
, path
):
240 abs_path
= os
.path
.normpath(os
.path
.abspath(path
))
241 return os
.path
.relpath(abs_path
, self
.topsrcdir
)
243 def wpt_type(self
, path
):
244 path
= self
.src_rel_path(path
)
245 if path
.startswith(self
.upstream_path
):
247 elif path
.startswith(self
.local_path
):
251 def ref_path(self
, path
):
252 # The ref parameter can be one of several things
253 # 1. An absolute path to a reference file
254 # 2. A path to a file relative to the topsrcdir
255 # 3. A path relative to the test file
256 # These are not unambiguous, so it's somewhat best effort
258 if os
.path
.isabs(path
):
259 path
= os
.path
.normpath(path
)
260 if not path
.startswith(self
.topsrcdir
):
261 # Path is an absolute URL relative to the tests root
262 if path
.startswith("/_mozilla/"):
263 base
= self
.local_path
264 path
= path
[len("/_mozilla/") :]
266 base
= self
.upstream_path
268 path
= path
.replace("/", os
.sep
)
269 return os
.path
.join(base
, path
)
271 return self
.src_rel_path(path
)
273 if self
.wpt_type(path
) is not None:
276 test_rel_path
= self
.src_rel_path(
277 os
.path
.join(os
.path
.dirname(self
.test
), path
)
279 if self
.wpt_type(test_rel_path
) is not None:
281 # Returning None indicates that the path wasn't valid
283 def ref_url(self
, path
):
284 ref_path
= self
.ref_path(path
)
288 if path
[0] == "/" and len(path
) < len(ref_path
):
289 # This is an absolute url
292 # Othewise it's a file path
293 wpt_type_ref
= self
.wpt_type(ref_path
)
294 wpt_type_test
= self
.wpt_type(self
.test
)
295 if wpt_type_ref
== wpt_type_test
:
296 return os
.path
.relpath(ref_path
, os
.path
.dirname(self
.test
))
298 # If we have a local test referencing an upstream ref,
299 # or vice-versa use absolute paths
300 if wpt_type_ref
== "upstream":
301 rel_path
= os
.path
.relpath(ref_path
, self
.upstream_path
)
303 elif wpt_type_ref
== "local":
304 rel_path
= os
.path
.relpath(ref_path
, self
.local_path
)
305 url_base
= "/_mozilla/"
308 return url_base
+ rel_path
.replace(os
.path
.sep
, "/")
311 # Insert a new test in the right place within a given manifest file
312 def write_to_ini_file(manifest_file
, filename
):
313 # Insert a new test in the right place within a given manifest file
314 manifest
= manifestparser
.TestManifest(manifests
=[manifest_file
])
317 if any(t
["name"] == filename
for t
in manifest
.tests
):
318 print("{} is already in the manifest.".format(filename
))
321 for test
in manifest
.tests
:
322 if test
.get("name") > filename
:
323 insert_before
= test
.get("name")
326 with
open(manifest_file
, "r") as f
:
327 contents
= f
.readlines()
329 filename
= "[{}]\n".format(filename
)
331 if not insert_before
:
332 contents
.append(filename
)
334 insert_before
= "[{}]".format(insert_before
)
335 for i
in range(len(contents
)):
336 if contents
[i
].startswith(insert_before
):
337 contents
.insert(i
, filename
)
340 with io
.open(manifest_file
, "w", newline
="\n") as f
:
341 f
.write("".join(contents
))
345 "mochitest": MochitestCreator
,
346 "web-platform-tests": WebPlatformTestsCreator
,
347 "xpcshell": XpcshellCreator
,
351 def creator_for_suite(suite
):
352 if suite
.split("-")[0] == "mochitest":
353 base_suite
= "mochitest"
355 base_suite
= suite
.rsplit("-", 1)[0]
356 return TEST_CREATORS
.get(base_suite
)