From 4ed8aff682f92c0315165d9b475e5d72731b28f5 Mon Sep 17 00:00:00 2001
From: Iban Eguia Moraza <razican@protonmail.ch>
Date: Sat, 24 Feb 2024 21:09:27 +0100
Subject: [PATCH] Fixed latest.json result files for the new format (#3348)

---
 dev/bench/index.html                    |  29 ++-
 playground/index.html                   |  27 ++-
 test262/fix.py                          | 255 ++++++++++++++++++++++
 test262/index.html                      |  33 +--
 test262/refs/tags/v0.15/features.json   |   1 -
 test262/refs/tags/v0.16/features.json   |   1 -
 test262/refs/tags/v0.17.1/features.json |   1 -
 test262/refs/tags/v0.17.2/features.json |   1 -
 test262/refs/tags/v0.17.3/features.json |   1 -
 test262/refs/tags/v0.17/features.json   |   1 -
 test262/results.js                      | 267 +++++++++++++-----------
 11 files changed, 462 insertions(+), 155 deletions(-)
 create mode 100644 test262/fix.py
 delete mode 100644 test262/refs/tags/v0.15/features.json
 delete mode 100644 test262/refs/tags/v0.16/features.json
 delete mode 100644 test262/refs/tags/v0.17.1/features.json
 delete mode 100644 test262/refs/tags/v0.17.2/features.json
 delete mode 100644 test262/refs/tags/v0.17.3/features.json
 delete mode 100644 test262/refs/tags/v0.17/features.json

diff --git a/dev/bench/index.html b/dev/bench/index.html
index c5b54012ec5..07f86ad86d5 100644
--- a/dev/bench/index.html
+++ b/dev/bench/index.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!doctype html>
 <html>
   <head>
     <meta charset="UTF-8" />
@@ -8,9 +8,20 @@
     />
     <style>
       html {
-        font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto,
-          Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue",
-          Helvetica, Arial, sans-serif;
+        font-family:
+          BlinkMacSystemFont,
+          -apple-system,
+          "Segoe UI",
+          Roboto,
+          Oxygen,
+          Ubuntu,
+          Cantarell,
+          "Fira Sans",
+          "Droid Sans",
+          "Helvetica Neue",
+          Helvetica,
+          Arial,
+          sans-serif;
         -webkit-font-smoothing: antialiased;
         font-size: 16px;
       }
@@ -286,7 +297,7 @@
               .sort(
                 (a, b) =>
                   arr.filter((v) => v === a).length -
-                  arr.filter((v) => v === b).length
+                  arr.filter((v) => v === b).length,
               )
               .pop();
           }
@@ -335,7 +346,7 @@
 
           // Render header
           document.getElementById("last-update").textContent = new Date(
-            data.lastUpdate
+            data.lastUpdate,
           ).toString();
           const repoLink = document.getElementById("repository-link");
           repoLink.href = data.repoUrl;
@@ -470,7 +481,7 @@
             for (const [benchName, benches] of benchSet.entries()) {
               const benchUnit = unit.get(benchName);
               charts.push(
-                renderGraph(graphsElem, benchName, benchUnit, benches)
+                renderGraph(graphsElem, benchName, benchUnit, benches),
               );
             }
             return charts;
