#!/usr/bin/env python3 # Usage: python3 generate.py # # This will remove all existing .html files in the generated directories and generate new tests. # Notes on potential confusion with the 3 string substitution features in different layers: # # - In Python strings when calling .format(): {something} or {} # To get a literal {} use {{}}. # The template_* variables are ones below are those that will use .format(). # https://docs.python.org/3/library/string.html#formatstrings # - JS template literals: ${something} # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals # - wptserve server-side substitution when generating a response: {{GET[something]}} # https://web-platform-tests.org/writing-tests/server-pipes.html#sub import os, shutil target_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "/generated" delay = u'1500' # Lower value makes the test complete faster, but also higher risk of flaky results # Test data tentative_tests = [ # title, # encoding, # template_testcase_markup, # template_nonspeculative_testcase_markup (if different from template_testcase_markup), # expect_load, # test_nonspeculative ( u'script-src', u'utf-8', u'', None, u'true', u'true' ), ( u'meta-charset-script-src', None, u'', u'', u'true', u'true' ), ( # This test is only valid on "mobile" where meta viewport has an effect u'meta-viewport-link-stylesheet-media', u'utf-8', u'', None, u'false', u'true' ), ( u'meta-csp-img-src-none', u'utf-8', u'', None, u'false', u'true' ), ( u'meta-csp-img-src-asterisk', u'utf-8', u'', None, u'true', u'true' ), ( u'meta-referrer-no-referrer-img-src', u'utf-8', u'', None, u'true', u'true' ), ( u'base-href-script-src', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-unsupported-type', u'utf-8', u'', None, u'false', u'true' ), ( u'script-src-type-application-ecmascript', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-nomodule', u'utf-8', u'', None, u'false', u'true' ), ( u'script-src-module', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-async', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-defer', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-crossorigin', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-integrity', u'utf-8', u'', None, u'true', u'true' ), ( u'script-src-referrerpolicy-no-referrer', u'utf-8', u'', None, u'true', u'true' ), ( u'template-script-src', u'utf-8', u'', None, u'false', u'true' ), ( u'template-link-stylesheet', u'utf-8', u'', None, u'false', u'true' ), ( u'template-img-src', u'utf-8', u'', None, u'false', u'true' ), ( u'template-shadowrootmode-script-src', u'utf-8', u'
', None, u'true', u'true' ), ( u'template-shadowrootmode-link-stylesheet', u'utf-8', u'
', None, u'true', u'true' ), ( u'template-shadowrootmode-img-src', u'utf-8', u'
', None, u'true', u'true' ), ( u'nested-template-shadowrootmode-1', u'utf-8', u'', None, u'false', u'true' ), ( u'nested-template-shadowrootmode-2', u'utf-8', u'
', None, u'false', u'true' ), ( u'link-no-rel', u'utf-8', u'', None, u'false', u'true' ), ( u'link-rel-stylesheet', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-alternate-stylesheet', u'utf-8', u'', None, u'false', u'true' ), ( u'link-rel-stylesheet-disabled', u'utf-8', u'', None, u'false', u'true' ), ( u'link-rel-stylesheet-nomatch-media', u'utf-8', u'', None, u'false', u'true' ), ( u'link-rel-stylesheet-unsupported-type', u'utf-8', u'', None, u'false', u'true' ), ( u'link-rel-stylesheet-type-text-css', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-stylesheet-crossorigin', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-stylesheet-integrity', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-stylesheet-referrerpolicy-no-referrer', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-preload-as-style', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-preload-as-font-crossorigin', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-preload-as-script', u'utf-8', u'', None, u'true', u'true' ), ( u'link-rel-preload-as-image', u'utf-8', u'', None, u'true', u'true' ), ( u'img-src', u'utf-8', u'', None, u'true', u'true' ), ( u'img-data-src', u'utf-8', u'', None, u'false', u'true' ), ( # is turned into in the tree builder u'image-src', u'utf-8', u'', None, u'true', u'true' ), ( u'img-srcset', u'utf-8', u'', None, u'true', u'true' ), ( u'img-src-crossorigin', u'utf-8', u'', None, u'true', u'true' ), ( u'img-src-referrerpolicy-no-referrer', u'utf-8', u'', None, u'true', u'true' ), ( u'img-src-loading-lazy', u'utf-8', u'', None, u'false', u'false' ), ( u'picture-source-unsupported-type', u'utf-8', u'', None, u'false', u'true' ), ( u'picture-source-nomatch-media', u'utf-8', u'', None, u'false', u'true' ), ( u'picture-source-no-img', u'utf-8', u'', None, u'false', u'true' ), ( u'picture-source-br-img', u'utf-8', u'
', None, u'true', u'true' ), ( u'video-poster', u'utf-8', u'', None, u'true', u'true' ), ( u'xmp-script-src', u'utf-8', u'<script src="{}"></script>', None, u'false', u'true' ), ( # MathML doesn't have script u'math-script-src', u'utf-8', u'', None, u'false', u'true' ), ( u'math-font-script-src', u'utf-8', u'', None, u'false', u'true' ), ( # This breaks out of foreign content, so the script is an HTML script # https://html.spec.whatwg.org/multipage/#parsing-main-inforeign u'math-font-face-script-src', u'utf-8', u'', None, u'true', u'true' ), ( u'svg-script-href', u'utf-8', u'', None, u'true', u'true' ), ( u'svg-script-xlinkhref', u'utf-8', u'', None, u'true', u'true' ), ( # SVG script element doesn't have a src attribute u'svg-script-src', u'utf-8', u'', None, u'false', u'true' ), ( u'svg-image-href', u'utf-8', u'', None, u'true', u'true' ), ( u'svg-image-xlinkhref', u'utf-8', u'', None, u'true', u'true' ), ( # SVG image element doesn't have a src attribute u'svg-image-src', u'utf-8', u'', None, u'false', u'true' ), ] tests = [ # title, # encoding, # template_testcase_markup, # expect_load, # test_nonspeculative ] # Templates preamble = u""" """ no_meta_charset = u""" """ # Notes on `encodingcheck` in the URL below # # - Ğ is the HTML character reference for U+011E LATIN CAPITAL LETTER G WITH BREVE # - In windows-1254, this character is encoded as 0xD0. # When used in the query part of a URL, it gets percent-encoded as %D0. # - In windows-1252 (usually the fallback encoding), that character can't be encoded, so is instead # represented as Ğ percent-encoded, so %26%23286%3B. # https://url.spec.whatwg.org/#query-state # https://url.spec.whatwg.org/#code-point-percent-encode-after-encoding # - In utf-8, it's percent-encoded as utf-8: %C4%9E # - stash.py will store this value as "param-encodingcheck" url_wptserve_sub = u"/html/syntax/speculative-parsing/resources/stash.py?action=put&uuid={{GET[uuid]}}&encodingcheck=Ğ" url_js_sub = u"/html/syntax/speculative-parsing/resources/stash.py?action=put&uuid=${uuid}&encodingcheck=Ğ" # Non-speculative (normal) case to compare results with template_nonspeculative = u"""{preamble} {encoding_decl} Speculative parsing, non-speculative (helper file): {title} {nonspeculative_testcase_markup} """ # Scenario: page load template_pageload_toplevel = u"""{preamble} {encoding_decl} Speculative parsing, page load: {title} """ template_pageload_framed = u"""{preamble} {encoding_decl} Speculative parsing, page load (helper file): {title} {testcase_markup} """ # Scenario: document.write() template_docwrite = u"""{preamble} {encoding_decl} Speculative parsing, document.write(): {title} """ # Scenario: - TODO(zcorpan) template_prerender_toplevel = u"""{preamble} {encoding_decl} Speculative parsing, prerender: {title} ... """ template_prerender_linked = u"""{preamble} {encoding_decl} Speculative parsing, prerender (helper file): {title} ... """ # Generate tests # wipe target_dir of HTML files if os.path.isdir(target_dir): for root, dirs, files in os.walk(target_dir): for name in files: if name.endswith('.html'): path = os.path.join(root, name) if os.path.isfile(path): os.remove(path) def write_file(path, content): path = os.path.join(target_dir, path) os.makedirs(os.path.dirname(path), exist_ok=True) file = open(os.path.join(target_dir, path), 'w') file.write(content) file.close() def generate_tests(testcase, tentative): title, encoding, template_testcase_markup, template_nonspeculative_testcase_markup, expect_load, test_nonspeculative = testcase if template_nonspeculative_testcase_markup == None: template_nonspeculative_testcase_markup = template_testcase_markup ext = u"" if tentative: ext = u".tentative" if encoding == None: encoding_decl = no_meta_charset else: encoding_decl = f"" html_testcase_markup = template_testcase_markup.format(url_wptserve_sub) html_nonspeculative_testcase_markup = template_nonspeculative_testcase_markup.format(url_wptserve_sub) js_testcase_markup = template_testcase_markup.format(url_js_sub).replace(u"", u"<\\/script>").replace(u"