blob: 29551d9144177166955b2127b5d9ac9e8d855a7a [file] [log] [blame]
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generates HTML file with all dependencies from a js_unittest build target."""
import os
import sys
from argparse import ArgumentParser
_HTML_FILE = r"""<!DOCTYPE html>
<html>
<script>
// Basic include checker.
window.addEventListener('error', function(e) {
if ((e.target instanceof HTMLScriptElement)) {
console.log('ERROR loading <script> element (does it exist?):\n\t' +
e.srcElement.src + '\n\tIncluded from: ' +
e.srcElement.baseURI);
}
}, true /* useCapture */);
</script>
<body>
"""
_SCRIPT = r'<script src="%s"></script>'
_IMPORT = r'<link rel="import" href="%s">'
_HTML_FOOTER = r"""
</body>
</html>
"""
def _process_deps(unique_deps, html_import, target_name):
"""Processes all deps strings, yielding each HTML tag to include the dep.
Args:
unique_deps: Iterator of strings, for all deps to be processed.
html_import: Boolean: Enables the use of HTMLImport for the main Polymer
element being tested.
target_name: Current test target name, used to infer the main Polymer
element for HTMLImport. element_unitest => element.js/element.html.
Returns:
Iterator of strings, each string is a HTML tag <script> or <link>.
"""
for dep in unique_deps:
# Special case for jstemplate which has multiple files but we server all of
# them combined from chrome://resources/js/jstemplate_compiled.js
if '/jstemplate/' in dep:
if '/jstemplate.js' in dep:
yield ('<script src='
'"chrome://resources/js/jstemplate_compiled.js"></script>')
# just ignore other files files from /jstemplate/
continue
# Map file_manager files:
dep = dep.replace('ui/file_manager/',
'chrome://file_manager_test/ui/file_manager/', 1)
# WebUI files (both Polymer and non-Polymer):
dep = dep.replace('ui/webui/resources/', 'chrome://resources/', 1)
# Polymer Files:
dep = dep.replace('third_party/polymer/', 'chrome://resources/polymer/', 1)
dep = dep.replace('components-chromium/', '', 1)
# Remove the relative because all replaces above map to an absolute path in
# chrome://* and this URL scheme doesn't allow "..".
dep = dep.replace('../', '')
# Find the file being tested eg: element_unittest => element.js
implementation_file = target_name.replace('_unittest', '.js')
# If it should use HTMLImport the main element JS file shouldn't be
# included, instead we <link rel=import> its HTML file which in turn
# includes the JS file. Note that all other JS deps are included as
# <script>.
if html_import and dep.endswith(implementation_file):
dep = dep.replace('.js', '.html')
yield _IMPORT % (dep)
else:
# Normal dep, just return the <script src="dep.js">
yield _SCRIPT % (dep)
def _process(deps, output_filename, mocks, html_import, target_name):
"""Generates the HTML file with all JS dependencies for JS unittest.
Args:
deps: List of strings for each dependency path.
output_filename: String, HTML file name that will be generated.
mocks: List of strings, JS file names that will be included in the bottom to
overwrite JS implementation from deps.
html_import: Boolean, indicate if HTMLImport should be used for testing
Polymer elements.
target_name: Current test target name, used to infer the main Polymer
element for HTMLImport. element_unitest => element.js/element.html.
"""
with open(output_filename, 'w') as out:
out.write(_HTML_FILE)
for dep in _process_deps(mocks, html_import, target_name):
out.write(dep + '\n')
for dep in _process_deps(deps, html_import, target_name):
out.write(dep + '\n')
out.write(_HTML_FOOTER)
def main():
parser = ArgumentParser()
parser.add_argument(
'-s', '--src_path', help='Path to //src/ directory', required=True)
parser.add_argument(
'-i',
'--input',
help='Input dependency file generated by js_library.py',
required=True)
parser.add_argument(
'-o',
'--output',
help='Generated html output with flattened dependencies',
required=True)
parser.add_argument(
'-m',
'--mocks',
nargs='*',
default=[],
help='List of additional js files to load before others')
parser.add_argument('-t', '--target_name', help='Test target name')
parser.add_argument(
'--html_import',
action='store_true',
help='Enable HTMLImports, used for Polymer elements')
args = parser.parse_args()
# Append closure path to sys.path to be able to import js_unit_test.
sys.path.append(os.path.join(args.src_path, 'third_party/closure_compiler'))
from js_binary import CrawlDepsTree
deps, _ = CrawlDepsTree([args.input])
return _process(deps, args.output, args.mocks, args.html_import,
args.target_name)
if __name__ == '__main__':
main()