@@ -483,10 +494,10 @@
           }
 
           const darkModeCheckbox = document.querySelector(
-            ".dark-mode-toggle input[type=checkbox]"
+            ".dark-mode-toggle input[type=checkbox]",
           );
           const darkModeHandle = document.querySelector(
-            ".dark-mode-toggle .handle"
+            ".dark-mode-toggle .handle",
           );
           darkModeCheckbox.addEventListener("change", async (e) => {
             document.body.classList.toggle("dark");
diff --git a/playground/index.html b/playground/index.html
index 3a920535a25..4dc1577627a 100644
--- a/playground/index.html
+++ b/playground/index.html
@@ -1,4 +1,13 @@
-<!doctype html><html><head><meta charset="utf-8"/><title>Boa Playground</title><link href="assets/bootstrap.min.css" rel="stylesheet"/><meta name="viewport" content="width=device-width,initial-scale=1"/><script defer="defer" src="app.js"></script></head><style>header {
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <title>Boa Playground</title>
+    <link href="assets/bootstrap.min.css" rel="stylesheet" />
+    <meta name="viewport" content="width=device-width,initial-scale=1" />
+    <script defer="defer" src="app.js"></script></head
+  ><style>
+    header {
       display: flex;
       align-items: center;
     }
@@ -50,4 +59,18 @@
       .output {
         min-height: 100px;
       }
-    }</style><body><div class="container"><header><img class="demo__img" src="./assets/logo.svg"/><h1>Boa Playground</h1></header><div class="demo__repl"><div class="textbox"></div><p data-testid="output" class="output"></p></div></div></body></html>
\ No newline at end of file
+    }
+  </style>
+  <body>
+    <div class="container">
+      <header>
+        <img class="demo__img" src="./assets/logo.svg" />
+        <h1>Boa Playground</h1>
+      </header>
+      <div class="demo__repl">
+        <div class="textbox"></div>
+        <p data-testid="output" class="output"></p>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/test262/fix.py b/test262/fix.py
new file mode 100644
index 00000000000..9069b3af70a
--- /dev/null
+++ b/test262/fix.py
@@ -0,0 +1,255 @@
+import json
+import os
+
+
+def suite_conformance(suite):
+    global function_suite
+    res = {
+        "t": 0,
+        "o": 0,
+        "i": 0,
+        "p": 0
+    }
+
+    if "s" in suite.keys():
+        for subSuite in suite["s"].values():
+            conformance = suite_conformance(subSuite)
+            res["t"] += conformance["t"]
+            res["o"] += conformance["o"]
+            res["i"] += conformance["i"]
+            res["p"] += conformance["p"]
+
+    if "t" in suite.keys():
+        for testName in suite["t"].keys():
+            test = suite["t"][testName]
+
+            res["t"] += 1
+            if "s" in test.keys() and "r" in test.keys():
+                if test["s"] == "O" and test["r"] == "O":
+                    res["o"] += 1
+                elif test["s"] == "I" and test["r"] == "I":
+                    res["i"] += 1
+                elif test["s"] == "P" or test["r"] == "P":
+                    res["p"] += 1
+            elif "s" in test.keys():
+                if test["s"] == "O":
+                    res["o"] += 1
+                elif test["s"] == "I":
+                    res["i"] += 1
+                elif test["s"] == "P":
+                    res["p"] += 1
+            else:
+                if test["r"] == "O":
+                    res["o"] += 1
+                elif test["r"] == "I":
+                    res["i"] += 1
+                elif test["r"] == "P":
+                    res["p"] += 1
+
+    return res
+
+
+def version_conformance(suite):
+    res = {}
+
+    if "s" in suite.keys():
+        for subSuite in suite["s"].values():
+            versions = version_conformance(subSuite)
+            for key in versions.keys():
+                if key not in res.keys():
+                    res[key] = {
+                        "t": 0,
+                        "o": 0,
+                        "i": 0,
+                        "p": 0
+                    }
+
+                res[key]["t"] += versions[key]["t"]
+                res[key]["o"] += versions[key]["o"]
+                res[key]["i"] += versions[key]["i"]
+                res[key]["p"] += versions[key]["p"]
+
+    if "t" in suite.keys():
+        for testName in suite["t"].keys():
+            test = suite["t"][testName]
+
+            if "v" in test.keys():
+                version = test["v"]
+                if version != 255:
+                    key = str(version)
+                    if key not in res.keys():
+                        res[key] = {
+                            "t": 0,
+                            "o": 0,
+                            "i": 0,
+                            "p": 0
+                        }
+
+                    res[key]["t"] += 1
+                    if "s" in test.keys() and "r" in test.keys():
+                        if test["s"] == "O" and test["r"] == "O":
+                            res[key]["o"] += 1
+                        elif test["s"] == "I" and test["r"] == "I":
+                            res[key]["i"] += 1
+                        elif test["s"] == "P" or test["r"] == "P":
+                            res[key]["p"] += 1
+                    elif "s" in test.keys():
+                        if test["s"] == "O":
+                            res[key]["o"] += 1
+                        elif test["s"] == "I":
+                            res[key]["i"] += 1
+                        elif test["s"] == "P":
+                            res[key]["p"] += 1
+                    else:
+                        if test["r"] == "O":
+                            res[key]["o"] += 1
+                        elif test["r"] == "I":
+                            res[key]["i"] += 1
+                        elif test["r"] == "P":
+                            res[key]["p"] += 1
+
+    return res
+
+
+def fix_tests(tests):
+    fixed = {}
+
+    for test in tests:
+        name = test["n"]
+        if test["n"] in fixed:
+            if test["s"]:
+                fixed[name]["s"] = test["r"]
+            else:
+                fixed[name]["r"] = test["r"]
+        else:
+            fixed[name] = {}
+
+            if "v" in test.keys():
+                fixed[name]["v"] = test["v"]
+
+            if "s" in test.keys():
+                if test["s"]:
+                    fixed[name]["s"] = test["r"]
+                else:
+                    fixed[name]["r"] = test["r"]
+            else:
+                fixed[name]["r"] = test["r"]
+
+    return fixed
+
+
+def fix_suite(suites):
+    fixed = {}
+    for suite in suites:
+        name = suite["n"]
+        fixed[name] = {}
+
+        if "s" in suite.keys():
+            fixed[name]["s"] = fix_suite(suite["s"])
+
+        if "t" in suite.keys():
+            fixed[name]["t"] = fix_tests(suite["t"])
+
+        fixed[name]["a"] = suite_conformance(fixed[name])
+        fixed[name]["v"] = version_conformance(fixed[name])
+
+    return fixed
+
+
+def fix_all(latest):
+    fixed = {
+        "c": latest["c"],
+        "u": latest["u"],
+        "r": fix_suite(latest["r"]["s"]),
+        "a": {
+            "t": 0,
+            "o": 0,
+            "i": 0,
+            "p": 0
+        },
+        "v": {},
+    }
+
+    for suite in fixed["r"].values():
+        fixed["a"]["t"] += suite["a"]["t"]
+        fixed["a"]["o"] += suite["a"]["o"]
+        fixed["a"]["i"] += suite["a"]["i"]
+        fixed["a"]["p"] += suite["a"]["p"]
+
+        for key in suite["v"].keys():
+            if key not in fixed["v"].keys():
+                fixed["v"][key] = {
+                    "t": 0,
+                    "o": 0,
+                    "i": 0,
+                    "p": 0
+                }
+
+            fixed["v"][key]["t"] += suite["v"][key]["t"]
+            fixed["v"][key]["o"] += suite["v"][key]["o"]
+            fixed["v"][key]["i"] += suite["v"][key]["i"]
+            fixed["v"][key]["p"] += suite["v"][key]["p"]
+
+    return fixed
+
+
+def fix_file(file_name):
+    with open(file_name) as latest_f:
+        latest = json.load(latest_f)
+        fixed_latest = fix_all(latest)
+
+        with open(file_name, 'w') as latest_of:
+            json.dump(fixed_latest, latest_of, separators=(
+                ',', ':'), ensure_ascii=False)
+
+        return fixed_latest
+
+
+def clean_main(latest):
+    with open("./refs/heads/main/results.json") as results_f:
+        results = json.load(results_f)
+        fixed_results = []
+        for result in results:
+            fixed_results.append({
+                "c": result["c"],
+                "u": result["u"],
+                "a": result["a"],
+            })
+
+        fixed_results[-1] = {
+            "c": latest["c"],
+            "u": latest["u"],
+            "a": latest["a"],
+        }
+
+        with open("./refs/heads/main/results.json", 'w') as results_of:
+            json.dump(fixed_results, results_of, separators=(
+                ',', ':'), ensure_ascii=False)
+
+
+def clean_old(file_name, results):
+    fixed_results = [{
+        "c": results["c"],
+        "u": results["u"],
+        "a": results["a"],
+    }]
+
+    with open(file_name, 'w') as results_of:
+        json.dump(fixed_results, results_of, separators=(
+            ',', ':'), ensure_ascii=False)
+
+
+for top, dirs, files in os.walk("./refs/tags"):
+    for dir in dirs:
+        print("Fixing " + dir)
+        results = fix_file("./refs/tags/" + dir + "/latest.json")
+        clean_old("./refs/tags/" + dir + "/results.json", results)
+
+        if os.path.exists("./refs/tags/" + dir + "/features.json"):
+            os.remove("./refs/tags/" + dir + "/features.json")
+
+print("Fixing main branch")
+results = fix_file("./refs/heads/main/latest.json")
+clean_main(results)
+if os.path.exists("./refs/heads/main/features.json"):
+    os.remove("./refs/heads/main/features.json")
diff --git a/test262/index.html b/test262/index.html
index e6009302610..d9079777aa2 100644
--- a/test262/index.html
+++ b/test262/index.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en">
   <head>
     <title>Boa EcmaScript conformance</title>
@@ -6,14 +6,14 @@
     <link rel="icon" href="../assets/logo.svg" type="image/svg+xml" />
     <link
       rel="stylesheet"
-      href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css"
-      integrity="sha256-IUOUHAPazai08QFs7W4MbzTlwEWFo7z/4zw8YmxEiko="
+      href="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css"
+      integrity="sha256-MBffSnbbXwHCuZtgPYiwMQbfE7z+GOZ7fBPCNB06Z98="
       crossorigin="anonymous"
     />
     <link
       rel="stylesheet"
-      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css"
-      integrity="sha256-8M+b2Hj+vy/2J5tZ9pYDHeuPD59KsaEZn1XXj3xVhjg="
+      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1/font/bootstrap-icons.min.css"
+      integrity="sha256-6MNujrdbV0Z7S927PzUMXOmMLwkKdsdD7XIl/w89HMQ="
       crossorigin="anonymous"
     />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -159,8 +159,17 @@ <h2 class="card-title">Older versions</h2>
             </select>
           </div>
           <div class="form-check form-switch mx-4">
-            <input class="form-check-input" type="checkbox" role="switch" id="info-options-hide-passing-switch">
-            <label class="form-check-label" for="info-options-hide-passing-switch">Hide passing</label>
+            <input
+              class="form-check-input"
+              type="checkbox"
+              role="switch"
+              id="info-options-hide-passing-switch"
+            />
+            <label
+              class="form-check-label"
+              for="info-options-hide-passing-switch"
+              >Hide passing</label
+            >
           </div>
         </div>
       </form>
@@ -194,15 +203,11 @@ <h5 class="modal-title" id="modalTitle">Main branch progress</h5>
       </div>
     </div>
     <script
-      src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js"
-      integrity="sha256-h1OMS35Ij1pJ0S+Y1qBK/GHQDyankPMZVpeZrNQ062U="
-      crossorigin="anonymous"
-    ></script>
-    <script
-      src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"
-      integrity="sha256-+8RZJua0aEWg+QVVKg4LEzEEm/8RFez5Tb4JBNiV5xA="
+      src="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/js/bootstrap.min.js"
+      integrity="sha256-YMa+wAM6QkVyz999odX7lPRxkoYAan8suedu4k2Zur8="
       crossorigin="anonymous"
     ></script>
+    <script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
     <script type="module" src="./results.js"></script>
   </body>
 </html>
diff --git a/test262/refs/tags/v0.15/features.json b/test262/refs/tags/v0.15/features.json
deleted file mode 100644
index 211d57f824c..00000000000
--- a/test262/refs/tags/v0.15/features.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"c":"9e81103cdf73893abc8ec3894c0bcf3c51329b0c","u":"79e3bc5176b6f29a5aed3b7164a9c623a3a9a63b","n":"test","f":["AggregateError","Array.prototype.at","Array.prototype.flat","Array.prototype.flatMap","Array.prototype.values","ArrayBuffer","Atomics","Atomics.waitAsync","BigInt","DataView","DataView.prototype.getFloat32","DataView.prototype.getFloat64","DataView.prototype.getInt16","DataView.prototype.getInt32","DataView.prototype.getInt8","DataView.prototype.getUint16","DataView.prototype.getUint32","DataView.prototype.setUint8","FinalizationRegistry","FinalizationRegistry.prototype.cleanupSome","Float32Array","Float64Array","Int16Array","Int32Array","Int8Array","Intl-enumeration","Intl.DateTimeFormat-datetimestyle","Intl.DateTimeFormat-dayPeriod","Intl.DateTimeFormat-extend-timezonename","Intl.DateTimeFormat-formatRange","Intl.DateTimeFormat-fractionalSecondDigits","Intl.DisplayNames","Intl.DisplayNames-v2","Intl.DurationFormat","Intl.ListFormat","Intl.Locale","Intl.Locale-info","Intl.NumberFormat-unified","Intl.NumberFormat-v3","Intl.RelativeTimeFormat","Intl.Segmenter","IsHTMLDDA","Map","Object.fromEntries","Object.hasOwn","Object.is","Promise","Promise.allSettled","Promise.any","Promise.prototype.finally","Proxy","Reflect","Reflect.construct","Reflect.set","Reflect.setPrototypeOf","Set","ShadowRealm","SharedArrayBuffer","String.fromCodePoint","String.prototype.at","String.prototype.endsWith","String.prototype.includes","String.prototype.matchAll","String.prototype.replaceAll","String.prototype.trimEnd","String.prototype.trimStart","Symbol","Symbol.asyncIterator","Symbol.hasInstance","Symbol.isConcatSpreadable","Symbol.iterator","Symbol.match","Symbol.matchAll","Symbol.prototype.description","Symbol.replace","Symbol.search","Symbol.species","Symbol.split","Symbol.toPrimitive","Symbol.toStringTag","Symbol.unscopables","Temporal","TypedArray","TypedArray.prototype.at","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray","WeakMap","WeakRef","WeakSet","__getter__","__proto__","__setter__","align-detached-buffer-semantics-with-web-reality","arbitrary-module-namespace-names","array-find-from-last","array-grouping","arrow-function","async-functions","async-iteration","caller","class","class-fields-private","class-fields-private-in","class-fields-public","class-methods-private","class-static-block","class-static-fields-private","class-static-fields-public","class-static-methods-private","coalesce-expression","computed-property-names","const","cross-realm","decorators","default-parameters","destructuring-assignment","destructuring-binding","dynamic-import","error-cause","export-star-as-namespace-from-module","for-in-order","for-of","generators","globalThis","hashbang","host-gc-required","import-assertions","import.meta","intl-normative-optional","json-modules","json-superset","legacy-regexp","let","logical-assignment-operators","new.target","numeric-separator-literal","object-rest","object-spread","optional-catch-binding","optional-chaining","proxy-missing-checks","regexp-dotall","regexp-lookbehind","regexp-match-indices","regexp-named-groups","regexp-unicode-property-escapes","regexp-v-flag","resizable-arraybuffer","rest-parameters","string-trimming","super","tail-call-optimization","template","top-level-await","u180e","well-formed-json-stringify"]}]
\ No newline at end of file
diff --git a/test262/refs/tags/v0.16/features.json b/test262/refs/tags/v0.16/features.json
deleted file mode 100644
index cc43755499f..00000000000
--- a/test262/refs/tags/v0.16/features.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"c":"888cc28e1a5368295b9ec9269069c99fc9f5656e","u":"9215420deee3e5887d29f95822bf6a474c1bf728","n":"test","f":["AggregateError","Array.prototype.at","Array.prototype.flat","Array.prototype.flatMap","Array.prototype.values","ArrayBuffer","Atomics","Atomics.waitAsync","BigInt","DataView","DataView.prototype.getFloat32","DataView.prototype.getFloat64","DataView.prototype.getInt16","DataView.prototype.getInt32","DataView.prototype.getInt8","DataView.prototype.getUint16","DataView.prototype.getUint32","DataView.prototype.setUint8","FinalizationRegistry","FinalizationRegistry.prototype.cleanupSome","Float32Array","Float64Array","Int16Array","Int32Array","Int8Array","Intl-enumeration","Intl.DateTimeFormat-datetimestyle","Intl.DateTimeFormat-dayPeriod","Intl.DateTimeFormat-extend-timezonename","Intl.DateTimeFormat-formatRange","Intl.DateTimeFormat-fractionalSecondDigits","Intl.DisplayNames","Intl.DisplayNames-v2","Intl.DurationFormat","Intl.ListFormat","Intl.Locale","Intl.Locale-info","Intl.NumberFormat-unified","Intl.NumberFormat-v3","Intl.RelativeTimeFormat","Intl.Segmenter","IsHTMLDDA","Map","Object.fromEntries","Object.hasOwn","Object.is","Promise","Promise.allSettled","Promise.any","Promise.prototype.finally","Proxy","Reflect","Reflect.construct","Reflect.set","Reflect.setPrototypeOf","Set","ShadowRealm","SharedArrayBuffer","String.fromCodePoint","String.prototype.at","String.prototype.endsWith","String.prototype.includes","String.prototype.matchAll","String.prototype.replaceAll","String.prototype.trimEnd","String.prototype.trimStart","Symbol","Symbol.asyncIterator","Symbol.hasInstance","Symbol.isConcatSpreadable","Symbol.iterator","Symbol.match","Symbol.matchAll","Symbol.prototype.description","Symbol.replace","Symbol.search","Symbol.species","Symbol.split","Symbol.toPrimitive","Symbol.toStringTag","Symbol.unscopables","Temporal","TypedArray","TypedArray.prototype.at","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray","WeakMap","WeakRef","WeakSet","__getter__","__proto__","__setter__","align-detached-buffer-semantics-with-web-reality","arbitrary-module-namespace-names","array-find-from-last","array-grouping","arrow-function","async-functions","async-iteration","caller","class","class-fields-private","class-fields-private-in","class-fields-public","class-methods-private","class-static-block","class-static-fields-private","class-static-fields-public","class-static-methods-private","coalesce-expression","computed-property-names","const","cross-realm","decorators","default-parameters","destructuring-assignment","destructuring-binding","dynamic-import","error-cause","export-star-as-namespace-from-module","for-in-order","for-of","generators","globalThis","hashbang","host-gc-required","import-assertions","import.meta","intl-normative-optional","json-modules","json-superset","legacy-regexp","let","logical-assignment-operators","new.target","numeric-separator-literal","object-rest","object-spread","optional-catch-binding","optional-chaining","proxy-missing-checks","regexp-dotall","regexp-duplicate-named-groups","regexp-lookbehind","regexp-match-indices","regexp-named-groups","regexp-unicode-property-escapes","regexp-v-flag","resizable-arraybuffer","rest-parameters","string-trimming","super","tail-call-optimization","template","top-level-await","u180e","well-formed-json-stringify"]}]
\ No newline at end of file
diff --git a/test262/refs/tags/v0.17.1/features.json b/test262/refs/tags/v0.17.1/features.json
deleted file mode 100644
index 739e05b1414..00000000000
--- a/test262/refs/tags/v0.17.1/features.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"c":"3379753b17b1ba502af0cdb06397dc3f150893c1","u":"8ce9864511c1c83ba2d0b351da3390c9e33fd60e","n":"test","f":["Uint8ClampedArray","Array.prototype.flatMap","Object.fromEntries","regexp-match-indices","DataView.prototype.getFloat32","Symbol.toPrimitive","class-static-methods-private","regexp-dotall","Symbol","Array.prototype.values","class-static-fields-private","Intl.RelativeTimeFormat","error-cause","String.prototype.replaceAll","super","Float64Array","Uint8Array","legacy-regexp","string-trimming","regexp-v-flag","const","TypedArray","new.target","Symbol.matchAll","destructuring-binding","Promise.allSettled","Intl.DateTimeFormat-fractionalSecondDigits","arraybuffer-transfer","String.prototype.isWellFormed","String.prototype.includes","rest-parameters","u180e","Int32Array","iterator-helpers","for-in-order","caller","Array.prototype.includes","DataView","String.prototype.trimStart","Reflect.set","Symbol.isConcatSpreadable","Symbol.asyncIterator","__getter__","proxy-missing-checks","regexp-named-groups","destructuring-assignment","Intl.DateTimeFormat-formatRange","Intl-enumeration","Map","DataView.prototype.getInt32","String.prototype.at","Symbol.hasInstance","symbols-as-weakmap-keys","numeric-separator-literal","String.fromCodePoint","tail-call-optimization","IsHTMLDDA","for-of","decorators","class-static-fields-public","intl-normative-optional","DataView.prototype.getInt8","top-level-await","class-fields-public","let","Promise","Array.fromAsync","json-modules","DataView.prototype.setUint8","Symbol.toStringTag","SharedArrayBuffer","Symbol.split","Temporal","logical-assignment-operators","Atomics","DataView.prototype.getInt16","default-parameters","Intl.DateTimeFormat-datetimestyle","Intl.DateTimeFormat-extend-timezonename","Intl.NumberFormat-unified","class","__setter__","change-array-by-copy","Set","class-static-block","regexp-duplicate-named-groups","arbitrary-module-namespace-names","optional-catch-binding","hashbang","Symbol.unscopables","Intl.ListFormat","Symbol.iterator","class-methods-private","template","BigInt","Object.is","DataView.prototype.getUint16","optional-chaining","String.prototype.endsWith","Intl.DurationFormat","AggregateError","Atomics.waitAsync","class-fields-private-in","String.prototype.trimEnd","DataView.prototype.getFloat64","Object.hasOwn","WeakSet","arrow-function","Symbol.match","Intl.Locale","cross-realm","ShadowRealm","regexp-lookbehind","computed-property-names","Intl.NumberFormat-v3","array-find-from-last","Proxy","exponentiation","ArrayBuffer","Promise.any","well-formed-json-stringify","Symbol.replace","object-rest","export-star-as-namespace-from-module","import.meta","Symbol.species","Float32Array","Symbol.search","FinalizationRegistry","Reflect.setPrototypeOf","Promise.prototype.finally","object-spread","dynamic-import","align-detached-buffer-semantics-with-web-reality","Reflect.construct","json-superset","Array.prototype.flat","Intl.DateTimeFormat-dayPeriod","Reflect","Symbol.prototype.description","array-grouping","host-gc-required","FinalizationRegistry.prototype.cleanupSome","Intl.Locale-info","Uint16Array","async-iteration","TypedArray.prototype.at","resizable-arraybuffer","Intl.Segmenter","WeakMap","String.prototype.toWellFormed","WeakRef","globalThis","String.prototype.matchAll","__proto__","DataView.prototype.getUint32","json-parse-with-source","Uint32Array","coalesce-expression","regexp-unicode-property-escapes","async-functions","generators","Int16Array","Intl.DisplayNames","Array.prototype.at","Intl.DisplayNames-v2","import-assertions","Int8Array","class-fields-private"]}]
\ No newline at end of file
diff --git a/test262/refs/tags/v0.17.2/features.json b/test262/refs/tags/v0.17.2/features.json
deleted file mode 100644
index 10f84b20afb..00000000000
--- a/test262/refs/tags/v0.17.2/features.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"c":"40241c09374581e19f0f6a4866de16c231b23296","u":"8ce9864511c1c83ba2d0b351da3390c9e33fd60e","n":"test","f":["Uint8ClampedArray","Array.prototype.flatMap","Object.fromEntries","regexp-match-indices","DataView.prototype.getFloat32","Symbol.toPrimitive","class-static-methods-private","regexp-dotall","Symbol","Array.prototype.values","class-static-fields-private","Intl.RelativeTimeFormat","error-cause","String.prototype.replaceAll","super","Float64Array","Uint8Array","legacy-regexp","string-trimming","regexp-v-flag","const","TypedArray","new.target","Symbol.matchAll","destructuring-binding","Promise.allSettled","Intl.DateTimeFormat-fractionalSecondDigits","arraybuffer-transfer","String.prototype.isWellFormed","String.prototype.includes","rest-parameters","u180e","Int32Array","iterator-helpers","for-in-order","caller","Array.prototype.includes","DataView","String.prototype.trimStart","Reflect.set","Symbol.isConcatSpreadable","Symbol.asyncIterator","__getter__","proxy-missing-checks","regexp-named-groups","destructuring-assignment","Intl.DateTimeFormat-formatRange","Intl-enumeration","Map","DataView.prototype.getInt32","String.prototype.at","Symbol.hasInstance","symbols-as-weakmap-keys","numeric-separator-literal","String.fromCodePoint","tail-call-optimization","IsHTMLDDA","for-of","decorators","class-static-fields-public","intl-normative-optional","DataView.prototype.getInt8","top-level-await","class-fields-public","let","Promise","Array.fromAsync","json-modules","DataView.prototype.setUint8","Symbol.toStringTag","SharedArrayBuffer","Symbol.split","Temporal","logical-assignment-operators","Atomics","DataView.prototype.getInt16","default-parameters","Intl.DateTimeFormat-datetimestyle","Intl.DateTimeFormat-extend-timezonename","Intl.NumberFormat-unified","class","__setter__","change-array-by-copy","Set","class-static-block","regexp-duplicate-named-groups","arbitrary-module-namespace-names","optional-catch-binding","hashbang","Symbol.unscopables","Intl.ListFormat","Symbol.iterator","class-methods-private","template","BigInt","Object.is","DataView.prototype.getUint16","optional-chaining","String.prototype.endsWith","Intl.DurationFormat","AggregateError","Atomics.waitAsync","class-fields-private-in","String.prototype.trimEnd","DataView.prototype.getFloat64","Object.hasOwn","WeakSet","arrow-function","Symbol.match","Intl.Locale","cross-realm","ShadowRealm","regexp-lookbehind","computed-property-names","Intl.NumberFormat-v3","array-find-from-last","Proxy","exponentiation","ArrayBuffer","Promise.any","well-formed-json-stringify","Symbol.replace","object-rest","export-star-as-namespace-from-module","import.meta","Symbol.species","Float32Array","Symbol.search","FinalizationRegistry","Reflect.setPrototypeOf","Promise.prototype.finally","object-spread","dynamic-import","align-detached-buffer-semantics-with-web-reality","Reflect.construct","json-superset","Array.prototype.flat","Intl.DateTimeFormat-dayPeriod","Reflect","Symbol.prototype.description","array-grouping","host-gc-required","FinalizationRegistry.prototype.cleanupSome","Intl.Locale-info","Uint16Array","async-iteration","TypedArray.prototype.at","resizable-arraybuffer","Intl.Segmenter","WeakMap","String.prototype.toWellFormed","WeakRef","globalThis","String.prototype.matchAll","__proto__","DataView.prototype.getUint32","json-parse-with-source","Uint32Array","coalesce-expression","regexp-unicode-property-escapes","async-functions","generators","Int16Array","Intl.DisplayNames","Array.prototype.at","Intl.DisplayNames-v2","import-assertions","Int8Array","class-fields-private"]}]
\ No newline at end of file
diff --git a/test262/refs/tags/v0.17.3/features.json b/test262/refs/tags/v0.17.3/features.json
deleted file mode 100644
index 7a3ce481f83..00000000000
--- a/test262/refs/tags/v0.17.3/features.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"c":"60086838665545aa8f9361b76642616898e42853","u":"8ce9864511c1c83ba2d0b351da3390c9e33fd60e","n":"test","f":["Uint8ClampedArray","Array.prototype.flatMap","Object.fromEntries","regexp-match-indices","DataView.prototype.getFloat32","Symbol.toPrimitive","class-static-methods-private","regexp-dotall","Symbol","Array.prototype.values","Intl.RelativeTimeFormat","class-static-fields-private","super","error-cause","String.prototype.replaceAll","Float64Array","Uint8Array","legacy-regexp","string-trimming","const","regexp-v-flag","TypedArray","new.target","Symbol.matchAll","destructuring-binding","Intl.DateTimeFormat-fractionalSecondDigits","Promise.allSettled","arraybuffer-transfer","String.prototype.isWellFormed","String.prototype.includes","rest-parameters","u180e","Int32Array","caller","for-in-order","iterator-helpers","Array.prototype.includes","Symbol.asyncIterator","DataView","Intl.DateTimeFormat-formatRange","regexp-named-groups","Reflect.set","String.prototype.trimStart","destructuring-assignment","Intl-enumeration","Symbol.isConcatSpreadable","__getter__","proxy-missing-checks","Map","DataView.prototype.getInt32","Symbol.hasInstance","symbols-as-weakmap-keys","String.prototype.at","numeric-separator-literal","tail-call-optimization","decorators","String.fromCodePoint","for-of","IsHTMLDDA","intl-normative-optional","class-static-fields-public","DataView.prototype.getInt8","top-level-await","let","class-fields-public","Promise","json-modules","Array.fromAsync","DataView.prototype.setUint8","Symbol.toStringTag","Temporal","SharedArrayBuffer","Symbol.split","logical-assignment-operators","Intl.DateTimeFormat-datetimestyle","Intl.DateTimeFormat-extend-timezonename","default-parameters","DataView.prototype.getInt16","Intl.NumberFormat-unified","Atomics","class","optional-catch-binding","change-array-by-copy","class-static-block","Set","hashbang","arbitrary-module-namespace-names","__setter__","regexp-duplicate-named-groups","Symbol.unscopables","Intl.ListFormat","class-methods-private","Symbol.iterator","template","BigInt","optional-chaining","DataView.prototype.getUint16","Intl.DurationFormat","Object.is","String.prototype.endsWith","AggregateError","Atomics.waitAsync","class-fields-private-in","String.prototype.trimEnd","DataView.prototype.getFloat64","Object.hasOwn","WeakSet","arrow-function","Intl.Locale","Symbol.match","cross-realm","ShadowRealm","regexp-lookbehind","computed-property-names","Intl.NumberFormat-v3","array-find-from-last","Proxy","exponentiation","ArrayBuffer","Promise.any","well-formed-json-stringify","Symbol.replace","object-rest","export-star-as-namespace-from-module","import.meta","object-spread","Float32Array","Symbol.species","dynamic-import","FinalizationRegistry","Reflect.setPrototypeOf","Symbol.search","Promise.prototype.finally","align-detached-buffer-semantics-with-web-reality","Reflect.construct","json-superset","Array.prototype.flat","Intl.DateTimeFormat-dayPeriod","Reflect","Intl.Locale-info","Symbol.prototype.description","host-gc-required","array-grouping","FinalizationRegistry.prototype.cleanupSome","Uint16Array","async-iteration","Intl.Segmenter","TypedArray.prototype.at","resizable-arraybuffer","WeakMap","String.prototype.toWellFormed","globalThis","WeakRef","String.prototype.matchAll","Uint32Array","__proto__","DataView.prototype.getUint32","json-parse-with-source","coalesce-expression","regexp-unicode-property-escapes","async-functions","generators","Int16Array","Intl.DisplayNames-v2","Intl.DisplayNames","Array.prototype.at","import-assertions","Int8Array","class-fields-private"]}]
\ No newline at end of file
diff --git a/test262/refs/tags/v0.17/features.json b/test262/refs/tags/v0.17/features.json
deleted file mode 100644
index aa6ca6f4e32..00000000000
--- a/test262/refs/tags/v0.17/features.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"c":"e027932ae2da3f548b28f9fafc4d12b04f69d0e4","u":"8ce9864511c1c83ba2d0b351da3390c9e33fd60e","n":"test","f":["Uint8ClampedArray","Array.prototype.flatMap","Object.fromEntries","regexp-match-indices","DataView.prototype.getFloat32","Symbol.toPrimitive","class-static-methods-private","regexp-dotall","Symbol","Array.prototype.values","Intl.RelativeTimeFormat","class-static-fields-private","error-cause","String.prototype.replaceAll","super","Float64Array","Uint8Array","legacy-regexp","string-trimming","regexp-v-flag","const","TypedArray","new.target","Symbol.matchAll","destructuring-binding","Promise.allSettled","Intl.DateTimeFormat-fractionalSecondDigits","arraybuffer-transfer","String.prototype.isWellFormed","String.prototype.includes","rest-parameters","u180e","iterator-helpers","caller","for-in-order","Int32Array","Array.prototype.includes","Symbol.asyncIterator","DataView","Reflect.set","Symbol.isConcatSpreadable","String.prototype.trimStart","regexp-named-groups","__getter__","proxy-missing-checks","Intl.DateTimeFormat-formatRange","Intl-enumeration","destructuring-assignment","Map","DataView.prototype.getInt32","Symbol.hasInstance","symbols-as-weakmap-keys","String.prototype.at","numeric-separator-literal","String.fromCodePoint","tail-call-optimization","decorators","for-of","IsHTMLDDA","intl-normative-optional","class-static-fields-public","DataView.prototype.getInt8","top-level-await","let","class-fields-public","Promise","Array.fromAsync","json-modules","DataView.prototype.setUint8","Temporal","Symbol.toStringTag","SharedArrayBuffer","Symbol.split","logical-assignment-operators","Atomics","DataView.prototype.getInt16","Intl.DateTimeFormat-datetimestyle","Intl.DateTimeFormat-extend-timezonename","Intl.NumberFormat-unified","default-parameters","class","change-array-by-copy","__setter__","Set","class-static-block","regexp-duplicate-named-groups","optional-catch-binding","hashbang","arbitrary-module-namespace-names","Symbol.unscopables","Intl.ListFormat","Symbol.iterator","class-methods-private","template","BigInt","DataView.prototype.getUint16","Object.is","Intl.DurationFormat","String.prototype.endsWith","optional-chaining","AggregateError","Atomics.waitAsync","class-fields-private-in","String.prototype.trimEnd","DataView.prototype.getFloat64","Object.hasOwn","WeakSet","arrow-function","Symbol.match","Intl.Locale","cross-realm","regexp-lookbehind","ShadowRealm","computed-property-names","Intl.NumberFormat-v3","array-find-from-last","Proxy","exponentiation","ArrayBuffer","Promise.any","well-formed-json-stringify","Symbol.replace","object-rest","export-star-as-namespace-from-module","import.meta","Symbol.species","Float32Array","Symbol.search","Promise.prototype.finally","Reflect.setPrototypeOf","FinalizationRegistry","object-spread","dynamic-import","align-detached-buffer-semantics-with-web-reality","Reflect.construct","json-superset","Array.prototype.flat","Intl.DateTimeFormat-dayPeriod","Reflect","Symbol.prototype.description","array-grouping","host-gc-required","FinalizationRegistry.prototype.cleanupSome","Intl.Locale-info","Uint16Array","async-iteration","TypedArray.prototype.at","resizable-arraybuffer","Intl.Segmenter","WeakMap","String.prototype.toWellFormed","globalThis","WeakRef","String.prototype.matchAll","DataView.prototype.getUint32","__proto__","json-parse-with-source","Uint32Array","coalesce-expression","regexp-unicode-property-escapes","async-functions","generators","Int16Array","Intl.DisplayNames-v2","Array.prototype.at","Intl.DisplayNames","import-assertions","Int8Array","class-fields-private"]}]
\ No newline at end of file
diff --git a/test262/results.js b/test262/results.js
index c66b4bc3e9b..d9db3b5b080 100644
--- a/test262/results.js
+++ b/test262/results.js
@@ -1,31 +1,30 @@
+const ignored = ["v0.17.1", "v0.17.2"];
+
 const formatter = new Intl.NumberFormat("en-GB");
 const esVersionPicker = document.getElementById("info-options-es-version");
