diff --git a/.gitignore b/.gitignore index 3f306a88921..60d0f3dd203 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /.vs /android-toolchains /target +/etc/layout-2020-regressions/regressions.html /ports/android/bin /ports/android/libs /ports/android/local.properties diff --git a/etc/layout-2020-regressions/gen.py b/etc/layout-2020-regressions/gen.py new file mode 100755 index 00000000000..fd01c4e6d46 --- /dev/null +++ b/etc/layout-2020-regressions/gen.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. + +import json +import os +import re +import sys +import urllib.request +from html import escape as html_escape + + +TASKCLUSTER_ROOT_URL = "https://community-tc.services.mozilla.com" + + +def fetch(url): + url = TASKCLUSTER_ROOT_URL + "/api/" + url + print("Fetching " + url) + response = urllib.request.urlopen(url) + assert response.getcode() == 200 + return response + + +def fetch_json(url): + with fetch(url) as response: + return json.load(response) + + +def task(platform, chunk, key): + return "index/v1/task/project.servo.%s_wpt_%s.%s" % (platform, chunk, key) + + +def failing_reftests(platform, key): + chunk_1_task_id = fetch_json(task(platform, 1, key))["taskId"] + name = fetch_json("queue/v1/task/" + chunk_1_task_id)["metadata"]["name"] + match = re.search("WPT chunk (\d+) / (\d+)", name) + assert match.group(1) == "1" + total_chunks = int(match.group(2)) + + for chunk in range(1, total_chunks + 1): + with fetch(task(platform, chunk, key) + "/artifacts/public/test-wpt.log") as response: + for line in response: + message = json.loads(line) + if message.get("status") not in {None, "OK", "PASS"}: + screenshots = message.get("extra", {}).get("reftest_screenshots") + if screenshots: + yield message["test"], screenshots + + +def main(index_key, commit_sha): + failures_2013 = {url for url, _ in failing_reftests("linux_x64", index_key)} + failures_2020 = Directory() + for url, screenshots in failing_reftests("linux_x64_2020", index_key): + if url not in failures_2013: + assert url.startswith("/") + failures_2020.add(url[1:], screenshots) + + here = os.path.dirname(__file__) + with open(os.path.join(here, "prism.js")) as f: + prism_js = f.read() + with open(os.path.join(here, "prism.css")) as f: + prism_css = f.read() + with open(os.path.join(here, "regressions.html"), "w", encoding="utf-8") as html: + os.chdir(os.path.join(here, "../../tests/wpt")) + html.write(""" + + +
%s
%s
\n" % k)
+ if isinstance(v, Directory):
+ html.write("%s\n" % v.count)
+ v.write(html)
+ else:
+ a, rel, b = v
+ html.write("%s
%s %s
%s
\n" % src)
+ html.write("\n")
+ html.write("\n")
+
+
+if __name__ == "__main__":
+ sys.exit(main(*sys.argv[1:]))
diff --git a/etc/layout-2020-regressions/prism.css b/etc/layout-2020-regressions/prism.css
new file mode 100644
index 00000000000..6fa6fcc5be6
--- /dev/null
+++ b/etc/layout-2020-regressions/prism.css
@@ -0,0 +1,141 @@
+/* PrismJS 1.19.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ background: none;
+ text-shadow: 0 1px white;
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+ font-size: 1em;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
+code[class*="language-"]::selection, code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+@media print {
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+ white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.token.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #9a6e3a;
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+
+.token.function,
+.token.class-name {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/etc/layout-2020-regressions/prism.js b/etc/layout-2020-regressions/prism.js
new file mode 100644
index 00000000000..a43970450d6
--- /dev/null
+++ b/etc/layout-2020-regressions/prism.js
@@ -0,0 +1,7 @@
+/* PrismJS 1.19.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,r=0,C={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(r){return r instanceof _?new _(r.type,e(r.content),r.alias):Array.isArray(r)?r.map(e):r.replace(/&/g,"&").replace(/e.length)return;if(!(k instanceof _)){if(h&&y!=r.length-1){if(c.lastIndex=v,!(S=c.exec(e)))break;for(var b=S.index+(f&&S[1]?S[1].length:0),w=S.index+S[0].length,A=y,P=v,x=r.length;A