-const hidePassingSwitch = document.getElementById("info-options-hide-passing-switch");
+const hidePassingSwitch = document.getElementById(
+  "info-options-hide-passing-switch"
+);
 
 let hidePassingSuites = false;
 let currentData = null;
 let esVersion = 255;
 
 hidePassingSwitch.checked = false;
-hidePassingSwitch
-  .addEventListener("change", () => {
-    hidePassingSuites = !hidePassingSuites;
-    showData(currentData);
-  });
+hidePassingSwitch.addEventListener("change", () => {
+  hidePassingSuites = !hidePassingSuites;
+  showData(currentData);
+});
 
-esVersionPicker.getElementsByTagName('option')[0].selected = true;
+esVersionPicker.getElementsByTagName("option")[0].selected = true;
 esVersionPicker.disabled = false;
 esVersionPicker.addEventListener("change", () => {
   const version = Number.parseInt(esVersionPicker.value);
-  console.log(`selected version: ${version}`);
-
   esVersion = version;
 
-  showData(currentData)
+  showData(currentData);
 });
 
-
-
 loadMainData();
 loadMainResults();
 
@@ -40,6 +39,11 @@ loadLatestVersionResults(latestTag);
 const releaseTags = [];
 for (const release of releases) {
   const tag = release.tag_name;
+
+  if (ignored.includes(tag)) {
+    continue;
+  }
+
   const version = tag.split(".");
 
   // We know there is no data for versions lower than v0.10.
@@ -56,7 +60,7 @@ const versionListHTMLItems = await Promise.all(
   releaseTags.map(async (tag) => {
     const response = await fetch(`./refs/tags/${tag}/latest.json`);
     const json = await response.json();
-    const stats = json.r.a;
+    const stats = json.a;
 
     releaseData.set(tag, json);
 
@@ -68,18 +72,19 @@ const versionListHTMLItems = await Promise.all(
         <span class="text-warning">${formatter.format(stats.i)}</span>
         /
         <span class="text-danger">${formatter.format(
-      stats.t - stats.o - stats.i
-    )}
-        ${json.r.p !== 0
-        ? ` (${formatter.format(
-          stats.p
-        )} <i class="bi-exclamation-triangle"></i>)`
-        : ""
-      }</span>
+          stats.t - stats.o - stats.i
+        )}
+        ${
+          stats.p !== 0
+            ? ` (${formatter.format(
+                stats.p
+              )} <i class="bi-exclamation-triangle"></i>)`
+            : ""
+        }</span>
         /
         <b>${formatter.format(
-        Math.round((10000 * stats.o) / stats.t) / 100
-      )}%</b>
+          Math.round((10000 * stats.o) / stats.t) / 100
+        )}%</b>
       </div>
       <button type="button" class="btn btn-outline-primary" id="old-version-${tag}">
         Test Results
@@ -124,41 +129,40 @@ async function loadMainResults() {
     type: "line",
     data: {
       labels: data.map((data) => data.a.t),
-      datasets:
-        [
-          {
-            label: "Passed",
-            data: data.map((data) => data.a.o),
-            backgroundColor: "#1fcb4a",
-            borderColor: "#0f6524",
-            borderWidth: 1,
-            fill: true,
-          },
-          {
-            label: "Ignored",
-            data: data.map((data) => data.a.i),
-            backgroundColor: "#dfa800",
-            borderColor: "#6f5400",
-            borderWidth: 1,
-            fill: true,
-          },
-          {
-            label: "Panics",
-            data: data.map((data) => data.a.p),
-            backgroundColor: "#a30000",
-            borderColor: "#510000",
-            borderWidth: 1,
-            fill: true,
-          },
-          {
-            label: "Failed",
-            data: data.map((data) => data.a.t - data.a.i - data.a.o - data.a.p),
-            backgroundColor: "#ff4848",
-            borderColor: "#a30000",
-            borderWidth: 1,
-            fill: true,
-          },
-        ],
+      datasets: [
+        {
+          label: "Passed",
+          data: data.map((data) => data.a.o),
+          backgroundColor: "#1fcb4a",
+          borderColor: "#0f6524",
+          borderWidth: 1,
+          fill: true,
+        },
+        {
+          label: "Ignored",
+          data: data.map((data) => data.a.i),
+          backgroundColor: "#dfa800",
+          borderColor: "#6f5400",
+          borderWidth: 1,
+          fill: true,
+        },
+        {
+          label: "Panics",
+          data: data.map((data) => data.a.p),
+          backgroundColor: "#a30000",
+          borderColor: "#510000",
+          borderWidth: 1,
+          fill: true,
+        },
+        {
+          label: "Failed",
+          data: data.map((data) => data.a.t - data.a.i - data.a.o - data.a.p),
+          backgroundColor: "#ff4848",
+          borderColor: "#a30000",
+          borderWidth: 1,
+          fill: true,
+        },
+      ],
     },
     options: {
       elements: {
@@ -212,32 +216,34 @@ function createInfoFromResults(resultsData, nodeID) {
     "afterbegin",
     `
     <li class="list-group-item">
-      Latest commit: <a href="https://github.com/boa-dev/boa/commit/${latest.c
-    }" title="Check commit">${latest.c}</a>
+      Latest commit: <a href="https://github.com/boa-dev/boa/commit/${
+        latest.c
+      }" title="Check commit">${latest.c}</a>
     </li>
     <li class="list-group-item">
       Total tests: <span>${formatter.format(stats.t)}</span>
     </li>
     <li class="list-group-item">
       Passed tests: <span class="text-success">${formatter.format(
-      stats.o
-    )}</span>
+        stats.o
+      )}</span>
     </li>
     <li class="list-group-item">
       Ignored tests: <span class="text-warning">${formatter.format(
-      stats.i
-    )}</span>
+        stats.i
+      )}</span>
     </li>
     <li class="list-group-item">
       Failed tests: <span class="text-danger">${formatter.format(
-      stats.t - stats.o - stats.i
-    )}
-      ${stats.p !== 0
-      ? ` (${formatter.format(
-        stats.p
-      )} <i class="bi-exclamation-triangle"></i>)`
-      : ""
-    }</span>
+        stats.t - stats.o - stats.i
+      )}
+      ${
+        stats.p !== 0
+          ? ` (${formatter.format(
+              stats.p
+            )} <i class="bi-exclamation-triangle"></i>)`
+          : ""
+      }</span>
     </li>
     <li class="list-group-item">
       Conformance: <b>${Math.round((10000 * stats.o) / stats.t) / 100}%</b>
@@ -254,9 +260,10 @@ function showData(data) {
   const infoOptionsContainer = document.getElementById("info-options");
   const progressInfoContainer = document.getElementById("progress-info");
 
-  const stats = data.r.a;
-  if (!data.r.av) {
-    esVersionPicker.getElementsByTagName('option')[0].selected = true;
+  const stats = data.a;
+
+  if (!data.v) {
+    esVersionPicker.getElementsByTagName("option")[0].selected = true;
     esVersionPicker.disabled = true;
   } else {
     esVersionPicker.disabled = false;
@@ -295,26 +302,29 @@ function showData(data) {
     ></div>
   </div>`;
 
-  for (const suite of data.r.s) {
-    addSuite(suite, "info", "test/" + suite.n, data.u);
+  for (const suiteName in data.r) {
+    addSuite(suiteName, data.r[suiteName], "info", "test/" + suiteName, data.u);
   }
 }
 
-function addSuite(suite, parentID, namespace, upstream) {
-
+function addSuite(suiteName, suite, parentID, namespace, upstream) {
   function shouldDisplayTest(test) {
-    if (hidePassingSuites && test.r === "O") {
+    if (
+      hidePassingSuites &&
+      (typeof test.r === "undefined" || test.r === "O") &&
+      (typeof test.s === "undefined" || test.s === "O")
+    ) {
       return false;
     }
     return test.v ? test.v <= esVersion : true;
   }
 
   function shouldDisplaySuite(suite) {
-    const tests = suite.t ?? [];
-    const subSuites = suite.s ?? [];
+    const tests = suite.t ?? {};
+    const subSuites = suite.s ?? {};
 
-    const hasTests = tests.some(shouldDisplayTest);
-    const hasSubSuites = subSuites.some(shouldDisplaySuite);
+    const hasTests = Object.values(tests).some(shouldDisplayTest);
+    const hasSubSuites = Object.values(subSuites).some(shouldDisplaySuite);
 
     return hasTests || hasSubSuites;
   }
@@ -324,7 +334,7 @@ function addSuite(suite, parentID, namespace, upstream) {
       return suite.a;
     }
 
-    const versioned_stats = suite.av;
+    const versioned_stats = suite.v;
     if (!versioned_stats) {
       return suite.a;
     }
@@ -332,8 +342,8 @@ function addSuite(suite, parentID, namespace, upstream) {
     let version = esVersion;
 
     while (version >= 5) {
-      if (versioned_stats["es" + version]) {
-        return versioned_stats["es" + version];
+      if (versioned_stats[version]) {
+        return versioned_stats[version];
       }
 
       version -= 1;
@@ -342,16 +352,23 @@ function addSuite(suite, parentID, namespace, upstream) {
     return suite.a;
   }
 
-
   if (!shouldDisplaySuite(suite)) {
     return;
   }
 
   const stats = findStats(suite);
-  const tests = suite.t ? suite.t.filter(shouldDisplayTest) : [];
+
+  const tests = suite.t
+    ? Object.keys(suite.t).reduce((r, k) => {
+        if (shouldDisplayTest(suite.t[k])) {
+          r[k] = suite.t[k];
+        }
+        return r;
+      }, {})
+    : [];
   const subSuites = suite.s ?? [];
 
-  const newID = (parentID + suite.n).replaceAll(".", "-");
+  const newID = (parentID + suiteName).replaceAll(".", "-");
   const newInnerID = newID + "-inner";
   const headerID = newID + "header";
 
@@ -366,20 +383,21 @@ function addSuite(suite, parentID, namespace, upstream) {
         data-bs-target="#${newID}"
       >
         <span class="data-overview">
-          <span class="name">${suite.n}</span>
+          <span class="name">${suiteName}</span>
           <span class="text-success">${formatter.format(stats.o)}</span>
           /
           <span class="text-warning">${formatter.format(stats.i)}</span>
           /
           <span class="text-danger">${formatter.format(
-    stats.t - stats.o - stats.i
-  )}
-          ${stats.p !== 0
-      ? ` (${formatter.format(
-        stats.p
-      )} <i class="bi-exclamation-triangle"></i>)`
-      : ""
-    }</span>
+            stats.t - stats.o - stats.i
+          )}
+          ${
+            stats.p !== 0
+              ? ` (${formatter.format(
+                  stats.p
+                )} <i class="bi-exclamation-triangle"></i>)`
+              : ""
+          }</span>
           /
           <span>${formatter.format(stats.t)}</span>
         </span>
@@ -399,31 +417,31 @@ function addSuite(suite, parentID, namespace, upstream) {
   newContainer.addEventListener("show.bs.collapse", (event) => {
     event.stopPropagation();
 
-    if (tests.length != 0) {
-      const rows = tests
-        .map((innerTest) => {
-          const panics = innerTest.r === "P";
-          let style;
-          switch (innerTest.r) {
-            case "O":
-              style = "bg-success";
-              break;
-            case "I":
-              style = "bg-warning";
-              break;
-            default:
-              style = "bg-danger";
-          }
-
-          return `<a
-            title="${innerTest.n}"
-            class="card test embed-responsive ${style}${panics ? "" : " embed-responsive-1by1"
-            }"
+    if (Object.keys(tests).length != 0) {
+      const rows = Object.keys(tests).map((testName) => {
+        const innerTest = tests[testName];
+        const panics = innerTest.r === "P" || innerTest.s === "P";
+        const passes = innerTest.r === "O" || innerTest.s === "O";
+        const ignored = innerTest.r === "I" || innerTest.s === "I";
+
+        let style;
+        if (passes) {
+          style = "bg-success";
+        } else if (ignored) {
+          style = "bg-warning";
+        } else {
+          style = "bg-danger";
+        }
+
+        return `<a
+            title="${testName}"
+            class="card test embed-responsive ${style}${
+          panics ? "" : " embed-responsive-1by1"
+        }"
             target="_blank"
-            href="https://github.com/tc39/test262/blob/${upstream}/${namespace}/${innerTest.n
-            }.js"
+            href="https://github.com/tc39/test262/blob/${upstream}/${namespace}/${testName}.js"
           >${panics ? '<i class="bi-exclamation-triangle"></i>' : ""}</a>`;
-        });
+      });
 
       const testsHTML = `<div class="card">
           <div class="row card-body">
@@ -434,11 +452,12 @@ function addSuite(suite, parentID, namespace, upstream) {
 
       newInnerContainer.insertAdjacentHTML("beforeend", testsHTML);
     }
-    for (const innerSuite of subSuites) {
+    for (const innerSuite in subSuites) {
       addSuite(
         innerSuite,
+        subSuites[innerSuite],
         newInnerID,
-        namespace + "/" + innerSuite.n,
+        namespace + "/" + innerSuite,
         upstream
       );
     }