From 940947299f07fd8831187c25f693541362a77f0d Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2026 17:13:16 -0700 Subject: [PATCH 01/19] Update all npm dependencies (2026-07-28) (#1072) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⬆️ Update all npm dependencies (2026-07-28) * Fix @typescript-eslint/unbound-method errors in tests after typescript-eslint 8.65 bump --------- Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Carla Severe --- package-lock.json | 518 +++++++++--------- package.json | 8 +- .../CompareResults/ResultsView.test.tsx | 10 +- .../SubtestsResultsView.test.tsx | 10 +- .../TaskclusterCallback.test.tsx | 14 +- 5 files changed, 282 insertions(+), 278 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b4a936bc..13c4fd221 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "react-dom": "^19.2.7", "react-redux": "^9.3.0", "react-router": "^7.18.1", - "react-virtuoso": "^4.18.10", + "react-virtuoso": "^4.18.11", "stream-browserify": "^3.0.0", "taskcluster-client-web": "^87.1.3", "taskcluster-lib-scopes": "^11.0.0", @@ -47,10 +47,10 @@ "@eslint/js": "^9.39.5", "@fetch-mock/jest": "^0.2.20", "@jest/types": "^30.4.1", - "@swc/core": "^1.15.43", + "@swc/core": "^1.15.46", "@swc/jest": "^0.2.39", "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.9.1", + "@testing-library/jest-dom": "^6.10.0", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", @@ -90,7 +90,7 @@ "ts-loader": "^9.6.2", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "typescript-eslint": "^8.62.1", + "typescript-eslint": "^8.65.0", "webpack": "^5.108.4", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.6", @@ -3948,9 +3948,9 @@ "license": "MIT" }, "node_modules/@swc/core": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.43.tgz", - "integrity": "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.46.tgz", + "integrity": "sha512-Ri3em2mBpq3h2zSPliCYl63otDGqek8PPEfv2nWgRQEbZ/VBCNyypVTVQ6cEbTCXBhy+WE2T3fQb08moIyuYaw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3965,18 +3965,18 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.43", - "@swc/core-darwin-x64": "1.15.43", - "@swc/core-linux-arm-gnueabihf": "1.15.43", - "@swc/core-linux-arm64-gnu": "1.15.43", - "@swc/core-linux-arm64-musl": "1.15.43", - "@swc/core-linux-ppc64-gnu": "1.15.43", - "@swc/core-linux-s390x-gnu": "1.15.43", - "@swc/core-linux-x64-gnu": "1.15.43", - "@swc/core-linux-x64-musl": "1.15.43", - "@swc/core-win32-arm64-msvc": "1.15.43", - "@swc/core-win32-ia32-msvc": "1.15.43", - "@swc/core-win32-x64-msvc": "1.15.43" + "@swc/core-darwin-arm64": "1.15.46", + "@swc/core-darwin-x64": "1.15.46", + "@swc/core-linux-arm-gnueabihf": "1.15.46", + "@swc/core-linux-arm64-gnu": "1.15.46", + "@swc/core-linux-arm64-musl": "1.15.46", + "@swc/core-linux-ppc64-gnu": "1.15.46", + "@swc/core-linux-s390x-gnu": "1.15.46", + "@swc/core-linux-x64-gnu": "1.15.46", + "@swc/core-linux-x64-musl": "1.15.46", + "@swc/core-win32-arm64-msvc": "1.15.46", + "@swc/core-win32-ia32-msvc": "1.15.46", + "@swc/core-win32-x64-msvc": "1.15.46" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" @@ -3988,9 +3988,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.43.tgz", - "integrity": "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.46.tgz", + "integrity": "sha512-IsISIT22EfktVJrlvIpnAxG2u/A9aob9l99HMlx80x72WlFmFPk1V3UhkEzx86eJP8hw049KTFv/RISho2cq2Q==", "cpu": [ "arm64" ], @@ -4004,9 +4004,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.43.tgz", - "integrity": "sha512-lp3d4Lamc8dt5huYdGLSR+9hLxmfr1jb0l+4XXG2zPqZwYWRN9R0U2qYoTrggiU2RWW0oV9VbWM3kBnqIc2kdQ==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.46.tgz", + "integrity": "sha512-4Tj4ppVIPCmUMpmGFiGtyEriwLyJ+yi/US4WfBrP/ok8COGddDZXLEzQETnKyK46mjvr1v0jevrS23zjoff7vA==", "cpu": [ "x64" ], @@ -4020,9 +4020,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.43.tgz", - "integrity": "sha512-JWTQQELtsG5GgphDrr/XqqmM2pDN3cZqbMS0Mrg+iTiXL3F74sn/S2IyYE/5u4h2KLkTf9qQ7dXyxsbx7YzkeA==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.46.tgz", + "integrity": "sha512-i8tUGnNjyOgMmfmgFSg4aeJLQoFyfpIHK5FjpQAwpRyQIqEUB2w1e8zIDQzY1WhOxx8NoS1S5iUL813Un4Sf5A==", "cpu": [ "arm" ], @@ -4036,9 +4036,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.43.tgz", - "integrity": "sha512-B4otJRdPWIsmiSBf0uG7Z/+vMWmkufjz5MmYxubwKuZazDW14Zd3symga1N62QR4RT+kEFeHEgsXfZGyn/w0hw==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.46.tgz", + "integrity": "sha512-c0OnhqzdhfOvv6qhNCcByepB+sNYOGZyhtr2Qa6ZCHvAWTYhSRw4j/u92Stue9PbZ/6q74b9nHzi76+kVzqQHQ==", "cpu": [ "arm64" ], @@ -4052,9 +4052,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.43.tgz", - "integrity": "sha512-6zB6OnpViBxYy4tgY3v2i6AZY9fwkcHZ032UOwtwUuW1d19sdT07qF0kZe6/3UR1tUaK6jjg2rmVcUIBCEYVjQ==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.46.tgz", + "integrity": "sha512-imyRpNEcUzFQFV2LE4jL68ErvmKEuZCbvZru77iQREunJ+bR4i658cupTgtG1mLYM3F1Tzy3Sb9xYb02KghWTg==", "cpu": [ "arm64" ], @@ -4068,9 +4068,9 @@ } }, "node_modules/@swc/core-linux-ppc64-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.43.tgz", - "integrity": "sha512-coxE1ZWdB3uSDVNoEtYNrRi/1epvckZx9cTJ8ICUxTMTxGk+yvQ/Twacp3ruZSaMPGCriUjP86C37VhaT6nyRg==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.46.tgz", + "integrity": "sha512-ctEfcl/HcUeomK33cbySiHZm98GEDIxTm1EkpBsYCiHxElYBzvTXVeuQT2YwbUXn9XCrjiw4ipyUNk33k26qRg==", "cpu": [ "ppc64" ], @@ -4084,9 +4084,9 @@ } }, "node_modules/@swc/core-linux-s390x-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.43.tgz", - "integrity": "sha512-lXfLhs+LpBsD5inuYx+YDH5WsPPBQ95KPUiy8P5wq9ob9xKDZFqwNfU2QW6bGO8NqRO/H9JQomTSt5Yyh+FGfA==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.46.tgz", + "integrity": "sha512-DxlMdnt84TtRVTv7WL/thWyz9+QU8QZNNoAP9rrk0P68LziuhfePp8MjQ44zIprpTHTsEwyziIuGUUN5iSC1bQ==", "cpu": [ "s390x" ], @@ -4100,9 +4100,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.43.tgz", - "integrity": "sha512-07XnKwTmKy8TGOZG3D9fRnLWGynxPjwQnZLVmBFbo6F+7vHYzBIOuwXEhemrChBWb6yDNZsVCcMWCPX6FDD2xg==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.46.tgz", + "integrity": "sha512-SKxI7J6t90XPl8hRUqtJi9NfGdunN/E/vZMc7Bc0figeRdOPDBT+Tm8g7cx9xM0T0mewh2l+8dewa3Am27/P+A==", "cpu": [ "x64" ], @@ -4116,9 +4116,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.43.tgz", - "integrity": "sha512-TJc+bsSIaBh+hZvZ5GRtW/K1bw66TJ9vsUwvVIsZdiWxU5ObLwZvfcnZ3UpgVfMnFibRes9uriJrQNBHEEogRQ==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.46.tgz", + "integrity": "sha512-qj9T6B7bosI0VEsrWOVXZN1OXxS8Tp63ywyrLxNdOycnUtLdkgYcoBsN5y8ImnDDsnwrEWZOy1e+J4xSe7mA3Q==", "cpu": [ "x64" ], @@ -4132,9 +4132,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.43.tgz", - "integrity": "sha512-jfd7s2/bUQYkOHLs+LWQNKZdmDa8+sufKLllhpWAhVQ2GDCwsHe3vR/j+OSiItZNtkzFuaawa3+SAKz9y5gYfw==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.46.tgz", + "integrity": "sha512-8p7l4c3LU+eA5g9Et1JPhNeMC1oQwXTGU+uah8DPIBX7YXzqswvaBtyKVmXefVGi/DJU1x3YJsc3mbAp9aWzSQ==", "cpu": [ "arm64" ], @@ -4148,9 +4148,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.43.tgz", - "integrity": "sha512-rLAE8JvucqEW1ZGohxPQrQWPBQeJG4+ypKbWfdlU/qmKScvCkxf9/Jxnzki1dkUQCQ7P5Enp13RlvqOlvx/32g==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.46.tgz", + "integrity": "sha512-tUEnfr3Bn9u6FOjUb3PN9p+09qZC2j+wNDLKHzXXZn22rqGcUqR/ohCRSS+nG9B9+X+U+3FewNEHJkTmdIvMjQ==", "cpu": [ "ia32" ], @@ -4164,9 +4164,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.43.tgz", - "integrity": "sha512-h8MLDHZcfIukwQWj03rIJZx1I0E81AYj2X7J/nGErG4nz+QAv6G1Z+peotvinL3lqpbo32tLYSMFo32/ySzxKg==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.46.tgz", + "integrity": "sha512-Vux7UDzBJYQggSuPfcl2w9iu+IJpgpRCxHzgCaVkELnAXAE4XZMOTX9HNcaNiwfeIDqdu2rkr69RuDm6wY8neA==", "cpu": [ "x64" ], @@ -4264,9 +4264,10 @@ "dev": true }, "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.10.0.tgz", + "integrity": "sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ==", + "deprecated": "Incorrect minor release with breaking changes (Node >=22 and required @testing-library/dom peer). Use 6.9.1 for the 6.x line, or upgrade to 7.0.0.", "dev": true, "dependencies": { "@adobe/css-tools": "^4.4.0", @@ -4277,9 +4278,12 @@ "redent": "^3.0.0" }, "engines": { - "node": ">=14", + "node": ">=22", "npm": ">=6", "yarn": ">=1" + }, + "peerDependencies": { + "@testing-library/dom": ">=10 <11" } }, "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { @@ -4826,16 +4830,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.1.tgz", - "integrity": "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/type-utils": "8.62.1", - "@typescript-eslint/utils": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -4848,7 +4852,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.62.1", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -4864,15 +4868,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", - "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -4888,13 +4892,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", - "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.62.1", - "@typescript-eslint/types": "^8.62.1", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -4909,13 +4913,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", - "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4926,9 +4930,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", - "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4942,14 +4946,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz", - "integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -4966,9 +4970,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", - "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4979,15 +4983,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", - "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.62.1", - "@typescript-eslint/tsconfig-utils": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -5015,24 +5019,24 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -5042,15 +5046,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz", - "integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5065,12 +5069,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", - "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -13967,9 +13971,9 @@ } }, "node_modules/react-virtuoso": { - "version": "4.18.10", - "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.18.10.tgz", - "integrity": "sha512-P6GIZ7kWAPOYB2H16yRQNgy+VF9pJOuTFw1EUc1EAtCj5WxVSAF1Sql3x3fbLwaLeBFsiPnu+3U9o6sIOyTdFw==", + "version": "4.18.11", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.18.11.tgz", + "integrity": "sha512-Qeeq9vqa5seCxACvzbQTUeq3s2/Bu+VlwOMF0jfy3E/ZKHLiXWwJpXBhv2rckqYkvm1XRVFLCBMCmqCU8JNEJg==", "peerDependencies": { "react": ">=16 || >=17 || >= 18 || >= 19", "react-dom": ">=16 || >=17 || >= 18 || >=19" @@ -16035,15 +16039,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.1.tgz", - "integrity": "sha512-vymnnM5g0AKQDSAyfP12nMIBvgwgA42syg74kkuZ4x1VuTzwQKwc5h9rGxeShCjny5o+zWAb6OEoz7XLgrIkIw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.62.1", - "@typescript-eslint/parser": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -19893,108 +19897,108 @@ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==" }, "@swc/core": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.43.tgz", - "integrity": "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw==", - "dev": true, - "requires": { - "@swc/core-darwin-arm64": "1.15.43", - "@swc/core-darwin-x64": "1.15.43", - "@swc/core-linux-arm-gnueabihf": "1.15.43", - "@swc/core-linux-arm64-gnu": "1.15.43", - "@swc/core-linux-arm64-musl": "1.15.43", - "@swc/core-linux-ppc64-gnu": "1.15.43", - "@swc/core-linux-s390x-gnu": "1.15.43", - "@swc/core-linux-x64-gnu": "1.15.43", - "@swc/core-linux-x64-musl": "1.15.43", - "@swc/core-win32-arm64-msvc": "1.15.43", - "@swc/core-win32-ia32-msvc": "1.15.43", - "@swc/core-win32-x64-msvc": "1.15.43", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.46.tgz", + "integrity": "sha512-Ri3em2mBpq3h2zSPliCYl63otDGqek8PPEfv2nWgRQEbZ/VBCNyypVTVQ6cEbTCXBhy+WE2T3fQb08moIyuYaw==", + "dev": true, + "requires": { + "@swc/core-darwin-arm64": "1.15.46", + "@swc/core-darwin-x64": "1.15.46", + "@swc/core-linux-arm-gnueabihf": "1.15.46", + "@swc/core-linux-arm64-gnu": "1.15.46", + "@swc/core-linux-arm64-musl": "1.15.46", + "@swc/core-linux-ppc64-gnu": "1.15.46", + "@swc/core-linux-s390x-gnu": "1.15.46", + "@swc/core-linux-x64-gnu": "1.15.46", + "@swc/core-linux-x64-musl": "1.15.46", + "@swc/core-win32-arm64-msvc": "1.15.46", + "@swc/core-win32-ia32-msvc": "1.15.46", + "@swc/core-win32-x64-msvc": "1.15.46", "@swc/counter": "^0.1.3", "@swc/types": "^0.1.27" } }, "@swc/core-darwin-arm64": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.43.tgz", - "integrity": "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.46.tgz", + "integrity": "sha512-IsISIT22EfktVJrlvIpnAxG2u/A9aob9l99HMlx80x72WlFmFPk1V3UhkEzx86eJP8hw049KTFv/RISho2cq2Q==", "dev": true, "optional": true }, "@swc/core-darwin-x64": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.43.tgz", - "integrity": "sha512-lp3d4Lamc8dt5huYdGLSR+9hLxmfr1jb0l+4XXG2zPqZwYWRN9R0U2qYoTrggiU2RWW0oV9VbWM3kBnqIc2kdQ==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.46.tgz", + "integrity": "sha512-4Tj4ppVIPCmUMpmGFiGtyEriwLyJ+yi/US4WfBrP/ok8COGddDZXLEzQETnKyK46mjvr1v0jevrS23zjoff7vA==", "dev": true, "optional": true }, "@swc/core-linux-arm-gnueabihf": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.43.tgz", - "integrity": "sha512-JWTQQELtsG5GgphDrr/XqqmM2pDN3cZqbMS0Mrg+iTiXL3F74sn/S2IyYE/5u4h2KLkTf9qQ7dXyxsbx7YzkeA==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.46.tgz", + "integrity": "sha512-i8tUGnNjyOgMmfmgFSg4aeJLQoFyfpIHK5FjpQAwpRyQIqEUB2w1e8zIDQzY1WhOxx8NoS1S5iUL813Un4Sf5A==", "dev": true, "optional": true }, "@swc/core-linux-arm64-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.43.tgz", - "integrity": "sha512-B4otJRdPWIsmiSBf0uG7Z/+vMWmkufjz5MmYxubwKuZazDW14Zd3symga1N62QR4RT+kEFeHEgsXfZGyn/w0hw==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.46.tgz", + "integrity": "sha512-c0OnhqzdhfOvv6qhNCcByepB+sNYOGZyhtr2Qa6ZCHvAWTYhSRw4j/u92Stue9PbZ/6q74b9nHzi76+kVzqQHQ==", "dev": true, "optional": true }, "@swc/core-linux-arm64-musl": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.43.tgz", - "integrity": "sha512-6zB6OnpViBxYy4tgY3v2i6AZY9fwkcHZ032UOwtwUuW1d19sdT07qF0kZe6/3UR1tUaK6jjg2rmVcUIBCEYVjQ==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.46.tgz", + "integrity": "sha512-imyRpNEcUzFQFV2LE4jL68ErvmKEuZCbvZru77iQREunJ+bR4i658cupTgtG1mLYM3F1Tzy3Sb9xYb02KghWTg==", "dev": true, "optional": true }, "@swc/core-linux-ppc64-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.43.tgz", - "integrity": "sha512-coxE1ZWdB3uSDVNoEtYNrRi/1epvckZx9cTJ8ICUxTMTxGk+yvQ/Twacp3ruZSaMPGCriUjP86C37VhaT6nyRg==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.46.tgz", + "integrity": "sha512-ctEfcl/HcUeomK33cbySiHZm98GEDIxTm1EkpBsYCiHxElYBzvTXVeuQT2YwbUXn9XCrjiw4ipyUNk33k26qRg==", "dev": true, "optional": true }, "@swc/core-linux-s390x-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.43.tgz", - "integrity": "sha512-lXfLhs+LpBsD5inuYx+YDH5WsPPBQ95KPUiy8P5wq9ob9xKDZFqwNfU2QW6bGO8NqRO/H9JQomTSt5Yyh+FGfA==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.46.tgz", + "integrity": "sha512-DxlMdnt84TtRVTv7WL/thWyz9+QU8QZNNoAP9rrk0P68LziuhfePp8MjQ44zIprpTHTsEwyziIuGUUN5iSC1bQ==", "dev": true, "optional": true }, "@swc/core-linux-x64-gnu": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.43.tgz", - "integrity": "sha512-07XnKwTmKy8TGOZG3D9fRnLWGynxPjwQnZLVmBFbo6F+7vHYzBIOuwXEhemrChBWb6yDNZsVCcMWCPX6FDD2xg==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.46.tgz", + "integrity": "sha512-SKxI7J6t90XPl8hRUqtJi9NfGdunN/E/vZMc7Bc0figeRdOPDBT+Tm8g7cx9xM0T0mewh2l+8dewa3Am27/P+A==", "dev": true, "optional": true }, "@swc/core-linux-x64-musl": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.43.tgz", - "integrity": "sha512-TJc+bsSIaBh+hZvZ5GRtW/K1bw66TJ9vsUwvVIsZdiWxU5ObLwZvfcnZ3UpgVfMnFibRes9uriJrQNBHEEogRQ==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.46.tgz", + "integrity": "sha512-qj9T6B7bosI0VEsrWOVXZN1OXxS8Tp63ywyrLxNdOycnUtLdkgYcoBsN5y8ImnDDsnwrEWZOy1e+J4xSe7mA3Q==", "dev": true, "optional": true }, "@swc/core-win32-arm64-msvc": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.43.tgz", - "integrity": "sha512-jfd7s2/bUQYkOHLs+LWQNKZdmDa8+sufKLllhpWAhVQ2GDCwsHe3vR/j+OSiItZNtkzFuaawa3+SAKz9y5gYfw==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.46.tgz", + "integrity": "sha512-8p7l4c3LU+eA5g9Et1JPhNeMC1oQwXTGU+uah8DPIBX7YXzqswvaBtyKVmXefVGi/DJU1x3YJsc3mbAp9aWzSQ==", "dev": true, "optional": true }, "@swc/core-win32-ia32-msvc": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.43.tgz", - "integrity": "sha512-rLAE8JvucqEW1ZGohxPQrQWPBQeJG4+ypKbWfdlU/qmKScvCkxf9/Jxnzki1dkUQCQ7P5Enp13RlvqOlvx/32g==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.46.tgz", + "integrity": "sha512-tUEnfr3Bn9u6FOjUb3PN9p+09qZC2j+wNDLKHzXXZn22rqGcUqR/ohCRSS+nG9B9+X+U+3FewNEHJkTmdIvMjQ==", "dev": true, "optional": true }, "@swc/core-win32-x64-msvc": { - "version": "1.15.43", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.43.tgz", - "integrity": "sha512-h8MLDHZcfIukwQWj03rIJZx1I0E81AYj2X7J/nGErG4nz+QAv6G1Z+peotvinL3lqpbo32tLYSMFo32/ySzxKg==", + "version": "1.15.46", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.46.tgz", + "integrity": "sha512-Vux7UDzBJYQggSuPfcl2w9iu+IJpgpRCxHzgCaVkELnAXAE4XZMOTX9HNcaNiwfeIDqdu2rkr69RuDm6wY8neA==", "dev": true, "optional": true }, @@ -20068,9 +20072,9 @@ } }, "@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.10.0.tgz", + "integrity": "sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ==", "dev": true, "requires": { "@adobe/css-tools": "^4.4.0", @@ -20558,16 +20562,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.1.tgz", - "integrity": "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/type-utils": "8.62.1", - "@typescript-eslint/utils": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -20582,75 +20586,75 @@ } }, "@typescript-eslint/parser": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", - "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" } }, "@typescript-eslint/project-service": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", - "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "requires": { - "@typescript-eslint/tsconfig-utils": "^8.62.1", - "@typescript-eslint/types": "^8.62.1", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" } }, "@typescript-eslint/scope-manager": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", - "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "requires": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" } }, "@typescript-eslint/tsconfig-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", - "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "requires": {} }, "@typescript-eslint/type-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz", - "integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "requires": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" } }, "@typescript-eslint/types": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", - "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", - "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "requires": { - "@typescript-eslint/project-service": "8.62.1", - "@typescript-eslint/tsconfig-utils": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -20665,44 +20669,44 @@ "dev": true }, "brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "requires": { "balanced-match": "^4.0.2" } }, "minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "requires": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" } } } }, "@typescript-eslint/utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz", - "integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" } }, "@typescript-eslint/visitor-keys": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", - "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "requires": { - "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "dependencies": { @@ -26892,9 +26896,9 @@ } }, "react-virtuoso": { - "version": "4.18.10", - "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.18.10.tgz", - "integrity": "sha512-P6GIZ7kWAPOYB2H16yRQNgy+VF9pJOuTFw1EUc1EAtCj5WxVSAF1Sql3x3fbLwaLeBFsiPnu+3U9o6sIOyTdFw==", + "version": "4.18.11", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.18.11.tgz", + "integrity": "sha512-Qeeq9vqa5seCxACvzbQTUeq3s2/Bu+VlwOMF0jfy3E/ZKHLiXWwJpXBhv2rckqYkvm1XRVFLCBMCmqCU8JNEJg==", "requires": {} }, "read-package-json-fast": { @@ -28352,15 +28356,15 @@ "dev": true }, "typescript-eslint": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.1.tgz", - "integrity": "sha512-vymnnM5g0AKQDSAyfP12nMIBvgwgA42syg74kkuZ4x1VuTzwQKwc5h9rGxeShCjny5o+zWAb6OEoz7XLgrIkIw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "requires": { - "@typescript-eslint/eslint-plugin": "8.62.1", - "@typescript-eslint/parser": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" } }, "typestyle": { diff --git a/package.json b/package.json index cb29b4e3f..146c9aa98 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "react-dom": "^19.2.7", "react-redux": "^9.3.0", "react-router": "^7.18.1", - "react-virtuoso": "^4.18.10", + "react-virtuoso": "^4.18.11", "stream-browserify": "^3.0.0", "taskcluster-client-web": "^87.1.3", "taskcluster-lib-scopes": "^11.0.0", @@ -89,10 +89,10 @@ "@eslint/js": "^9.39.5", "@fetch-mock/jest": "^0.2.20", "@jest/types": "^30.4.1", - "@swc/core": "^1.15.43", + "@swc/core": "^1.15.46", "@swc/jest": "^0.2.39", "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.9.1", + "@testing-library/jest-dom": "^6.10.0", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", @@ -132,7 +132,7 @@ "ts-loader": "^9.6.2", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "typescript-eslint": "^8.62.1", + "typescript-eslint": "^8.65.0", "webpack": "^5.108.4", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.6", diff --git a/src/__tests__/CompareResults/ResultsView.test.tsx b/src/__tests__/CompareResults/ResultsView.test.tsx index 9d6bb7f31..bb5f9e370 100644 --- a/src/__tests__/CompareResults/ResultsView.test.tsx +++ b/src/__tests__/CompareResults/ResultsView.test.tsx @@ -345,10 +345,8 @@ describe('Results View', () => { results: [testData[0]], }); - jest.spyOn(window, 'alert').mockImplementation(); - const mockedWindowAlert = window.alert as jest.Mock; - jest.spyOn(window, 'open').mockImplementation(); - const mockedWindowOpen = window.open as jest.Mock; + const mockedWindowAlert = jest.spyOn(window, 'alert').mockImplementation(); + const mockedWindowOpen = jest.spyOn(window, 'open').mockImplementation(); renderWithRouter( , @@ -375,7 +373,7 @@ describe('Results View', () => { await user.click(retriggerButton); await user.click(await screen.findByRole('button', { name: /Sign in/ })); - let windowOpenUrlString = mockedWindowOpen.mock.lastCall[0] as string; + let windowOpenUrlString = mockedWindowOpen.mock.lastCall![0] as string; let windowOpenUrl = new URL(windowOpenUrlString); expect(sessionStorage.requestState).toBe( windowOpenUrl.searchParams.get('state'), @@ -385,7 +383,7 @@ describe('Results View', () => { // Test requesting an authorization code from Taskcluster staging URL window.location.hash = 'taskcluster-staging'; await user.click(retriggerButton); - windowOpenUrlString = mockedWindowOpen.mock.lastCall[0] as string; + windowOpenUrlString = mockedWindowOpen.mock.lastCall![0] as string; windowOpenUrl = new URL(windowOpenUrlString); expect(sessionStorage.requestState).toBe( windowOpenUrl.searchParams.get('state'), diff --git a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx index 87e1b9081..bff3fb298 100644 --- a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx +++ b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx @@ -141,10 +141,8 @@ describe('SubtestsResultsView Component Tests', () => { const { subtestsResult } = getTestData(); const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); - jest.spyOn(window, 'alert').mockImplementation(); - const mockedWindowAlert = window.alert as jest.Mock; - jest.spyOn(window, 'open').mockImplementation(); - const mockedWindowOpen = window.open as jest.Mock; + const mockedWindowAlert = jest.spyOn(window, 'alert').mockImplementation(); + const mockedWindowOpen = jest.spyOn(window, 'open').mockImplementation(); setup({ element: ( @@ -172,7 +170,7 @@ describe('SubtestsResultsView Component Tests', () => { await user.click(retriggerButton); await user.click(await screen.findByRole('button', { name: /Sign in/ })); - let windowOpenUrlString = mockedWindowOpen.mock.lastCall[0] as string; + let windowOpenUrlString = mockedWindowOpen.mock.lastCall![0] as string; let windowOpenUrl = new URL(windowOpenUrlString); expect(sessionStorage.requestState).toBe( windowOpenUrl.searchParams.get('state'), @@ -182,7 +180,7 @@ describe('SubtestsResultsView Component Tests', () => { // Test requesting an authorization code from Taskcluster staging URL window.location.hash = 'taskcluster-staging'; await user.click(retriggerButton); - windowOpenUrlString = mockedWindowOpen.mock.lastCall[0] as string; + windowOpenUrlString = mockedWindowOpen.mock.lastCall![0] as string; windowOpenUrl = new URL(windowOpenUrlString); expect(sessionStorage.requestState).toBe( windowOpenUrl.searchParams.get('state'), diff --git a/src/__tests__/TaskclusterAuth/TaskclusterCallback.test.tsx b/src/__tests__/TaskclusterAuth/TaskclusterCallback.test.tsx index dfe8b6084..e7aa2fb8e 100644 --- a/src/__tests__/TaskclusterAuth/TaskclusterCallback.test.tsx +++ b/src/__tests__/TaskclusterAuth/TaskclusterCallback.test.tsx @@ -12,7 +12,9 @@ describe('Taskcluster Callback', () => { function setup({ inputState }: { inputState: string }) { // Make window.close a noop so that the component can be rendered after the // authentication process. - jest.spyOn(window, 'close').mockImplementation(() => {}); + const mockedWindowClose = jest + .spyOn(window, 'close') + .mockImplementation(() => {}); sessionStorage.setItem('requestState', inputState); sessionStorage.setItem( @@ -21,6 +23,8 @@ describe('Taskcluster Callback', () => { ); mockedGetLocationOrigin.mockImplementation(() => 'http://localhost:3000'); + + return { mockedWindowClose }; } it('should fetch credentials with token bearer', async () => { @@ -31,7 +35,7 @@ describe('Taskcluster Callback', () => { const returnedClientId = 'mozilla-auth0/ad|Mozilla-LDAP|ldapuser/perfcompare-localhost-3000-client-OCvzh5'; - setup({ inputState }); + const { mockedWindowClose } = setup({ inputState }); fetchMock.post( 'https://firefox-ci-tc.services.mozilla.com/login/oauth/token', @@ -61,7 +65,7 @@ describe('Taskcluster Callback', () => { await screen.findByText(/Credentials were found/), ).toBeInTheDocument(); - expect(window.fetch).toHaveFetched( + expect(global.fetch).toHaveFetched( 'https://firefox-ci-tc.services.mozilla.com/login/oauth/token', { method: 'POST', @@ -88,7 +92,7 @@ describe('Taskcluster Callback', () => { redirect_uri: 'http://localhost/taskcluster-auth', }); - expect(window.fetch).toHaveLastFetched( + expect(global.fetch).toHaveLastFetched( 'https://firefox-ci-tc.services.mozilla.com/login/oauth/credentials', { headers: { @@ -106,7 +110,7 @@ describe('Taskcluster Callback', () => { `{"https://firefox-ci-tc.services.mozilla.com":{"expires":"2024-05-20T14:07:40.828Z","credentials":{"clientId":"${returnedClientId}","accessToken":"${returnedUserToken}"}}}`, ); - expect(window.close).toHaveBeenCalled(); + expect(mockedWindowClose).toHaveBeenCalled(); }); it('should show a spinner while waiting for the credentials', async () => { From 228b9a504d7b2f406228c57dd9f590333000de34 Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2026 17:33:02 -0700 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=9A=A8=20[security]=20Update=20reac?= =?UTF-8?q?t-router=207.18.1=20=E2=86=92=208.3.0=20(major)=20(#1070)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⬆️ Update react-router to version 8.3.0 * ⬆️ Update react-router to version 8.3.0 * Transform ESM-only react-router 8 and cookie-es in jest react-router 8 dropped its CommonJS build ("type": "module", no "require" export condition), so jest loaded it as raw ESM and 27 of 32 suites failed with "Cannot use import statement outside a module" — every suite that goes through renderWithRouter in test-utils --------- Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Carla Severe --- jest.config.ts | 15 +++++++++-- package-lock.json | 63 +++++++++++++++++------------------------------ package.json | 2 +- 3 files changed, 36 insertions(+), 44 deletions(-) diff --git a/jest.config.ts b/jest.config.ts index 303137c53..914fac80e 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -18,7 +18,7 @@ const config: Config.InitialOptions = { testPathIgnorePatterns: ['/node_modules/', '/src/__tests__/utils/'], testEnvironment: './src/__tests__/utils/custom-environment', transform: { - '^.+\\.(t|j)sx?$': [ + '^.+\\.[cm]?[tj]sx?$': [ '@swc/jest', { jsc: { @@ -26,6 +26,17 @@ const config: Config.InitialOptions = { react: { runtime: 'automatic', }, + // react-router (ESM-only since v8) guards a dev-only HMR branch + // with `import.meta.hot`, which is a syntax error once swc + // transforms the module to CommonJS for jest. There is no HMR in + // tests, so compile the check away. + optimizer: { + globals: { + vars: { + 'import.meta.hot': 'undefined', + }, + }, + }, }, }, }, @@ -38,7 +49,7 @@ const config: Config.InitialOptions = { // dependencies of fetch-mock do! Hopefully this won't be needed in the future // when fetch-mock updates. transformIgnorePatterns: [ - '/node_modules/(?!(taskcluster-client-web|data-uri-to-buffer|fetch-blob|formdata-polyfill|fetch-mock|@fetch-mock/jest)/)', + '/node_modules/(?!(taskcluster-client-web|data-uri-to-buffer|fetch-blob|formdata-polyfill|fetch-mock|@fetch-mock/jest|react-router|cookie-es)/)', ], modulePaths: [], moduleNameMapper: { diff --git a/package-lock.json b/package-lock.json index 13c4fd221..8c9e0a9c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "react": "^19.2.7", "react-dom": "^19.2.7", "react-redux": "^9.3.0", - "react-router": "^7.18.1", + "react-router": "^8.3.0", "react-virtuoso": "^4.18.11", "stream-browserify": "^3.0.0", "taskcluster-client-web": "^87.1.3", @@ -7102,6 +7102,11 @@ "node": ">= 0.6" } }, + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==" + }, "node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", @@ -13925,19 +13930,18 @@ } }, "node_modules/react-router": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.1.tgz", - "integrity": "sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.0.tgz", + "integrity": "sha512-qyPMvW83jGIct3yiieisxdk9M745anqhpIMKN5m1t6yBMfgVPpt77aHOqs5fUlEJRMCGffg9BaQLH9oPVOL7xQ==", "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" + "cookie-es": "^3.1.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.22.0" }, "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" + "react": ">=19.2.7", + "react-dom": ">=19.2.7" }, "peerDependenciesMeta": { "react-dom": { @@ -13945,15 +13949,6 @@ } } }, - "node_modules/react-router/node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -14691,12 +14686,6 @@ "node": ">= 18" } }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "license": "MIT" - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -22102,6 +22091,11 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" }, + "cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==" + }, "cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", @@ -26869,19 +26863,11 @@ "dev": true }, "react-router": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.1.tgz", - "integrity": "sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.0.tgz", + "integrity": "sha512-qyPMvW83jGIct3yiieisxdk9M745anqhpIMKN5m1t6yBMfgVPpt77aHOqs5fUlEJRMCGffg9BaQLH9oPVOL7xQ==", "requires": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "dependencies": { - "cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==" - } + "cookie-es": "^3.1.1" } }, "react-transition-group": { @@ -27443,11 +27429,6 @@ "send": "^1.2.0" } }, - "set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" - }, "set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", diff --git a/package.json b/package.json index 146c9aa98..28f360a7f 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "react": "^19.2.7", "react-dom": "^19.2.7", "react-redux": "^9.3.0", - "react-router": "^7.18.1", + "react-router": "^8.3.0", "react-virtuoso": "^4.18.11", "stream-browserify": "^3.0.0", "taskcluster-client-web": "^87.1.3", From f5439dc50fe9d0f89aafeedda641c5dc07c17c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Tue, 4 Aug 2026 11:57:02 +0200 Subject: [PATCH 03/19] Remove canova from the codeowners (#1074) --- CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index a74369bf8..0c33233b0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,4 @@ # Automatically request reviews for dependency updates -/package.json @esanuandra @beatrice-acasandrei @canova @kala-moz -/package-lock.json @esanuandra @beatrice-acasandrei @canova @kala-moz +/package.json @esanuandra @beatrice-acasandrei @kala-moz +/package-lock.json @esanuandra @beatrice-acasandrei @kala-moz From 375cd0f03b01b7be1452e5326ba8a0ed541c54f8 Mon Sep 17 00:00:00 2001 From: Gopar Date: Wed, 5 Aug 2026 14:44:21 -0700 Subject: [PATCH 04/19] [bug-2021092] Update light/dark toggle wording to be less ambiguous (#1073) --- src/__tests__/App.test.tsx | 6 ++++-- .../__snapshots__/ResultsTable.test.tsx.snap | 4 ++-- .../__snapshots__/SubtestsResultsView.test.tsx.snap | 10 +++++----- src/__tests__/Search/SearchResultsList.test.tsx | 2 +- .../Search/__snapshots__/CompareWithBase.test.tsx.snap | 2 +- .../__snapshots__/SearchResultsList.test.tsx.snap | 2 +- .../Search/__snapshots__/SearchView.test.tsx.snap | 2 +- src/__tests__/__snapshots__/App.test.tsx.snap | 6 +++--- src/components/Shared/ToggleDarkModeButton.tsx | 2 +- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx index a418178d9..b7645d421 100644 --- a/src/__tests__/App.test.tsx +++ b/src/__tests__/App.test.tsx @@ -96,10 +96,12 @@ describe('App', () => { }); await user.click(darkModeButton); - expect(screen.getByLabelText('Light mode')).toBeInTheDocument(); + expect(screen.getByLabelText('Switch to Light mode')).toBeInTheDocument(); await user.click(darkModeButton); - expect(screen.queryByLabelText('Light mode')).not.toBeInTheDocument(); + expect( + screen.queryByLabelText('Switch to Light mode'), + ).not.toBeInTheDocument(); }); describe('CompareResults or CompareOverTime loader', () => { diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap index 95b362d3d..95f3f1fbf 100644 --- a/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap @@ -47,7 +47,7 @@ exports[`Results Table Should match snapshot 1`] = ` - Dark mode + Switch to Dark mode @@ -2930,7 +2930,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion - Dark mode + Switch to Dark mode diff --git a/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap index 18f8b99f1..f0401948c 100644 --- a/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap @@ -387,7 +387,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results - Dark mode + Switch to Dark mode @@ -2306,7 +2306,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi - Dark mode + Switch to Dark mode @@ -3908,7 +3908,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi - Dark mode + Switch to Dark mode @@ -5510,7 +5510,7 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when - Dark mode + Switch to Dark mode @@ -7112,7 +7112,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests - Dark mode + Switch to Dark mode diff --git a/src/__tests__/Search/SearchResultsList.test.tsx b/src/__tests__/Search/SearchResultsList.test.tsx index 779e9104b..a909f57a5 100644 --- a/src/__tests__/Search/SearchResultsList.test.tsx +++ b/src/__tests__/Search/SearchResultsList.test.tsx @@ -192,7 +192,7 @@ describe('SearchResultsList', () => { }); await user.click(darkModeToggle); - expect(screen.getByLabelText('Light mode')).toBeInTheDocument(); + expect(screen.getByLabelText('Switch to Light mode')).toBeInTheDocument(); const autocomplete = screen.getAllByTestId('autocomplete')[0]; // open dropdown using keyboard arrow down diff --git a/src/__tests__/Search/__snapshots__/CompareWithBase.test.tsx.snap b/src/__tests__/Search/__snapshots__/CompareWithBase.test.tsx.snap index 088445814..fd6e35eea 100644 --- a/src/__tests__/Search/__snapshots__/CompareWithBase.test.tsx.snap +++ b/src/__tests__/Search/__snapshots__/CompareWithBase.test.tsx.snap @@ -4296,7 +4296,7 @@ exports[`Compare With Base should remove the checked revision once X button is c - Dark mode + Switch to Dark mode diff --git a/src/__tests__/Search/__snapshots__/SearchResultsList.test.tsx.snap b/src/__tests__/Search/__snapshots__/SearchResultsList.test.tsx.snap index 995528807..72ab6b51c 100644 --- a/src/__tests__/Search/__snapshots__/SearchResultsList.test.tsx.snap +++ b/src/__tests__/Search/__snapshots__/SearchResultsList.test.tsx.snap @@ -847,7 +847,7 @@ exports[`SearchResultsList should match snapshot 1`] = ` - Dark mode + Switch to Dark mode diff --git a/src/__tests__/Search/__snapshots__/SearchView.test.tsx.snap b/src/__tests__/Search/__snapshots__/SearchView.test.tsx.snap index 1cc8d6f1a..4be7b1308 100644 --- a/src/__tests__/Search/__snapshots__/SearchView.test.tsx.snap +++ b/src/__tests__/Search/__snapshots__/SearchView.test.tsx.snap @@ -53,7 +53,7 @@ exports[`Search View renders correctly when there are no results 1`] = ` - Dark mode + Switch to Dark mode diff --git a/src/__tests__/__snapshots__/App.test.tsx.snap b/src/__tests__/__snapshots__/App.test.tsx.snap index af36bb4d7..239916e1c 100644 --- a/src/__tests__/__snapshots__/App.test.tsx.snap +++ b/src/__tests__/__snapshots__/App.test.tsx.snap @@ -51,7 +51,7 @@ exports[`App CompareResults or CompareOverTime loader Should render an error pag - Dark mode + Switch to Dark mode @@ -353,7 +353,7 @@ exports[`App CompareResults or CompareOverTime loader Should render an error pag - Dark mode + Switch to Dark mode @@ -550,7 +550,7 @@ exports[`App CompareResults or CompareOverTime loader Should render an error pag - Dark mode + Switch to Dark mode diff --git a/src/components/Shared/ToggleDarkModeButton.tsx b/src/components/Shared/ToggleDarkModeButton.tsx index 24d66386c..4b20fabd3 100644 --- a/src/components/Shared/ToggleDarkModeButton.tsx +++ b/src/components/Shared/ToggleDarkModeButton.tsx @@ -57,7 +57,7 @@ function ToggleDarkMode() { id={theme == 'light' ? strings.darkMode : strings.lightMode} /> } - label={theme == 'light' ? strings.darkMode : strings.lightMode} + label={`Switch to ${theme == 'light' ? strings.darkMode : strings.lightMode}`} /> From f39163fcf9c2c20c71bebcd77953b7b0b0b99ea8 Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 15:10:35 -0700 Subject: [PATCH 05/19] Update all npm dependencies (2026-08-05) (#1075) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⬆️ Update all npm dependencies (2026-08-05) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- package-lock.json | 194 ++++++++++++++++++---------------------------- package.json | 14 ++-- 2 files changed, 83 insertions(+), 125 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c9e0a9c5..aa1fbf4d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,8 @@ "moize": "^6.1.7", "notistack": "^3.0.2", "process": "^0.11.10", - "react": "^19.2.7", - "react-dom": "^19.2.7", + "react": "^19.2.8", + "react-dom": "^19.2.8", "react-redux": "^9.3.0", "react-router": "^8.3.0", "react-virtuoso": "^4.18.11", @@ -69,13 +69,13 @@ "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "^29.15.4", + "eslint-plugin-jest": "^29.16.0", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-react": "^7.37.5", "eslint-plugin-testing-library": "^7.16.2", - "globals": "^17.7.0", + "globals": "^17.9.0", "history": "^5.3.0", - "html-webpack-plugin": "^5.6.7", + "html-webpack-plugin": "^5.6.8", "jest": "^30.4.2", "jest-axe": "^10.0.0", "jest-environment-jsdom": "^30.4.1", @@ -86,12 +86,12 @@ "react-refresh": "^0.18.0", "regenerator-runtime": "^0.14.1", "style-loader": "^4.0.0", - "ts-jest": "^29.4.11", + "ts-jest": "^29.4.12", "ts-loader": "^9.6.2", "ts-node": "^10.9.2", "typescript": "^5.9.3", "typescript-eslint": "^8.65.0", - "webpack": "^5.108.4", + "webpack": "^5.109.2", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.6", "webpack-merge": "^6.0.1" @@ -5620,18 +5620,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -7869,9 +7857,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.23.0.tgz", - "integrity": "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==", + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -8360,9 +8348,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.15.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.4.tgz", - "integrity": "sha512-6ln5i9Nkrb27X4w91ZPt/xHDsVQnvxTS2ntgq6r32u+8gymdUrp88TdcBXSveZW0Dl+M5v2H6K75kJhMvUGhjg==", + "version": "29.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.0.tgz", + "integrity": "sha512-0WFBxDHlT2ratGQfnFQEVIsgQJ5cfd+0IV8Kc6U3X2onB8ATLG23voD2Ch5G9fCkEpCPmCMuzW0tbS0kYb8biw==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^8.0.0" @@ -8374,7 +8362,7 @@ "@typescript-eslint/eslint-plugin": "^8.0.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "jest": "*", - "typescript": ">=4.8.4 <7.0.0" + "typescript": ">=4.8.4 <8.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -9356,9 +9344,9 @@ "dev": true }, "node_modules/globals": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", - "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.9.0.tgz", + "integrity": "sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==", "dev": true, "engines": { "node": ">=18" @@ -9688,9 +9676,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.6.7", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.7.tgz", - "integrity": "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==", + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.8.tgz", + "integrity": "sha512-MZmKQcTnhEh1SPSyMiEytIeDZDUoBZVorNHivQGXMASHf/BSGGOrKa2xQ5bGx3TCe1n109ecCt+cpww7wwWhKA==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -9707,7 +9695,7 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { - "@rspack/core": "0.x || 1.x", + "@rspack/core": "0.x || 1.x || 2.x", "webpack": "^5.20.0" }, "peerDependenciesMeta": { @@ -12104,19 +12092,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "node_modules/loader-runner": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", - "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", - "dev": true, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -13835,9 +13810,9 @@ } }, "node_modules/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "engines": { "node": ">=0.10.0" } @@ -13867,14 +13842,14 @@ "license": "MIT" }, "node_modules/react-dom": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.7" + "react": "^19.2.8" } }, "node_modules/react-is": { @@ -14530,9 +14505,9 @@ } }, "node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -15642,9 +15617,9 @@ } }, "node_modules/ts-jest": { - "version": "29.4.11", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", - "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", "dev": true, "dependencies": { "bs-logger": "^0.2.6", @@ -15653,7 +15628,7 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.8.0", + "semver": "^7.8.5", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -16379,9 +16354,9 @@ } }, "node_modules/webpack": { - "version": "5.108.4", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.4.tgz", - "integrity": "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w==", + "version": "5.109.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.109.2.tgz", + "integrity": "sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==", "dev": true, "dependencies": { "@types/estree": "^1.0.8", @@ -16390,22 +16365,20 @@ "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", - "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.22.2", + "enhanced-resolve": "^5.24.4", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "graceful-fs": "^4.2.11", - "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "watchpack": "^2.5.2", - "webpack-sources": "^3.5.0" + "webpack-sources": "^3.5.1" }, "bin": { "webpack": "bin/webpack.js" @@ -16826,9 +16799,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", - "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", "dev": true, "engines": { "node": ">=10.13.0" @@ -21044,13 +21017,6 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true }, - "acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "requires": {} - }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -22652,9 +22618,9 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" }, "enhanced-resolve": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.23.0.tgz", - "integrity": "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==", + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -23055,9 +23021,9 @@ } }, "eslint-plugin-jest": { - "version": "29.15.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.4.tgz", - "integrity": "sha512-6ln5i9Nkrb27X4w91ZPt/xHDsVQnvxTS2ntgq6r32u+8gymdUrp88TdcBXSveZW0Dl+M5v2H6K75kJhMvUGhjg==", + "version": "29.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.0.tgz", + "integrity": "sha512-0WFBxDHlT2ratGQfnFQEVIsgQJ5cfd+0IV8Kc6U3X2onB8ATLG23voD2Ch5G9fCkEpCPmCMuzW0tbS0kYb8biw==", "dev": true, "requires": { "@typescript-eslint/utils": "^8.0.0" @@ -23678,9 +23644,9 @@ "dev": true }, "globals": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", - "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.9.0.tgz", + "integrity": "sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==", "dev": true }, "globalthis": { @@ -23935,9 +23901,9 @@ } }, "html-webpack-plugin": { - "version": "5.6.7", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.7.tgz", - "integrity": "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==", + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.8.tgz", + "integrity": "sha512-MZmKQcTnhEh1SPSyMiEytIeDZDUoBZVorNHivQGXMASHf/BSGGOrKa2xQ5bGx3TCe1n109ecCt+cpww7wwWhKA==", "dev": true, "requires": { "@types/html-minifier-terser": "^6.0.0", @@ -25616,12 +25582,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "loader-runner": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", - "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", - "dev": true - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -26795,9 +26755,9 @@ } }, "react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==" + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==" }, "react-app-polyfill": { "version": "3.0.0", @@ -26822,9 +26782,9 @@ } }, "react-dom": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "requires": { "scheduler": "^0.27.0" } @@ -27303,9 +27263,9 @@ } }, "semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true }, "send": { @@ -28096,9 +28056,9 @@ "requires": {} }, "ts-jest": { - "version": "29.4.11", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", - "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", "dev": true, "requires": { "bs-logger": "^0.2.6", @@ -28107,7 +28067,7 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.8.0", + "semver": "^7.8.5", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -28599,9 +28559,9 @@ "dev": true }, "webpack": { - "version": "5.108.4", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.4.tgz", - "integrity": "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w==", + "version": "5.109.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.109.2.tgz", + "integrity": "sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==", "dev": true, "requires": { "@types/estree": "^1.0.8", @@ -28610,22 +28570,20 @@ "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", - "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.22.2", + "enhanced-resolve": "^5.24.4", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "graceful-fs": "^4.2.11", - "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "watchpack": "^2.5.2", - "webpack-sources": "^3.5.0" + "webpack-sources": "^3.5.1" }, "dependencies": { "mime-db": { @@ -28923,9 +28881,9 @@ } }, "webpack-sources": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", - "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", "dev": true }, "websocket-driver": { diff --git a/package.json b/package.json index 28f360a7f..88e6e6433 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "moize": "^6.1.7", "notistack": "^3.0.2", "process": "^0.11.10", - "react": "^19.2.7", - "react-dom": "^19.2.7", + "react": "^19.2.8", + "react-dom": "^19.2.8", "react-redux": "^9.3.0", "react-router": "^8.3.0", "react-virtuoso": "^4.18.11", @@ -111,13 +111,13 @@ "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "^29.15.4", + "eslint-plugin-jest": "^29.16.0", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-react": "^7.37.5", "eslint-plugin-testing-library": "^7.16.2", - "globals": "^17.7.0", + "globals": "^17.9.0", "history": "^5.3.0", - "html-webpack-plugin": "^5.6.7", + "html-webpack-plugin": "^5.6.8", "jest": "^30.4.2", "jest-axe": "^10.0.0", "jest-environment-jsdom": "^30.4.1", @@ -128,12 +128,12 @@ "react-refresh": "^0.18.0", "regenerator-runtime": "^0.14.1", "style-loader": "^4.0.0", - "ts-jest": "^29.4.11", + "ts-jest": "^29.4.12", "ts-loader": "^9.6.2", "ts-node": "^10.9.2", "typescript": "^5.9.3", "typescript-eslint": "^8.65.0", - "webpack": "^5.108.4", + "webpack": "^5.109.2", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.6", "webpack-merge": "^6.0.1" From 9806c7be506c10328f9d8d321341967c5d6a356b Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Thu, 13 Aug 2026 08:45:47 -0700 Subject: [PATCH 06/19] Fix for Bug 2060613: PerfCompare statistical analysis has some NaN values in explanations (#1077) bootstrap-ci: return null for <2 runs instead of a NaN CI BCa's acceleration uses a leave-one-out jackknife, which is undefined for a single observation (leaving it out gives an empty sample). A subtest with one run per side therefore produced a [NaN, NaN] median-difference interval. Return null below two runs per group and omit the interval in the Mann-Whitney blurb. Adds a regression test. --- src/__tests__/bootstrapCi.test.ts | 32 +++++++++++++++++++++++++ src/common/testVersions/mannWhitney.tsx | 4 +++- src/utils/bootstrap-ci.ts | 10 +++++++- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/__tests__/bootstrapCi.test.ts diff --git a/src/__tests__/bootstrapCi.test.ts b/src/__tests__/bootstrapCi.test.ts new file mode 100644 index 000000000..2fde170e9 --- /dev/null +++ b/src/__tests__/bootstrapCi.test.ts @@ -0,0 +1,32 @@ +import { bootstrapMedianDiffCI } from '../utils/bootstrap-ci'; + +describe('bootstrapMedianDiffCI', () => { + it('returns null when either group has fewer than 2 observations', () => { + // A single run per side (common for some subtests) has no resampling + // variability and the BCa jackknife is undefined — must not yield NaNs. + expect(bootstrapMedianDiffCI([8.53], [8.73])).toBeNull(); + expect(bootstrapMedianDiffCI([], [1, 2, 3])).toBeNull(); + expect(bootstrapMedianDiffCI([1, 2, 3], [])).toBeNull(); + expect(bootstrapMedianDiffCI([5], [6])).toBeNull(); + }); + + it('returns a finite interval bracketing the observed difference', () => { + const base = [100, 102, 98, 101, 99, 103, 97, 100, 101, 99]; + const newData = [106, 108, 104, 107, 105, 109, 103, 106, 107, 105]; + const ci = bootstrapMedianDiffCI(base, newData); + expect(ci).not.toBeNull(); + const { medianDiff, ciLow, ciHigh } = ci!; + expect(Number.isFinite(ciLow)).toBe(true); + expect(Number.isFinite(ciHigh)).toBe(true); + expect(ciLow).toBeLessThanOrEqual(medianDiff); + expect(ciHigh).toBeGreaterThanOrEqual(medianDiff); + }); + + it('is deterministic for a fixed seed', () => { + const base = [10, 12, 11, 13, 9, 14, 10, 11]; + const newData = [14, 16, 15, 17, 13, 18, 14, 15]; + expect(bootstrapMedianDiffCI(base, newData)).toEqual( + bootstrapMedianDiffCI(base, newData), + ); + }); +}); diff --git a/src/common/testVersions/mannWhitney.tsx b/src/common/testVersions/mannWhitney.tsx index 742855fd4..e7af9326c 100644 --- a/src/common/testVersions/mannWhitney.tsx +++ b/src/common/testVersions/mannWhitney.tsx @@ -405,8 +405,10 @@ export const mannWhitneyStrategy = { const baseRuns = mwResult.base_runs ?? []; const newRuns = mwResult.new_runs ?? []; + // A BCa CI needs at least 2 runs per side (see bootstrapMedianDiffCI); + // with fewer it returns null and we render no interval rather than NaNs. const ci = - baseRuns.length > 0 && newRuns.length > 0 + baseRuns.length >= 2 && newRuns.length >= 2 ? bootstrapMedianDiffCI(baseRuns, newRuns) : null; const rawUnit = diff --git a/src/utils/bootstrap-ci.ts b/src/utils/bootstrap-ci.ts index eb6155b37..16547e165 100644 --- a/src/utils/bootstrap-ci.ts +++ b/src/utils/bootstrap-ci.ts @@ -136,6 +136,12 @@ export type BootstrapCI = { * - Skewness: the interval may need to be asymmetric (a, the acceleration, * estimated via leave-one-out jackknife). * + * Returns null when either group has fewer than 2 observations: BCa relies on + * a leave-one-out jackknife for the acceleration term, which is undefined for a + * single observation (leaving it out yields an empty sample), and a one-point + * sample carries no resampling variability to form an interval from. + * + * * @param base - baseline sample values * @param newData - new/comparison sample values * @param nIter - bootstrap resamples; 9999 is standard for BCa @@ -148,7 +154,9 @@ export function bootstrapMedianDiffCI( nIter: number = 9999, alpha: number = 0.05, seed: number = 42, -): BootstrapCI { +): BootstrapCI | null { + if (base.length < 2 || newData.length < 2) return null; + const rng = mulberry32(seed); const baseArr = new Float64Array(base); const newArr = new Float64Array(newData); From a67f0bb280afa1545622f949f7e40ba707e3489e Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Thu, 13 Aug 2026 10:56:24 -0700 Subject: [PATCH 07/19] Update all npm dependencies (2026-08-13) (#1078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⬆️ Update all npm dependencies (2026-08-13) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- package-lock.json | 78 +++++++++++++++++++++++------------------------ package.json | 10 +++--- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa1fbf4d4..fd6918329 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,25 +52,25 @@ "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.10.0", "@testing-library/react": "^16.3.2", - "@testing-library/user-event": "^14.6.1", + "@testing-library/user-event": "^14.6.3", "@types/jest": "^30.0.0", "@types/jest-axe": "^3.5.9", "@types/material-ui": "^0.21.18", "@types/node": "^25.9.5", - "@types/react": "^19.2.17", - "@types/react-dom": "^19.2.3", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", "babel-loader": "^10.1.1", "babel-preset-jest": "^30.4.0", "case-sensitive-paths-webpack-plugin": "^2.4.0", "copy-webpack-plugin": "^13.0.1", - "core-js": "^3.49.0", + "core-js": "^3.50.0", "css-loader": "^7.1.4", "eslint": "^9.39.5", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest": "^29.16.0", - "eslint-plugin-jest-dom": "^5.5.0", + "eslint-plugin-jest-dom": "^5.10.1", "eslint-plugin-react": "^7.37.5", "eslint-plugin-testing-library": "^7.16.2", "globals": "^17.9.0", @@ -4321,11 +4321,10 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "version": "14.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.3.tgz", + "integrity": "sha512-6dBq67jT8lE+JTE8Exm02Kt6ze43hz1jdiSpSJwtTZiT1xQQ6b7nZYTTQ9njdArdU8XklOwaDp/AbT/eYSKF4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=12", "npm": ">=6" @@ -4699,9 +4698,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "dependencies": { "csstype": "^3.2.2" } @@ -4716,9 +4715,9 @@ } }, "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", "dev": true, "peerDependencies": { "@types/react": "^19.2.0" @@ -7128,11 +7127,14 @@ } }, "node_modules/core-js": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", - "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", + "version": "3.50.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz", + "integrity": "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==", "dev": true, "hasInstallScript": true, + "engines": { + "node": "*" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -8377,12 +8379,11 @@ } }, "node_modules/eslint-plugin-jest-dom": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.5.0.tgz", - "integrity": "sha512-CRlXfchTr7EgC3tDI7MGHY6QjdJU5Vv2RPaeeGtkXUHnKZf04kgzMPIJUXt4qKCvYWVVIEo9ut9Oq1vgXAykEA==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.10.1.tgz", + "integrity": "sha512-IIJdzbACbhJUJyMAqpA9E9gxp1Gv29TeQ3DtL+pepwP8Oq2WiqjOB2HbnEIs23h0ewdKIZRDI56yLro2eUO+DA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.3", "requireindex": "^1.2.0" }, "engines": { @@ -8392,7 +8393,7 @@ }, "peerDependencies": { "@testing-library/dom": "^8.0.0 || ^9.0.0 || ^10.0.0", - "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { "@testing-library/dom": { @@ -20065,9 +20066,9 @@ } }, "@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "version": "14.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.3.tgz", + "integrity": "sha512-6dBq67jT8lE+JTE8Exm02Kt6ze43hz1jdiSpSJwtTZiT1xQQ6b7nZYTTQ9njdArdU8XklOwaDp/AbT/eYSKF4g==", "dev": true, "requires": {} }, @@ -20408,9 +20409,9 @@ "dev": true }, "@types/react": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "requires": { "csstype": "^3.2.2" } @@ -20425,9 +20426,9 @@ } }, "@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", "dev": true, "requires": {} }, @@ -22081,9 +22082,9 @@ } }, "core-js": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", - "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", + "version": "3.50.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz", + "integrity": "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==", "dev": true }, "core-js-compat": { @@ -23030,12 +23031,11 @@ } }, "eslint-plugin-jest-dom": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.5.0.tgz", - "integrity": "sha512-CRlXfchTr7EgC3tDI7MGHY6QjdJU5Vv2RPaeeGtkXUHnKZf04kgzMPIJUXt4qKCvYWVVIEo9ut9Oq1vgXAykEA==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.10.1.tgz", + "integrity": "sha512-IIJdzbACbhJUJyMAqpA9E9gxp1Gv29TeQ3DtL+pepwP8Oq2WiqjOB2HbnEIs23h0ewdKIZRDI56yLro2eUO+DA==", "dev": true, "requires": { - "@babel/runtime": "^7.16.3", "requireindex": "^1.2.0" } }, diff --git a/package.json b/package.json index 88e6e6433..b051e35f4 100644 --- a/package.json +++ b/package.json @@ -94,25 +94,25 @@ "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.10.0", "@testing-library/react": "^16.3.2", - "@testing-library/user-event": "^14.6.1", + "@testing-library/user-event": "^14.6.3", "@types/jest": "^30.0.0", "@types/jest-axe": "^3.5.9", "@types/material-ui": "^0.21.18", "@types/node": "^25.9.5", - "@types/react": "^19.2.17", - "@types/react-dom": "^19.2.3", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", "babel-loader": "^10.1.1", "babel-preset-jest": "^30.4.0", "case-sensitive-paths-webpack-plugin": "^2.4.0", "copy-webpack-plugin": "^13.0.1", - "core-js": "^3.49.0", + "core-js": "^3.50.0", "css-loader": "^7.1.4", "eslint": "^9.39.5", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest": "^29.16.0", - "eslint-plugin-jest-dom": "^5.5.0", + "eslint-plugin-jest-dom": "^5.10.1", "eslint-plugin-react": "^7.37.5", "eslint-plugin-testing-library": "^7.16.2", "globals": "^17.9.0", From f50b4a4e37650bb007c407dd9134e49a180882b3 Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Mon, 17 Aug 2026 14:43:12 -0700 Subject: [PATCH 08/19] Bug 2059493: Clean up components in perfcompare frontend using the unecessary silverman_kde data (#1079) * Remove unused MannWhitneyResultsItem fields (backend cleanup) * Remove the silverman_kde feature (request param + response field) --- .../__snapshots__/ResultsView.test.tsx.snap | 40 --- src/__tests__/helpers.test.ts | 60 ----- .../hooks/useSubtestRegressionCount.test.ts | 26 -- src/__tests__/utils/fixtures.ts | 243 ------------------ .../MannWhitneyCompareMetrics.tsx | 12 - .../CompareResults/ResultsTable.tsx | 1 - .../CompareResults/hashToCommitLoader.ts | 7 - .../CompareResults/landoToCommitLoader.ts | 7 - src/components/CompareResults/loader.ts | 18 -- .../CompareResults/overTimeLoader.ts | 15 -- .../CompareResults/subtestsLoader.ts | 11 - .../CompareResults/subtestsOverTimeLoader.tsx | 11 - src/hooks/useSubtestRegressionCount.ts | 3 - src/logic/treeherder.ts | 12 - src/types/state.ts | 43 ---- src/utils/helpers.ts | 26 -- 16 files changed, 535 deletions(-) diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap index ae8cf9fbc..9eca664b6 100644 --- a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap @@ -516,26 +516,6 @@ exports[`Results View Should display Base, New and Common graphs with replicates - - - Distribution - - - - - Estimated Modes - - - - - No modes or data for Base and New, possible oversmoothing, KDE evaluation failed - - @@ -1061,26 +1041,6 @@ exports[`Results View Should display Base, New and Common graphs with tooltips 1 - - - Distribution - - - - - Estimated Modes - - - - - No modes or data for Base and New, possible oversmoothing, KDE evaluation failed - - diff --git a/src/__tests__/helpers.test.ts b/src/__tests__/helpers.test.ts index 37edcde91..a95315c97 100644 --- a/src/__tests__/helpers.test.ts +++ b/src/__tests__/helpers.test.ts @@ -5,7 +5,6 @@ import { truncateHash, swapArrayElements, getDocsURL, - getModeInterpretation, capitalize, } from '../utils/helpers'; import getTestData from './utils/fixtures'; @@ -133,65 +132,6 @@ describe('swapArrayElements', () => { }); }); -describe('getModeInterpretation', () => { - const baseMode1 = 1; - const newMode1 = 1; - const baseMode2 = 2; - const newMode2 = 2; - const baseModenull = null; - const newMode0 = 0; - const baseMode0 = 0; - const newModenull = null; - - it('should handle same mode count interpretation for base and new', () => { - const expectedStr = getModeInterpretation(baseMode1, newMode1); - expect(expectedStr).toBe('Base and New revisions are unimodal'); - const expectedStr2 = getModeInterpretation(baseMode2, newMode2); - expect(expectedStr2).toBe('Base and New revisions are multimodal'); - }); - - it('should handle different mode count interpretation for base and new', () => { - const expectedStr2 = getModeInterpretation(baseMode2, newMode1); - expect(expectedStr2).toBe('Base is multimodal and New is unimodal'); - const expectedStr3 = getModeInterpretation(baseMode1, newMode2); - expect(expectedStr3).toBe('Base is unimodal and New is multimodal'); - }); - - it('should get mode interpretation with both baseRev and newRev as null or 0', () => { - const expectedStr4 = getModeInterpretation(baseModenull, newMode0); - expect(expectedStr4).toBe( - 'No modes or data for Base and New, possible oversmoothing, KDE evaluation failed', - ); - const expectedStr5 = getModeInterpretation(baseModenull, newModenull); - expect(expectedStr5).toBe( - 'No modes or data for Base and New, possible oversmoothing, KDE evaluation failed', - ); - const expectedStr6 = getModeInterpretation(baseMode0, newMode0); - expect(expectedStr6).toBe( - 'No modes or data for Base and New, possible oversmoothing, KDE evaluation failed', - ); - - const expectedStr7 = getModeInterpretation(baseMode0, newModenull); - expect(expectedStr7).toBe( - 'No modes or data for Base and New, possible oversmoothing, KDE evaluation failed', - ); - }); - - it('should get N/A for interpretModeCount one of baseRev or newRev < 1 and not null', () => { - const expectedStr1 = getModeInterpretation(baseMode2, newMode0); - expect(expectedStr1).toBe('Base is multimodal and New is N/A'); - const expectedStr2 = getModeInterpretation(baseMode0, newMode2); - expect(expectedStr2).toBe('Base is N/A and New is multimodal'); - }); - - it('should get N/A for interpretModeCount one of baseRev or newRev as null', () => { - const expectedStr0 = getModeInterpretation(baseModenull, newMode1); - expect(expectedStr0).toBe('Base is N/A and New is unimodal'); - const expectedStr3 = getModeInterpretation(baseMode1, newModenull); - expect(expectedStr3).toBe('Base is unimodal and New is N/A'); - }); -}); - describe('capitalize', () => { const string1 = 'i love my dog.'; const string2 = 'monkey'; diff --git a/src/__tests__/hooks/useSubtestRegressionCount.test.ts b/src/__tests__/hooks/useSubtestRegressionCount.test.ts index 4e1ee9a9f..471a3bdc0 100644 --- a/src/__tests__/hooks/useSubtestRegressionCount.test.ts +++ b/src/__tests__/hooks/useSubtestRegressionCount.test.ts @@ -104,7 +104,6 @@ describe('useSubtestRegressionCount', () => { newParentSignature: '200', replicates: false, testVersion: 'mann-whitney-u', - silvermanKDEEnabled: false, }); }); }); @@ -245,30 +244,6 @@ describe('useSubtestRegressionCount', () => { expect(hookResult.current.counts).not.toBeNull(); }); - it('passes silvermanKDEEnabled as true when the URL param is present', async () => { - window.history.replaceState( - null, - '', - '/compare-results?baseRev=abc&baseRepo=mozilla-central&framework=1&enable_silverman_kde', - ); - mockedFetchCompare.mockResolvedValue([]); - - renderHook(() => - useSubtestRegressionCount({ - result: baseResult, - view: compareView, - replicates: false, - testVersion: 'mann-whitney-u', - }), - ); - - await waitFor(() => { - expect(mockedFetchCompare).toHaveBeenCalledWith( - expect.objectContaining({ silvermanKDEEnabled: true }), - ); - }); - }); - it('calls memoizedFetchSubtestsCompareOverTimeResults with interval from URL for compareOverTimeView', async () => { window.history.replaceState( null, @@ -290,7 +265,6 @@ describe('useSubtestRegressionCount', () => { expect(mockedFetchCompareOverTime).toHaveBeenCalledWith( expect.objectContaining({ interval: 86400, - silvermanKDEEnabled: false, }), ); }); diff --git a/src/__tests__/utils/fixtures.ts b/src/__tests__/utils/fixtures.ts index 07a083d82..1572ade36 100644 --- a/src/__tests__/utils/fixtures.ts +++ b/src/__tests__/utils/fixtures.ts @@ -449,36 +449,8 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - kde_base: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: 'improvement', kde_warnings: [], }, @@ -568,35 +540,7 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - kde_base: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: 'regression', shapiro_wilk_test_base: null, kde_warnings: [], @@ -681,35 +625,7 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - kde_base: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: null, kde_warnings: [], }, @@ -792,35 +708,7 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - kde_base: { - median: 0, - sample_count: 0, - kde_x: [], - kde_y: [], - }, - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: null, kde_warnings: [], }, @@ -1343,7 +1231,6 @@ const getTestData = () => { delta_percentage: 0.0, is_new_better: null, lower_is_better: true, - is_fit_good: true, more_runs_are_needed: false, direction_of_change: 'regression', is_improvement: null, @@ -1405,7 +1292,6 @@ const getTestData = () => { }, cliffs_delta: 0.0, cliffs_interpretation: 'negligible', - warning_c_delta: null, cles: { cles: 0.2, cles_direction: '', @@ -1415,50 +1301,11 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - silverman_kde: { - bandwidth: 'Silverman', - base_mode_count: 1, - new_mode_count: 1, - base_locations: [465888.0, 465422.11, 466353.89], - new_locations: [465888.0, 465422.11, 466353.89], - base_prominence: 0.08, - new_prominence: 0.08, - warnings: [], - modes: [ - { - mode_name: 'Mode 1', - mode_start: '465883.93', - mode_end: '465892.07', - median_shift_summary: null, - ci_low: null, - ci_high: null, - ci_warning: null, - shift: null, - shift_summary: null, - }, - ], - is_regression: null, - is_improvement: null, - }, silverman_warnings: [], - kde_new: { - median: 465888.0, - sample_count: 1, - kde_x: [465888.0, 465422.11, 466353.89], - kde_y: [], - }, - kde_base: { - median: 465888.0, - sample_count: 1, - kde_x: [465888.0, 465422.11, 466353.89], - kde_y: [], - }, kde_warnings: [ 'Less than 2 datapoints or no standard variance for a meaningful fit Kernel Density Estimator (KDE) with an ISJ bandwidth to Base.', 'Less than 2 datapoints or no standard variance for a meaningful fit Kernel Density Estimator (KDE) with an ISJ bandwidth to New.', ], - is_significant: null, - performance_intepretation: '', new_is_better: null, }; @@ -1551,8 +1398,6 @@ const getTestData = () => { }, cliffs_delta: 0.02, cliffs_interpretation: 'negligible', - kde_new: { median: 982.41, sample_count: 2, kde_x: [], kde_y: [] }, - kde_base: { median: 971.38, sample_count: 2, kde_x: [], kde_y: [] }, kde_warnings: [], cles: { cles: 0.6, @@ -1563,23 +1408,7 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: 'regression', }, { @@ -1677,26 +1506,8 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { median: 319.45, sample_count: 2, kde_x: [], kde_y: [] }, - kde_base: { median: 316.35, sample_count: 2, kde_x: [], kde_y: [] }, kde_warnings: [], - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: 'improvement', }, { @@ -1785,26 +1596,8 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { median: 982.41, sample_count: 2, kde_x: [], kde_y: [] }, - kde_base: { median: 971.38, sample_count: 2, kde_x: [], kde_y: [] }, kde_warnings: [], - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: null, }, { @@ -1893,26 +1686,8 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { median: 984.16, sample_count: 3, kde_x: [], kde_y: [] }, - kde_base: { median: 973.66, sample_count: 3, kde_x: [], kde_y: [] }, kde_warnings: [], - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: null, }, { @@ -2001,26 +1776,8 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_new: { median: 984.16, sample_count: 3, kde_x: [], kde_y: [] }, - kde_base: { median: 973.66, sample_count: 3, kde_x: [], kde_y: [] }, kde_warnings: [], - silverman_kde: { - bandwidth: '', - base_mode_count: 0, - new_mode_count: 0, - modes: [], - base_locations: [], - new_locations: [], - base_prominence: 0, - new_prominence: 0, - warnings: [], - is_regression: null, - is_improvement: null, - }, - is_fit_good: null, - is_significant: null, is_new_better: null, - performance_intepretation: '', direction_of_change: null, }, ]; diff --git a/src/components/CompareResults/MannWhitneyCompareMetrics.tsx b/src/components/CompareResults/MannWhitneyCompareMetrics.tsx index 1cead497e..9c0e14850 100644 --- a/src/components/CompareResults/MannWhitneyCompareMetrics.tsx +++ b/src/components/CompareResults/MannWhitneyCompareMetrics.tsx @@ -1,7 +1,6 @@ import { Box } from '@mui/material'; import { MannWhitneyResultsItem } from '../../types/state'; -import { getModeInterpretation } from '../../utils/helpers'; const METRIC_HEADERS = ['Metric', 'Base', 'New', 'Interpretation']; @@ -52,8 +51,6 @@ export const MannWhitneyCompareMetrics = ({ result.shapiro_wilk_test_base?.interpretation ?? 'N/A'; const newShapiroWilkInterpretation = result.shapiro_wilk_test_new?.interpretation ?? 'N/A'; - const baseMode = result?.silverman_kde?.base_mode_count ?? null; - const newMode = result?.silverman_kde?.new_mode_count ?? null; return ( {`${result?.ks_test?.interpretation ?? ''}`} - - Distribution - - - Estimated Modes - {baseMode} - {newMode} - {getModeInterpretation(baseMode, newMode)} - diff --git a/src/components/CompareResults/ResultsTable.tsx b/src/components/CompareResults/ResultsTable.tsx index 3205fb5fe..d2586273b 100644 --- a/src/components/CompareResults/ResultsTable.tsx +++ b/src/components/CompareResults/ResultsTable.tsx @@ -76,7 +76,6 @@ export default function ResultsTable() { searchParams.set('test_version', testVersion); if (testVersion !== MANN_WHITNEY_U) { searchParams.delete('replicates'); - searchParams.delete('enable_silverman_kde'); } setSearchParams(searchParams); }; diff --git a/src/components/CompareResults/hashToCommitLoader.ts b/src/components/CompareResults/hashToCommitLoader.ts index 0f3de1ee5..a6f9a575c 100644 --- a/src/components/CompareResults/hashToCommitLoader.ts +++ b/src/components/CompareResults/hashToCommitLoader.ts @@ -67,9 +67,6 @@ export async function loader({ request }: { request: Request }) { const baseRevsFromHash = commits_from_hashes.baseRevision; const newRevsFromHash = [commits_from_hashes.newRevision]; const replicatesFromUrl = url.searchParams.has('replicates'); - const enableSilvermanKDEFromUrl = url.searchParams.has( - 'enable_silverman_kde', - ); const { baseRev, baseRepo, @@ -79,7 +76,6 @@ export async function loader({ request }: { request: Request }) { frameworkName, replicates, testVersion, - silvermanKDEEnabled, } = checkValues({ baseRev: baseRevsFromHash, baseRepo: baseRepoFromUrl, @@ -88,7 +84,6 @@ export async function loader({ request }: { request: Request }) { framework: frameworkFromUrl, replicates: replicatesFromUrl, testVersion: testVersionFromUrl, - silvermanKDEEnabled: enableSilvermanKDEFromUrl, }); return await getComparisonInformation( baseRev, @@ -98,7 +93,6 @@ export async function loader({ request }: { request: Request }) { frameworkId, frameworkName, replicates, - silvermanKDEEnabled, testVersion, ); } @@ -116,7 +110,6 @@ type HashLoaderData = { view: typeof compareView; generation: number; testVersion: TestVersion; - silvermanKDEEnabled: boolean; }; export type HashLoaderReturnValue = HashLoaderData; diff --git a/src/components/CompareResults/landoToCommitLoader.ts b/src/components/CompareResults/landoToCommitLoader.ts index 7f171613d..3dd29f463 100644 --- a/src/components/CompareResults/landoToCommitLoader.ts +++ b/src/components/CompareResults/landoToCommitLoader.ts @@ -33,9 +33,6 @@ export async function loader({ request }: { request: Request }) { ); } const replicatesFromUrl = url.searchParams.has('replicates'); - const enableSilvermanKDEFromUrl = url.searchParams.has( - 'enable_silverman_kde', - ); const baseRevisionsFromLando = await fetchRevisionFromLandoId( baseLandoIDFromUrl, @@ -57,7 +54,6 @@ export async function loader({ request }: { request: Request }) { frameworkName, replicates, testVersion, - silvermanKDEEnabled, } = checkValues({ baseRev: baseRevisionsFromLando.commit_id, baseRepo: baseRepoFromUrl, @@ -66,7 +62,6 @@ export async function loader({ request }: { request: Request }) { framework: frameworkFromUrl, replicates: replicatesFromUrl, testVersion: testVersionFromUrl, - silvermanKDEEnabled: enableSilvermanKDEFromUrl, }); return await getComparisonInformation( baseRev, @@ -76,7 +71,6 @@ export async function loader({ request }: { request: Request }) { frameworkId, frameworkName, replicates, - silvermanKDEEnabled, testVersion, ); } @@ -94,7 +88,6 @@ type LandoLoaderData = { view: typeof compareView; generation: number; testVersion: TestVersion; - silvermanKDEEnabled: boolean; }; export type LandoLoaderReturnValue = LandoLoaderData; diff --git a/src/components/CompareResults/loader.ts b/src/components/CompareResults/loader.ts index 06916b6e6..353db7eec 100644 --- a/src/components/CompareResults/loader.ts +++ b/src/components/CompareResults/loader.ts @@ -26,7 +26,6 @@ export function checkValues({ framework, replicates, testVersion, - silvermanKDEEnabled, }: { baseRev: string | null; baseRepo: Repository['name'] | null; @@ -35,7 +34,6 @@ export function checkValues({ framework: string | number | null; replicates: boolean; testVersion: TestVersion | null; - silvermanKDEEnabled: boolean; }): { baseRev: string; baseRepo: Repository['name']; @@ -45,7 +43,6 @@ export function checkValues({ frameworkName: Framework['name']; replicates: boolean; testVersion: TestVersion; - silvermanKDEEnabled: boolean; } { if (baseRev === null) { throw new Error('The parameter baseRev is missing.'); @@ -102,7 +99,6 @@ export function checkValues({ frameworkName, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -128,7 +124,6 @@ export function checkValues({ frameworkName, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -142,7 +137,6 @@ async function fetchCompareResultsOnTreeherder({ framework, replicates, testVersion, - silvermanKDEEnabled, }: { baseRev: string; baseRepo: Repository['name']; @@ -151,7 +145,6 @@ async function fetchCompareResultsOnTreeherder({ framework: Framework['id']; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled: boolean; }) { const promises = newRevs.map((newRev, i) => fetchCompareResults({ @@ -162,7 +155,6 @@ async function fetchCompareResultsOnTreeherder({ framework, replicates, testVersion, - silvermanKDEEnabled, }), ); return Promise.all(promises); @@ -234,9 +226,6 @@ export async function loader({ request }: { request: Request }) { const testVersionFromUrl = url.searchParams.get( 'test_version', ) as TestVersion; - const enableSilvermanKDEFromUrl = url.searchParams.has( - 'enable_silverman_kde', - ); const { baseRev, @@ -247,7 +236,6 @@ export async function loader({ request }: { request: Request }) { frameworkName, replicates, testVersion, - silvermanKDEEnabled, } = checkValues({ baseRev: baseRevFromUrl, baseRepo: baseRepoFromUrl, @@ -256,7 +244,6 @@ export async function loader({ request }: { request: Request }) { framework: frameworkFromUrl, replicates: replicatesFromUrl, testVersion: testVersionFromUrl, - silvermanKDEEnabled: enableSilvermanKDEFromUrl, }); return await getComparisonInformation( @@ -267,7 +254,6 @@ export async function loader({ request }: { request: Request }) { frameworkId, frameworkName, replicates, - silvermanKDEEnabled, testVersion, ); } @@ -280,7 +266,6 @@ export async function getComparisonInformation( frameworkId: Framework['id'], frameworkName: Framework['name'], replicates: boolean, - silvermanKDEEnabled: boolean, testVersion?: TestVersion, ) { const resultsPromise = fetchCompareResultsOnTreeherder({ @@ -291,7 +276,6 @@ export async function getComparisonInformation( framework: frameworkId, replicates, testVersion, - silvermanKDEEnabled, }); // TODO what happens if there's no result? @@ -325,7 +309,6 @@ export async function getComparisonInformation( generation: generationCounter++, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -343,7 +326,6 @@ type DeferredLoaderData = { generation: number; replicates: boolean; testVersion: TestVersion; - silvermanKDEEnabled: boolean; }; // Be explicit with the returned type to control it better than if we were diff --git a/src/components/CompareResults/overTimeLoader.ts b/src/components/CompareResults/overTimeLoader.ts index 206d04d04..b47be0ea5 100644 --- a/src/components/CompareResults/overTimeLoader.ts +++ b/src/components/CompareResults/overTimeLoader.ts @@ -26,7 +26,6 @@ function checkValues({ interval, replicates, testVersion, - silvermanKDEEnabled, }: { baseRepo: Repository['name'] | null; newRevs: string[]; @@ -35,7 +34,6 @@ function checkValues({ interval: string | number | null; replicates: boolean; testVersion?: TestVersion | null; - silvermanKDEEnabled: boolean; }): { baseRepo: Repository['name']; newRevs: string[]; @@ -46,7 +44,6 @@ function checkValues({ intervalText: TimeRange['text']; replicates: boolean; testVersion: TestVersion; - silvermanKDEEnabled: boolean; } { if (baseRepo === null) { throw new Error('The parameter baseRepo is missing.'); @@ -127,7 +124,6 @@ function checkValues({ intervalValue, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -141,7 +137,6 @@ async function fetchCompareOverTimeResultsOnTreeherder({ interval, replicates, testVersion, - silvermanKDEEnabled, }: { baseRepo: Repository['name']; newRevs: string[]; @@ -150,7 +145,6 @@ async function fetchCompareOverTimeResultsOnTreeherder({ interval: TimeRange['value']; replicates: boolean; testVersion: TestVersion; - silvermanKDEEnabled: boolean; }) { const promises = newRevs.map((newRev, i) => fetchCompareOverTimeResults({ @@ -161,7 +155,6 @@ async function fetchCompareOverTimeResultsOnTreeherder({ interval, replicates, testVersion, - silvermanKDEEnabled, }), ); return Promise.all(promises); @@ -193,9 +186,6 @@ export async function loader({ request }: { request: Request }) { const testVersionFromUrl = url.searchParams.get( 'test_version', ) as TestVersion; - const enableSilvermanKDEFromUrl = url.searchParams.has( - 'enable_silverman_kde', - ); const { baseRepo, @@ -207,7 +197,6 @@ export async function loader({ request }: { request: Request }) { intervalText, replicates, testVersion, - silvermanKDEEnabled, } = checkValues({ baseRepo: baseRepoFromUrl, newRevs: newRevsFromUrl, @@ -216,7 +205,6 @@ export async function loader({ request }: { request: Request }) { interval: intervalFromUrl, replicates: replicatesFromUrl, testVersion: testVersionFromUrl, - silvermanKDEEnabled: enableSilvermanKDEFromUrl, }); const resultsTimePromise = fetchCompareOverTimeResultsOnTreeherder({ @@ -227,7 +215,6 @@ export async function loader({ request }: { request: Request }) { interval: intervalValue, replicates, testVersion, - silvermanKDEEnabled, }); const newRevsInfoPromises = newRevs.map((newRev, i) => @@ -253,7 +240,6 @@ export async function loader({ request }: { request: Request }) { generation: generationCounter++, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -271,7 +257,6 @@ type DeferredLoaderData = { generation: number; replicates: boolean; testVersion: TestVersion; - silvermanKDEEnabled: boolean; }; // Be explicit with the returned type to control it better than if we were diff --git a/src/components/CompareResults/subtestsLoader.ts b/src/components/CompareResults/subtestsLoader.ts index 2e381b7ea..fcf3800ef 100644 --- a/src/components/CompareResults/subtestsLoader.ts +++ b/src/components/CompareResults/subtestsLoader.ts @@ -15,7 +15,6 @@ function checkValues({ newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }: { baseRev: string | null; baseRepo: Repository['name'] | null; @@ -26,7 +25,6 @@ function checkValues({ newParentSignature: string | null; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled: boolean; }): { baseRev: string; baseRepo: Repository['name']; @@ -38,7 +36,6 @@ function checkValues({ newParentSignature: string; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled: boolean; } { if (baseRev === null) { throw new Error('The parameter baseRev is missing.'); @@ -119,7 +116,6 @@ function checkValues({ newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -146,9 +142,6 @@ export function loader({ request }: { request: Request }) { const replicatesFromUrl = url.searchParams.has('replicates'); const testVersionFromUrl = (url.searchParams.get('test_version') ?? MANN_WHITNEY_U) as TestVersion; - const enableSilvermanKDEFromUrl = url.searchParams.has( - 'enable_silverman_kde', - ); const { baseRev, @@ -161,7 +154,6 @@ export function loader({ request }: { request: Request }) { baseParentSignature, replicates, testVersion, - silvermanKDEEnabled, } = checkValues({ baseRev: baseRevFromUrl, baseRepo: baseRepoFromUrl, @@ -172,7 +164,6 @@ export function loader({ request }: { request: Request }) { newParentSignature: newParentSignatureFromUrl, replicates: replicatesFromUrl, testVersion: testVersionFromUrl, - silvermanKDEEnabled: enableSilvermanKDEFromUrl, }); const results = fetchSubtestsCompareResults({ @@ -185,7 +176,6 @@ export function loader({ request }: { request: Request }) { newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }); return { @@ -200,7 +190,6 @@ export function loader({ request }: { request: Request }) { newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }; } diff --git a/src/components/CompareResults/subtestsOverTimeLoader.tsx b/src/components/CompareResults/subtestsOverTimeLoader.tsx index 906926b21..e45568305 100644 --- a/src/components/CompareResults/subtestsOverTimeLoader.tsx +++ b/src/components/CompareResults/subtestsOverTimeLoader.tsx @@ -20,7 +20,6 @@ function checkValues({ newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }: { baseRepo: Repository['name'] | null; newRev: string | null; @@ -31,7 +30,6 @@ function checkValues({ newParentSignature: string | null; replicates: boolean; testVersion?: TestVersion | null; - silvermanKDEEnabled: boolean; }): { baseRepo: Repository['name']; newRev: string; @@ -44,7 +42,6 @@ function checkValues({ newParentSignature: string; replicates: boolean; testVersion: TestVersion; - silvermanKDEEnabled: boolean; } { if (baseRepo === null) { throw new Error('The parameter baseRepo is missing.'); @@ -144,7 +141,6 @@ function checkValues({ newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }; } @@ -172,9 +168,6 @@ export function loader({ request }: { request: Request }) { const testVersionFromUrl = url.searchParams.get( 'test_version', ) as TestVersion; - const enableSilvermanKDEFromUrl = url.searchParams.has( - 'enable_silverman_kde', - ); const { baseRepo, newRev, @@ -187,7 +180,6 @@ export function loader({ request }: { request: Request }) { newParentSignature, replicates, testVersion, - silvermanKDEEnabled, } = checkValues({ baseRepo: baseRepoFromUrl, newRev: newRevFromUrl, @@ -198,7 +190,6 @@ export function loader({ request }: { request: Request }) { newParentSignature: newParentSignatureFromUrl, replicates: replicatesFromUrl, testVersion: testVersionFromUrl, - silvermanKDEEnabled: enableSilvermanKDEFromUrl, }); const results = fetchSubtestsCompareOverTimeResults({ @@ -211,7 +202,6 @@ export function loader({ request }: { request: Request }) { newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }); return { @@ -227,7 +217,6 @@ export function loader({ request }: { request: Request }) { newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }; } diff --git a/src/hooks/useSubtestRegressionCount.ts b/src/hooks/useSubtestRegressionCount.ts index 70b2ae572..a6db8008c 100644 --- a/src/hooks/useSubtestRegressionCount.ts +++ b/src/hooks/useSubtestRegressionCount.ts @@ -57,7 +57,6 @@ export function useSubtestRegressionCount({ setIsLoading(true); const searchParams = new URLSearchParams(location.search); - const silvermanKDEEnabled = searchParams.has('enable_silverman_kde'); let interval: TimeRange['value'] | null = null; if (view !== compareView) { const intervalStr = searchParams.get('selectedTimeRange'); @@ -78,7 +77,6 @@ export function useSubtestRegressionCount({ newParentSignature: String(new_signature_id), replicates, testVersion, - silvermanKDEEnabled, }) : memoizedFetchSubtestsCompareOverTimeResults({ baseRepo: base_repository_name, @@ -90,7 +88,6 @@ export function useSubtestRegressionCount({ newParentSignature: String(new_signature_id), replicates, testVersion, - silvermanKDEEnabled, }); const strategy: TestVersionStrategy = getStrategy(testVersion); diff --git a/src/logic/treeherder.ts b/src/logic/treeherder.ts index 45fb9bf45..b6921a9c2 100644 --- a/src/logic/treeherder.ts +++ b/src/logic/treeherder.ts @@ -22,7 +22,6 @@ type FetchProps = { framework: Framework['id']; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled?: boolean; }; type FetchOverTimeProps = { @@ -33,7 +32,6 @@ type FetchOverTimeProps = { interval: TimeRange['value']; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled?: boolean; }; type FetchSubtestsProps = { @@ -46,7 +44,6 @@ type FetchSubtestsProps = { newParentSignature: string; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled?: boolean; }; type FetchSubtestsOverTimeProps = { @@ -59,7 +56,6 @@ type FetchSubtestsOverTimeProps = { newParentSignature: string; replicates: boolean; testVersion?: TestVersion; - silvermanKDEEnabled?: boolean; }; export async function fetchRevisionFromHash( @@ -109,7 +105,6 @@ export async function fetchCompareResults({ framework, replicates, testVersion, - silvermanKDEEnabled, }: FetchProps) { const searchParams = new URLSearchParams({ base_repository: baseRepo, @@ -120,7 +115,6 @@ export async function fetchCompareResults({ no_subtests: 'true', replicates: String(replicates), test_version: testVersion ?? STUDENT_T, - enable_silverman_kde: String(silvermanKDEEnabled), }); const url = `${treeherderBaseURL}/api/perfcompare/results/?${searchParams.toString()}`; const response = await fetchFromTreeherder(url); @@ -137,7 +131,6 @@ export async function fetchCompareOverTimeResults({ interval, replicates, testVersion, - silvermanKDEEnabled, }: FetchOverTimeProps) { const searchParams = new URLSearchParams({ base_repository: baseRepo, @@ -148,7 +141,6 @@ export async function fetchCompareOverTimeResults({ no_subtests: 'true', replicates: String(replicates), test_version: testVersion ?? STUDENT_T, - enable_silverman_kde: String(silvermanKDEEnabled), }); const url = `${treeherderBaseURL}/api/perfcompare/results/?${searchParams.toString()}`; const response = await fetchFromTreeherder(url); @@ -167,7 +159,6 @@ export async function fetchSubtestsCompareResults({ newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }: FetchSubtestsProps) { const searchParams = new URLSearchParams({ base_repository: baseRepo, @@ -179,7 +170,6 @@ export async function fetchSubtestsCompareResults({ new_parent_signature: newParentSignature, replicates: String(replicates), test_version: testVersion ?? STUDENT_T, - enable_silverman_kde: String(silvermanKDEEnabled), }); const url = `${treeherderBaseURL}/api/perfcompare/results/?${searchParams.toString()}`; @@ -199,7 +189,6 @@ export async function fetchSubtestsCompareOverTimeResults({ newParentSignature, replicates, testVersion, - silvermanKDEEnabled, }: FetchSubtestsOverTimeProps) { const searchParams = new URLSearchParams({ base_repository: baseRepo, @@ -211,7 +200,6 @@ export async function fetchSubtestsCompareOverTimeResults({ new_parent_signature: newParentSignature, replicates: String(replicates), test_version: testVersion ?? STUDENT_T, - enable_silverman_kde: String(silvermanKDEEnabled), }); const url = `${treeherderBaseURL}/api/perfcompare/results/?${searchParams.toString()}`; diff --git a/src/types/state.ts b/src/types/state.ts index 2091e09ef..4ece99fb9 100644 --- a/src/types/state.ts +++ b/src/types/state.ts @@ -137,13 +137,6 @@ export type StatisticsTestItem = { /* KDE plot values for base or new runs. */ -export type KDEItem = { - median: number; - sample_count: number; - kde_x: number[]; - kde_y: number[]; -}; - /* Common Language Effect Size (CLES) results with Mann-Whitney U test. Interpretation of statistical effect and significance with what level of confidence interval. */ @@ -157,35 +150,6 @@ export type CLESItem = { cles_explanation?: string; } | null; -export type ModeItem = { - mode_name: string; - mode_start?: string; - mode_end?: string; - ci_low?: number | null; - ci_high?: number | null; - ci_warning?: string | null; - shift?: number | null; - shift_summary?: string | null; - median_shift_summary?: string | null; -}; - -/* - Results from Silverman KDE test for multimodal data. -*/ -export type SilvermanKDEItem = { - bandwidth: string; - base_mode_count: number; - new_mode_count: number; - base_locations: number[]; - new_locations: number[]; - base_prominence: number; - new_prominence: number; - warnings: string[]; - modes: ModeItem[]; - is_regression: boolean | null; - is_improvement: boolean | null; -}; - /* Results from the Mann-Whitney U test comparing two sets of runs. */ @@ -221,15 +185,9 @@ export type MannWhitneyResultsItem = { cliffs_delta: number; cliffs_interpretation: string; cles?: CLESItem; // CLES: Common Language Effect Size, statistical effect interpretation from Mann-Whitney U - kde_new: KDEItem; // KDE plots and summary plot with ISJ bandwidth for new runs - kde_base: KDEItem; // KDE plots and summary plot with ISJ bandwidth for base runs kde_warnings: string[]; silverman_warnings?: string[] | null; // silverman warnings about multimodal data - silverman_kde: SilvermanKDEItem; // Silverman KDE multimodal warnings and confidence interval - is_fit_good: boolean | null; // short form interpretation of KS test goodness of fit - is_significant: boolean | null; // is the result statistically significant is_new_better: boolean | null; // is the new revision better than the base revision - performance_intepretation: string; // short text interpretation of the performance change direction_of_change: 'no change' | 'improvement' | 'regression' | null; new_is_better: boolean | null; lower_is_better: boolean | null; @@ -241,7 +199,6 @@ export type MannWhitneyResultsItem = { is_regression: boolean | null; is_meaningful: boolean | null; more_runs_are_needed: boolean | null; - warning_c_delta?: string | null; /* Each test has a signature and each signature may or may not have a parent_signature. If a signature has a parent_signature then we are looking at a subtest. For regular tests this field will be null. diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 682dc8876..31de1db90 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -124,31 +124,6 @@ const swapArrayElements = ( return array; }; -// Mode interpretation base on mode counts -const getModeInterpretation = ( - baseModeCount: number | null, - newModeCount: number | null, -) => { - const interpretModeCount = (modeCount: number | null) => { - if (!modeCount) return 'N/A'; - if (modeCount === 1) return 'unimodal'; - if (modeCount > 1) return 'multimodal'; - return 'N/A'; - }; - if ( - (!baseModeCount && !newModeCount) || - (baseModeCount === 0 && newModeCount === 0) || - (!baseModeCount && newModeCount === 0) || - (baseModeCount === 0 && !newModeCount) - ) - return 'No modes or data for Base and New, possible oversmoothing, KDE evaluation failed'; - if (baseModeCount && newModeCount && baseModeCount === newModeCount) - return `Base and New revisions are ${interpretModeCount(baseModeCount)}`; - else { - return `Base is ${interpretModeCount(baseModeCount)} and New is ${interpretModeCount(newModeCount)}`; - } -}; - const capitalize = (str: string) => { if (str === '') return ''; return str.charAt(0).toUpperCase() + str.slice(1); @@ -162,6 +137,5 @@ export { swapArrayElements, truncateHash, getDocsURL, - getModeInterpretation, capitalize, }; From e519b8d9cf7878fd1a42149d5cc471a83d24a00e Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Tue, 18 Aug 2026 16:12:29 -0700 Subject: [PATCH 09/19] Removed silverman and kde warnings (#1082) removed silverman and kde warnings --- .../CompareResults/RevisionRowExpandable.test.tsx | 4 ---- src/__tests__/utils/fixtures.ts | 14 -------------- .../CompareResults/StatisticsWarnings.tsx | 2 -- src/types/state.ts | 2 -- 4 files changed, 22 deletions(-) diff --git a/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx b/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx index 542c0a22a..5c002d62a 100644 --- a/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx +++ b/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx @@ -73,15 +73,11 @@ describe('RevisionRowExpandable for mann-whitney-u testVersion', () => { />, ); - const expectedWarning1 = - 'Less than 2 datapoints or no standard variance for a meaningful fit Kernel Density Estimator (KDE) with an ISJ bandwidth to Base.'; const shapiroWarning = 'Shapiro-Wilk test cannot be run on Base with fewer than 3 data points.'; const shapiroWarning2 = 'Shapiro-Wilk test cannot be run on New with fewer than 3 data points.'; - const warning1 = await screen.findByText(expectedWarning1); - expect(warning1).toBeInTheDocument(); const swWarning = await screen.findByText(shapiroWarning); expect(swWarning).toBeInTheDocument(); const swWarning2 = await screen.findByText(shapiroWarning2); diff --git a/src/__tests__/utils/fixtures.ts b/src/__tests__/utils/fixtures.ts index 1572ade36..d192b2d94 100644 --- a/src/__tests__/utils/fixtures.ts +++ b/src/__tests__/utils/fixtures.ts @@ -452,7 +452,6 @@ const getTestData = () => { is_new_better: null, direction_of_change: 'improvement', - kde_warnings: [], }, { base_rev: 'coconut', @@ -543,7 +542,6 @@ const getTestData = () => { is_new_better: null, direction_of_change: 'regression', shapiro_wilk_test_base: null, - kde_warnings: [], }, { base_rev: 'coconut', @@ -627,7 +625,6 @@ const getTestData = () => { }, is_new_better: null, direction_of_change: null, - kde_warnings: [], }, { base_rev: 'coconut', @@ -710,7 +707,6 @@ const getTestData = () => { }, is_new_better: null, direction_of_change: null, - kde_warnings: [], }, ]; @@ -1301,11 +1297,6 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - silverman_warnings: [], - kde_warnings: [ - 'Less than 2 datapoints or no standard variance for a meaningful fit Kernel Density Estimator (KDE) with an ISJ bandwidth to Base.', - 'Less than 2 datapoints or no standard variance for a meaningful fit Kernel Density Estimator (KDE) with an ISJ bandwidth to New.', - ], new_is_better: null, }; @@ -1398,7 +1389,6 @@ const getTestData = () => { }, cliffs_delta: 0.02, cliffs_interpretation: 'negligible', - kde_warnings: [], cles: { cles: 0.6, cles_direction: '', @@ -1506,7 +1496,6 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_warnings: [], is_new_better: null, direction_of_change: 'improvement', }, @@ -1596,7 +1585,6 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_warnings: [], is_new_better: null, direction_of_change: null, }, @@ -1686,7 +1674,6 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_warnings: [], is_new_better: null, direction_of_change: null, }, @@ -1776,7 +1763,6 @@ const getTestData = () => { effect_size: '', cles_explanation: '', }, - kde_warnings: [], is_new_better: null, direction_of_change: null, }, diff --git a/src/components/CompareResults/StatisticsWarnings.tsx b/src/components/CompareResults/StatisticsWarnings.tsx index 513de1b6b..ca3ad4065 100644 --- a/src/components/CompareResults/StatisticsWarnings.tsx +++ b/src/components/CompareResults/StatisticsWarnings.tsx @@ -32,9 +32,7 @@ export const StatisticsWarnings = ({ // Combine all warnings into a single list const warnings: string[] = [ ...(result?.shapiro_wilk_warnings ?? []), - ...(result?.silverman_warnings ?? []), ...(result?.ks_warning ? [result?.ks_warning] : []), - ...(result?.kde_warnings ?? []), ]; return ( <> diff --git a/src/types/state.ts b/src/types/state.ts index 4ece99fb9..fd0b467b0 100644 --- a/src/types/state.ts +++ b/src/types/state.ts @@ -185,8 +185,6 @@ export type MannWhitneyResultsItem = { cliffs_delta: number; cliffs_interpretation: string; cles?: CLESItem; // CLES: Common Language Effect Size, statistical effect interpretation from Mann-Whitney U - kde_warnings: string[]; - silverman_warnings?: string[] | null; // silverman warnings about multimodal data is_new_better: boolean | null; // is the new revision better than the base revision direction_of_change: 'no change' | 'improvement' | 'regression' | null; new_is_better: boolean | null; From cc86b883c12e68b3e573774284d498b30a0837c6 Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Wed, 19 Aug 2026 17:14:57 -0700 Subject: [PATCH 10/19] Bug 2059826 - Simplified View: Create checkbox selection for advanced columns and display how to read the results (#1069) * Create simplified view and advanced column options Update tests too Adjust styles for new table changes created toggle for customizing col: simple vs power view update tests to reflect new UI/UX add interpret results panel for simple users render 0.00 vs - for no data in median col update table to include significance; add difference below status update how to read the results Add an "Advanced columns" dropdown with independent Cliff's Delta and CLES Hidden by default; the choice persists to localStorage. Available on both the main and subtests pages. Persist advanced-column selection in the URL resolved PR review comments Add sortable/filterable Magnitude column and widen the results table * resolved PR comments * Make Advanced Columns a native Select and move it into the inputs row * Move Significance to an advanced column and surface Noise in Status * resolved comments --- eslint.config.mjs | 9 + src/__tests__/App.test.tsx | 14 +- .../CompareResults/ResultsTable.test.tsx | 561 +++-- .../CompareResults/ResultsView.test.tsx | 20 + .../CompareResults/RevisionRow.test.tsx | 18 +- .../SubtestsResultsView.test.tsx | 148 +- .../SubtestsRevisionRow.test.tsx | 24 +- .../OverTimeResultsView.test.tsx.snap | 866 +++---- .../__snapshots__/ResultsTable.test.tsx.snap | 2178 ++++++++++------- .../__snapshots__/ResultsView.test.tsx.snap | 880 +++---- .../__snapshots__/SearchInput.test.tsx.snap | 2 +- .../SubtestsResultsView.test.tsx.snap | 1873 ++++++-------- .../SubtestsRevisionRow.test.tsx.snap | 6 +- .../CompareOverTime.test.tsx.snap | 8 +- .../CompareWithBase.test.tsx.snap | 28 +- src/__tests__/utils/test-utils.tsx | 15 + src/common/constants.ts | 14 +- src/common/store.ts | 2 + src/common/testVersions/index.ts | 16 +- src/common/testVersions/mannWhitney.tsx | 621 +++-- src/common/testVersions/studentT.tsx | 18 +- .../CompareResults/AdvancedColumnsMenu.tsx | 123 + .../CompareResults/HowToReadResults.tsx | 68 + .../CompareResults/ResultsControls.tsx | 160 +- src/components/CompareResults/ResultsMain.tsx | 10 +- .../CompareResults/ResultsTable.tsx | 18 +- src/components/CompareResults/RevisionRow.tsx | 6 +- .../SubtestsResults/SubtestsResultsMain.tsx | 7 +- .../SubtestsResults/SubtestsResultsTable.tsx | 11 +- .../SubtestsResults/SubtestsRevisionRow.tsx | 14 +- src/components/CompareResults/TableHeader.tsx | 31 +- .../CompareResults/TableRevisionContent.tsx | 9 +- src/hooks/useAdvancedColumns.ts | 24 + src/hooks/useSeedAdvancedColumnsFromUrl.ts | 34 + src/reducers/ColumnPrefsSlice.ts | 50 + src/types/types.ts | 9 + src/utils/advancedColumnsUrl.ts | 42 + src/utils/rowTemplateColumns.ts | 6 +- 38 files changed, 4413 insertions(+), 3530 deletions(-) create mode 100644 src/components/CompareResults/AdvancedColumnsMenu.tsx create mode 100644 src/components/CompareResults/HowToReadResults.tsx create mode 100644 src/hooks/useAdvancedColumns.ts create mode 100644 src/hooks/useSeedAdvancedColumnsFromUrl.ts create mode 100644 src/reducers/ColumnPrefsSlice.ts create mode 100644 src/utils/advancedColumnsUrl.ts diff --git a/eslint.config.mjs b/eslint.config.mjs index bb044cad0..4ff2f8773 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -82,6 +82,15 @@ export default defineConfig([ projectService: true, }, }, + + rules: { + // Allow intentionally-unused args to be marked with a leading underscore + // (e.g. interface methods that ignore a parameter). + '@typescript-eslint/no-unused-vars': [ + 'error', + { argsIgnorePattern: '^_' }, + ], + }, }, { // Typescript test files diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx index b7645d421..378d344db 100644 --- a/src/__tests__/App.test.tsx +++ b/src/__tests__/App.test.tsx @@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event'; import App, { router } from '../components/App'; import getTestData from './utils/fixtures'; -import { act, render, screen } from './utils/test-utils'; +import { act, render, screen, within } from './utils/test-utils'; describe('App', () => { beforeEach(() => { @@ -398,11 +398,13 @@ describe('App', () => { // Wait for the page to load await screen.findByText('a11yr'); - // Verify that Mann-Whitney-U specific columns are rendered - // (this indicates the testVersion defaulted to mann-whitney-u) - expect(screen.getByText('CD')).toBeInTheDocument(); - expect(screen.getByText('Sig')).toBeInTheDocument(); - expect(screen.getByText('CLES (%)')).toBeInTheDocument(); + // Verify a Mann-Whitney-U specific column is rendered — "Δ Median" is + // unique to the Mann-Whitney strategy (Student-T uses "Delta"), so its + // presence in the table header indicates the testVersion defaulted to + // mann-whitney-u. Scope to the header since the "How to read the results" + // panel also names it. + const tableHeader = screen.getByTestId('table-header'); + expect(within(tableHeader).getByText('Δ Median')).toBeInTheDocument(); // Verify the Stats Test Version dropdown shows Mann-Whitney-U as selected const testVersionDropdown = screen.getByRole('combobox', { diff --git a/src/__tests__/CompareResults/ResultsTable.test.tsx b/src/__tests__/CompareResults/ResultsTable.test.tsx index c663ada1d..bfd8e35bd 100644 --- a/src/__tests__/CompareResults/ResultsTable.test.tsx +++ b/src/__tests__/CompareResults/ResultsTable.test.tsx @@ -14,7 +14,13 @@ import getTestData, { augmentCompareMannWhitneyDataWithSeveralRevisions, augmentCompareMannWhitneyDataWithSeveralTests, } from '../utils/fixtures'; -import { renderWithRouter, screen, waitFor, within } from '../utils/test-utils'; +import { + renderWithRouter, + screen, + waitFor, + within, + enableAdvancedColumns, +} from '../utils/test-utils'; function renderWithRoute(component: ReactElement, extraParameters?: string) { return renderWithRouter(component, { @@ -48,7 +54,7 @@ function setupAndRender( // This handy function parses the results page and returns an array of visible // rows. It makes it easy to assert visible rows when filtering them in a // user-friendly way without using snapshots. -function summarizeVisibleRows(testVersion?: TestVersion) { +function summarizeVisibleRows(testVersion?: TestVersion, advanced = false) { const rowGroups = screen.getAllByRole('rowgroup'); const result = []; @@ -83,17 +89,34 @@ function summarizeVisibleRows(testVersion?: TestVersion) { for (const row of rows) { const rowClasses = testVersion === 'mann-whitney-u' - ? [ - '.platform span', - '.median-diff', - '.status', - '.delta', - '.significance', - '.effects', - ] + ? advanced + ? [ + '.platform span', + '.median-diff', + '.status-hint', + '.delta', + '.significance', + '.effects', + ] + : [ + '.platform span', + '.median-diff', + '.status-hint', + '.magnitude', + '.significance', + ] : ['.platform span', '.status', '.delta', '.confidence']; const rowString = rowClasses - .map((selector) => row.querySelector(selector)?.textContent?.trim()) + .map((selector) => { + const cell = row.querySelector(selector); + if (!cell) return undefined; + // Strip icon text (e.g. the median-diff normality warning) + // so the data-focused expectations stay stable; icon presence is + // asserted separately. + const clone = cell.cloneNode(true) as HTMLElement; + clone.querySelectorAll('svg').forEach((svg) => svg.remove()); + return clone.textContent?.trim(); + }) .join(', '); result.push(' - ' + rowString); @@ -690,6 +713,13 @@ describe('Results Table', () => { }); describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion', () => { + // These tests exercise the full (advanced) table — CD, CLES, Sig columns and + // their sort/filter behavior. The simplified default view (which hides + // CD/CLES and shows the Magnitude column) is covered separately below. + beforeEach(() => { + enableAdvancedColumns(); + }); + it('Should match snapshot', async () => { const { testCompareMannWhitneyData } = getTestData(); @@ -719,12 +749,12 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio setupAndRender(simplerTestCompareData, 'test_version=mann-whitney-u'); await screen.findByText('a11yr'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ' rev: devilrabbit', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); expect(screen.getByRole('rowgroup')).toMatchSnapshot(); }); @@ -746,25 +776,25 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); await screen.findByText('a11yr'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - inexistant, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - inexistant, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); await clickMenuItem(user, 'Platform', /Windows/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'linux', 'android', 'ios'], @@ -773,78 +803,78 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Clicking Windows again should remove the search param and make the // "inexitant" platform visible again. await clickMenuItem(user, 'Platform', /Windows/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - inexistant, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - inexistant, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); await clickMenuItem(user, 'Platform', /Windows/); await clickMenuItem(user, 'Platform', /Linux/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'android', 'ios'], }); await clickMenuItem(user, 'Platform', /Linux/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'android', 'ios', 'linux'], }); await clickMenuItem(user, 'Platform', 'Select all values'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - inexistant, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - inexistant, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); await clickMenuItem(user, 'Platform', /macOS/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['windows', 'linux', 'android', 'ios'], }); await clickMenuItem(user, 'Platform', /Android/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['windows', 'linux', 'ios'], }); await clickMenuItem(user, 'Platform', /Select only.*Android/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Android, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['android'], @@ -858,16 +888,16 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); - // Filter only "Significant" + // Filter only "Real" (significant) const signifianceMenu = await screen.findByRole('button', { name: /Sig.*filter/, }); await user.click(signifianceMenu); expect(signifianceMenu).toMatchSnapshot(); - // significant item 0 and Not significant item 1 + // "Real" is item 0, "Noise" (not significant) is item 1 const significantOptions = await screen.findAllByRole('menuitemcheckbox', { - name: /Significant/, + name: /Real|Noise/, }); await user.click(significantOptions[1]); await user.keyboard('[Escape]'); @@ -881,74 +911,49 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); await screen.findByText('a11yr'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); - await clickMenuItem(user, 'Status', /No changes/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ]); - expect(summarizeTableFiltersFromUrl()).toEqual({ - status: ['improvement', 'regression'], - }); - await clickMenuItem(user, 'Status', /Improvement/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + // Noise is mutually exclusive with the direction buckets: selecting only + // Noise shows the not-significant rows regardless of their direction. + await clickMenuItem(user, 'Status', /Select only.*Noise/); + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); - expect(summarizeTableFiltersFromUrl()).toEqual({ - status: ['regression'], - }); + expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['noise'] }); + // Unchecking Noise (the three direction buckets stay checked) hides the + // noisy rows and leaves only the real (significant) rows. await clickMenuItem(user, 'Status', /Select all values/); - await clickMenuItem(user, 'Status', /Regression/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', - ]); - expect(summarizeTableFiltersFromUrl()).toEqual({ - status: ['none', 'improvement'], - }); - - await clickMenuItem(user, 'Status', /Regression/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', - ]); - expect(summarizeTableFiltersFromUrl()).toEqual({}); - - await clickMenuItem(user, 'Status', /Select only.*Regression/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + await clickMenuItem(user, 'Status', /^Noise/); + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ - status: ['regression'], + status: ['none', 'improvement', 'regression'], }); - await clickMenuItem(user, 'Status', /Select only.*Improvement/); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + // A direction bucket only matches real rows, so "No changes" shows the two + // significant no-change rows. + await clickMenuItem(user, 'Status', /Select only.*No changes/); + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); - expect(summarizeTableFiltersFromUrl()).toEqual({ - status: ['improvement'], - }); + expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['none'] }); }); it('can load the filter parameters from the URL on mann-whitney-u test_version', async () => { @@ -959,15 +964,15 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ); await screen.findByText('dhtml.html'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', ]); const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); expect(await summarizeTableFiltersFromCheckboxes(user)).toEqual({ 'Platform(2)': ['macOS', 'Android'], - 'Sig(2)': ['Significant', 'Not Significant-'], - 'Status(3)': ['No changes', 'Improvement', 'Regression'], + 'Sig(2)': ['Real', 'Noise'], + 'Status(4)': ['No changes', 'Improvement', 'Regression', 'Noise'], }); // After a change, "foo" should disappear @@ -994,29 +999,29 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(deltaButton).toMatchSnapshot(); // // Sort descending - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', - ' - Windows 10, -, , 1.2, , 99.00 %', - ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - Linux 18.04, +1.85%, Regression, 1.2, Noise, 44.00 %', + ' - macOS 10.15, +1.08%, Improvement, 1.3, Noise, 24.00 %', + ' - Windows 10, -, , 1.2, Real, 99.00 %', + ' - Windows 10, -2.40%, , 1.2, Real, 49.00 %', ' rev: tictactoe', - ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', - ' - Windows 10, -, , 2, , 98.00 %', - ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - Linux 18.04, +1.85%, Regression, 2, Noise, 43.00 %', + ' - macOS 10.15, +1.08%, Improvement, 2.1, Noise, 23.00 %', + ' - Windows 10, -, , 2, Real, 98.00 %', + ' - Windows 10, -2.40%, , 2, Real, 48.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ' rev: tictactoe', - ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', - ' - Windows 10, -, , 0.8, , 99.00 %', - ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - Linux 18.04, +1.85%, Regression, 0.8, Noise, 44.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.9, Noise, 24.00 %', + ' - Windows 10, -, , 0.8, Real, 99.00 %', + ' - Windows 10, -2.40%, , 0.8, Real, 49.00 %', ]); // It should have the "descending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1025,29 +1030,29 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // sort ascending await user.click(deltaButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', - ' - Windows 10, -2.401 %, , 2, , 48.00 %', - ' - Windows 10, -, , 2, , 98.00 %', + ' - macOS 10.15, +1.08%, Improvement, 2.1, Noise, 23.00 %', + ' - Linux 18.04, +1.85%, Regression, 2, Noise, 43.00 %', + ' - Windows 10, -2.40%, , 2, Real, 48.00 %', + ' - Windows 10, -, , 2, Real, 98.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', - ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', - ' - Windows 10, -, , 1.2, , 99.00 %', + ' - macOS 10.15, +1.08%, Improvement, 1.3, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 1.2, Noise, 44.00 %', + ' - Windows 10, -2.40%, , 1.2, Real, 49.00 %', + ' - Windows 10, -, , 1.2, Real, 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', - ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', - ' - Windows 10, -, , 0.8, , 99.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.9, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 0.8, Noise, 44.00 %', + ' - Windows 10, -2.40%, , 0.8, Real, 49.00 %', + ' - Windows 10, -, , 0.8, Real, 99.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', - ' - Windows 10, -, , -, , 100.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1059,29 +1064,29 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio name: /Sig.*sort/, }); await user.click(significanceButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', - ' - Windows 10, -, , 2, , 98.00 %', - ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - macOS 10.15, +1.08%, Improvement, 2.1, Noise, 23.00 %', + ' - Linux 18.04, +1.85%, Regression, 2, Noise, 43.00 %', + ' - Windows 10, -, , 2, Real, 98.00 %', + ' - Windows 10, -2.40%, , 2, Real, 48.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', - ' - Windows 10, -, , 1.2, , 99.00 %', - ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - macOS 10.15, +1.08%, Improvement, 1.3, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 1.2, Noise, 44.00 %', + ' - Windows 10, -, , 1.2, Real, 99.00 %', + ' - Windows 10, -2.40%, , 1.2, Real, 49.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', - ' - Windows 10, -, , 0.8, , 99.00 %', - ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.9, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 0.8, Noise, 44.00 %', + ' - Windows 10, -, , 0.8, Real, 99.00 %', + ' - Windows 10, -2.40%, , 0.8, Real, 49.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ]); // It should have the "descending" SVG. expect(significanceButton).toMatchSnapshot(); @@ -1090,29 +1095,29 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by Significance ascending await user.click(significanceButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -2.401 %, , -, , 50.00 %', - ' - Windows 10, -, , -, , 100.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', ' rev: tictactoe', - ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', - ' - Windows 10, -, , 0.8, , 99.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', + ' - Windows 10, -2.40%, , 0.8, Real, 49.00 %', + ' - Windows 10, -, , 0.8, Real, 99.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.9, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 0.8, Noise, 44.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', - ' - Windows 10, -, , 1.2, , 99.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', + ' - Windows 10, -2.40%, , 1.2, Real, 49.00 %', + ' - Windows 10, -, , 1.2, Real, 99.00 %', + ' - macOS 10.15, +1.08%, Improvement, 1.3, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 1.2, Noise, 44.00 %', ' rev: tictactoe', - ' - Windows 10, -2.401 %, , 2, , 48.00 %', - ' - Windows 10, -, , 2, , 98.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', + ' - Windows 10, -2.40%, , 2, Real, 48.00 %', + ' - Windows 10, -, , 2, Real, 98.00 %', + ' - macOS 10.15, +1.08%, Improvement, 2.1, Noise, 23.00 %', + ' - Linux 18.04, +1.85%, Regression, 2, Noise, 43.00 %', ]); // It should have the "descending" SVG. expect(significanceButton).toMatchSnapshot(); @@ -1121,32 +1126,32 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by Effect Size (%) descending const effectSizeButton = screen.getByRole('button', { - name: /CLES \(%\).*sort/, + name: /CLES.*sort/, }); await user.click(effectSizeButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -, , -, , 100.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', ' rev: tictactoe', - ' - Windows 10, -, , 0.8, , 99.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', - ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - Windows 10, -, , 0.8, Real, 99.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.9, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 0.8, Noise, 44.00 %', + ' - Windows 10, -2.40%, , 0.8, Real, 49.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -, , 1.2, , 99.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', - ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - Windows 10, -, , 1.2, Real, 99.00 %', + ' - macOS 10.15, +1.08%, Improvement, 1.3, Noise, 24.00 %', + ' - Linux 18.04, +1.85%, Regression, 1.2, Noise, 44.00 %', + ' - Windows 10, -2.40%, , 1.2, Real, 49.00 %', ' rev: tictactoe', - ' - Windows 10, -, , 2, , 98.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', - ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - Windows 10, -, , 2, Real, 98.00 %', + ' - macOS 10.15, +1.08%, Improvement, 2.1, Noise, 23.00 %', + ' - Linux 18.04, +1.85%, Regression, 2, Noise, 43.00 %', + ' - Windows 10, -2.40%, , 2, Real, 48.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); @@ -1155,46 +1160,46 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by Effect Size (%) ascending await user.click(effectSizeButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -2.401 %, , -, , 50.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', - ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.40%, , -, Real, 50.00 %', + ' - Linux 18.04, +1.85%, Regression, -, Noise, 45.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.1, Noise, 25.00 %', + ' - Windows 10, -, , -, Real, 100.00 %', ' rev: tictactoe', - ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', - ' - Windows 10, -, , 0.8, , 99.00 %', + ' - Windows 10, -2.40%, , 0.8, Real, 49.00 %', + ' - Linux 18.04, +1.85%, Regression, 0.8, Noise, 44.00 %', + ' - macOS 10.15, +1.08%, Improvement, 0.9, Noise, 24.00 %', + ' - Windows 10, -, , 0.8, Real, 99.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', - ' - Windows 10, -, , 1.2, , 99.00 %', + ' - Windows 10, -2.40%, , 1.2, Real, 49.00 %', + ' - Linux 18.04, +1.85%, Regression, 1.2, Noise, 44.00 %', + ' - macOS 10.15, +1.08%, Improvement, 1.3, Noise, 24.00 %', + ' - Windows 10, -, , 1.2, Real, 99.00 %', ' rev: tictactoe', - ' - Windows 10, -2.401 %, , 2, , 48.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', - ' - Windows 10, -, , 2, , 98.00 %', + ' - Windows 10, -2.40%, , 2, Real, 48.00 %', + ' - Linux 18.04, +1.85%, Regression, 2, Noise, 43.00 %', + ' - macOS 10.15, +1.08%, Improvement, 2.1, Noise, 23.00 %', + ' - Windows 10, -, , 2, Real, 98.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); // It should be persisted in the URL expectParameterToHaveValue('sort', 'effects|asc'); - // Sort by MD(%) descending + // Sort by Δ Median descending const medianDiffButton = screen.getByRole('button', { - name: /MD \(%\).*sort/, + name: /Δ Median.*sort/, }); await user.click(medianDiffButton); - expect(summarizeVisibleRows('mann-whitney-u')).toMatchSnapshot(); + expect(summarizeVisibleRows('mann-whitney-u', true)).toMatchSnapshot(); expect(medianDiffButton).toMatchSnapshot(); expectParameterToHaveValue('sort', 'median-diff|desc'); // Sort by MD(%) ascending await user.click(medianDiffButton); - expect(summarizeVisibleRows('mann-whitney-u')).toMatchSnapshot(); + expect(summarizeVisibleRows('mann-whitney-u', true)).toMatchSnapshot(); expect(medianDiffButton).toMatchSnapshot(); expectParameterToHaveValue('sort', 'median-diff|asc'); }); @@ -1248,3 +1253,115 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio }); }); }); + +describe('Advanced-columns toggle for mann-whitney-u testVersion', () => { + it('shows Magnitude but hides CD/CLES/Sig in the simplified (default) view', async () => { + const { testCompareMannWhitneyData } = getTestData(); + setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); + await screen.findByText('a11yr'); + + const header = screen.getByTestId('table-header'); + // Only Magnitude is shown in the simplified view; CD/CLES/Sig are all + // advanced columns and hidden by default. + expect(header.querySelector('.magnitude-header')).toBeTruthy(); + expect(header.querySelector('.significance-header')).toBeFalsy(); + expect(header.querySelector('.delta-header')).toBeFalsy(); + expect(header.querySelector('.effects-header')).toBeFalsy(); + }); + + it('reveals CD/CLES/Sig and hides Magnitude when advanced columns are enabled', async () => { + enableAdvancedColumns(); + const { testCompareMannWhitneyData } = getTestData(); + setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); + await screen.findByText('a11yr'); + + const header = screen.getByTestId('table-header'); + expect(header.querySelector('.delta-header')).toBeTruthy(); + expect(header.querySelector('.effects-header')).toBeTruthy(); + expect(header.querySelector('.significance-header')).toBeTruthy(); + expect(header.querySelector('.magnitude-header')).toBeFalsy(); + }); + + it('can filter on the Magnitude column', async () => { + const { testCompareMannWhitneyData } = getTestData(); + setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); + await screen.findByText('a11yr'); + expect(summarizeTableFiltersFromUrl()).toEqual({}); + + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + await clickMenuItem(user, 'Magnitude', /Select only.*Negligible/); + expect(summarizeTableFiltersFromUrl()).toEqual({ + magnitude: ['negligible'], + }); + }); + + it('toggles Cliff’s Delta and CLES independently from the Advanced columns dropdown', async () => { + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + const { testCompareMannWhitneyData } = getTestData(); + setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); + await screen.findByText('a11yr'); + + const header = () => screen.getByTestId('table-header'); + // Simplified default: neither advanced column. + expect(header().querySelector('.delta-header')).toBeFalsy(); + expect(header().querySelector('.effects-header')).toBeFalsy(); + + // Open the dropdown and enable Cliff's Delta only. + await user.click( + screen.getByRole('combobox', { name: 'Advanced columns' }), + ); + await user.click(screen.getByRole('option', { name: "Cliff's Delta" })); + expect(header().querySelector('.delta-header')).toBeTruthy(); + expect(header().querySelector('.effects-header')).toBeFalsy(); + + // Enable CLES too — both show. + await user.click(screen.getByRole('option', { name: 'CLES' })); + expect(header().querySelector('.delta-header')).toBeTruthy(); + expect(header().querySelector('.effects-header')).toBeTruthy(); + + // Turn Cliff's Delta back off — only CLES remains. + await user.click(screen.getByRole('option', { name: "Cliff's Delta" })); + expect(header().querySelector('.delta-header')).toBeFalsy(); + expect(header().querySelector('.effects-header')).toBeTruthy(); + }); + + it('shows the advanced columns named in the advanced_columns URL param', async () => { + const { testCompareMannWhitneyData } = getTestData(); + setupAndRender( + testCompareMannWhitneyData, + 'test_version=mann-whitney-u&advanced_columns=cliffs_delta', + ); + await screen.findByText('a11yr'); + + const header = screen.getByTestId('table-header'); + expect(header.querySelector('.delta-header')).toBeTruthy(); + expect(header.querySelector('.effects-header')).toBeFalsy(); + }); + + it('persists the advanced-column selection to the advanced_columns URL param', async () => { + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + const { testCompareMannWhitneyData } = getTestData(); + setupAndRender(testCompareMannWhitneyData, 'test_version=mann-whitney-u'); + await screen.findByText('a11yr'); + + const advancedParam = () => + new URLSearchParams(window.location.search).get('advanced_columns'); + expect(advancedParam()).toBeNull(); + + await user.click( + screen.getByRole('combobox', { name: 'Advanced columns' }), + ); + await user.click(screen.getByRole('option', { name: "Cliff's Delta" })); + expect(advancedParam()).toBe('cliffs_delta'); + + await user.click(screen.getByRole('option', { name: 'CLES' })); + expect(advancedParam()).toBe('cliffs_delta,cles'); + + // Turning a column off updates the param; turning the last one off removes it. + await user.click(screen.getByRole('option', { name: "Cliff's Delta" })); + expect(advancedParam()).toBe('cles'); + + await user.click(screen.getByRole('option', { name: 'CLES' })); + expect(advancedParam()).toBeNull(); + }); +}); diff --git a/src/__tests__/CompareResults/ResultsView.test.tsx b/src/__tests__/CompareResults/ResultsView.test.tsx index bb5f9e370..4f5200859 100644 --- a/src/__tests__/CompareResults/ResultsView.test.tsx +++ b/src/__tests__/CompareResults/ResultsView.test.tsx @@ -564,4 +564,24 @@ describe('Results View', () => { expect(screen.queryAllByTestId(/ExpandLessIcon/)).toHaveLength(0); }); }); + + it('shows the "How to read the results" panel by default and lets the user dismiss it', async () => { + renderWithRoute(<ResultsView title={Strings.metaData.pageTitle.results} />); + await screen.findByText('a11yr'); + + // Shown by default. + const panel = screen.getByTestId('how-to-read-results'); + expect(panel).toBeInTheDocument(); + + // Dismiss via the panel's close button. + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + await user.click(screen.getByRole('button', { name: /close/i })); + expect(screen.queryByTestId('how-to-read-results')).not.toBeInTheDocument(); + + // The "How to read the results" checkbox brings it back. + await user.click( + screen.getByRole('checkbox', { name: /How to read the results/i }), + ); + expect(screen.getByTestId('how-to-read-results')).toBeInTheDocument(); + }); }); diff --git a/src/__tests__/CompareResults/RevisionRow.test.tsx b/src/__tests__/CompareResults/RevisionRow.test.tsx index ae86e4950..6f542eab5 100644 --- a/src/__tests__/CompareResults/RevisionRow.test.tsx +++ b/src/__tests__/CompareResults/RevisionRow.test.tsx @@ -11,7 +11,11 @@ import { useSubtestRegressionCount } from '../../hooks/useSubtestRegressionCount import { CompareResultsItem, MannWhitneyResultsItem } from '../../types/state'; import { Platform } from '../../types/types'; import getTestData from '../utils/fixtures'; -import { screen, renderWithRouter } from '../utils/test-utils'; +import { + screen, + renderWithRouter, + enableAdvancedColumns, +} from '../utils/test-utils'; jest.mock('../../hooks/useSubtestRegressionCount'); const mockUseSubtestRegressionCount = useSubtestRegressionCount as jest.Mock; @@ -427,6 +431,7 @@ describe('Expanded row', () => { }); it('should display mean for base or new in row headers for mann-whitney-u testVersion', async () => { + enableAdvancedColumns(); const { testCompareMannWhitneyData: rowData } = getTestData(); renderWithRoute( <RevisionRow @@ -541,7 +546,7 @@ describe('Expanded row', () => { }; } - it('shows dash when neither distribution is normal', async () => { + it('shows value with warning icon when neither distribution is normal', async () => { const result = makeResult(tooFewRuns, tooFewRuns); expect(isDistributionNormal(result)).toBe(false); renderWithRoute( @@ -555,7 +560,10 @@ describe('Expanded row', () => { />, ); const roles = await screen.findAllByRole('cell'); - expect(roles[4]).toHaveTextContent('-'); + // The median difference is rank-based, so it's shown even for non-normal + // data; only a warning icon flags the shape. + expect(roles[4]).toHaveTextContent('%'); + expect(roles[4].querySelector('svg[role="img"]')).toBeTruthy(); }); it('shows value with warning icon when only one distribution is normal', async () => { @@ -572,7 +580,7 @@ describe('Expanded row', () => { />, ); const roles = await screen.findAllByRole('cell'); - expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4]).toHaveTextContent('%'); expect(roles[4].querySelector('svg[role="img"]')).toBeTruthy(); }); @@ -590,7 +598,7 @@ describe('Expanded row', () => { />, ); const roles = await screen.findAllByRole('cell'); - expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4]).toHaveTextContent('%'); expect(roles[4].querySelector('svg[role="img"]')).toBeFalsy(); }); }); diff --git a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx index bff3fb298..07711829e 100644 --- a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx +++ b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx @@ -10,7 +10,11 @@ import type { CombinedResultsItemType } from '../../types/state'; import { TestVersion } from '../../types/types'; import { getLocationOrigin } from '../../utils/location'; import getTestData from '../utils/fixtures'; -import { renderWithRouter, screen } from '../utils/test-utils'; +import { + renderWithRouter, + screen, + enableAdvancedColumns, +} from '../utils/test-utils'; jest.mock('../../utils/location'); const mockedGetLocationOrigin = getLocationOrigin as jest.Mock; @@ -48,7 +52,7 @@ const setup = ({ // This handy function parses the results page and returns an array of visible // rows. It makes it easy to assert visible rows when filtering them in a // user-friendly way without using snapshots. -function summarizeVisibleRows(testVersion?: TestVersion) { +function summarizeVisibleRows(testVersion?: TestVersion, advanced = false) { const rows = screen.getAllByRole('row'); const result = []; for (const row of rows) { @@ -59,10 +63,19 @@ function summarizeVisibleRows(testVersion?: TestVersion) { } const rowClasses = testVersion === 'mann-whitney-u' - ? ['.median-diff', '.delta', '.significance', '.effects'] + ? advanced + ? ['.median-diff', '.delta', '.significance', '.effects'] + : ['.median-diff', '.status-hint', '.magnitude', '.significance'] : ['.delta', '.confidence']; const rowString = rowClasses - .map((selector) => row.querySelector(selector)?.textContent.trim()) + .map((selector) => { + const cell = row.querySelector(selector); + if (!cell) return undefined; + // Strip icon <title> text (e.g. the median-diff normality warning). + const clone = cell.cloneNode(true) as HTMLElement; + clone.querySelectorAll('svg').forEach((svg) => svg.remove()); + return clone.textContent?.trim(); + }) .join(', '); result.push(`${subtest}: ${rowString}`); } @@ -497,6 +510,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( }); describe('table sorting', () => { + // These sort by CD and Significance, which are advanced-only columns. + beforeEach(() => { + enableAdvancedColumns(); + }); + async function setupForSorting({ extraParameters, }: Partial<{ @@ -524,12 +542,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( it('can sort the table and persist the information to the URL of mann-whitney-u values', async () => { await setupForSorting(); // Initial view (alphabetical ordered, even if "sort by subtests" isn't specified - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', ]); // Sort by Delta @@ -539,12 +557,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( expect(window.location.search).not.toContain('sort='); // Sort descending await user.click(deltaButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. @@ -554,12 +572,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort ascending await user.click(deltaButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -571,12 +589,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( name: /Sig.*sort/, }); await user.click(significanceButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', ]); // It should have the "no sort" SVG. expect(deltaButton).toMatchSnapshot(); @@ -587,26 +605,26 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Significance ascending await user.click(significanceButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', ]); expectParameterToHaveValue('sort', 'significance|asc'); // Sort by Effect Size descending const effectButton = screen.getByRole('button', { - name: /CLES \(%\).*sort/, + name: /CLES.*sort/, }); await user.click(effectButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', ]); // It should have the "descending" SVG. @@ -616,12 +634,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Effect Size ascending await user.click(effectButton); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', ]); expectParameterToHaveValue('sort', 'effects|asc'); }); @@ -629,12 +647,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( it('initializes the sort from the URL at load time for an ascending sort', async () => { await setupForSorting({ extraParameters: 'sort=delta|asc' }); await screen.findByText('dhtml.html'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'regression.html: 1.135 %, 0.12, , 25.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'regression.html: +1.14%, 0.12, Real, 25.00%', ]); // It should have the "ascending" SVG. expect(screen.getByRole('button', { name: /CD/ })).toMatchSnapshot(); @@ -643,12 +661,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( it('initializes the sort from the URL at load time for an implicit descending sort', async () => { await setupForSorting({ extraParameters: 'sort=delta' }); await screen.findByText('dhtml.html'); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. expect(screen.getByRole('button', { name: /CD/ })).toMatchSnapshot(); @@ -656,12 +674,12 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( it('initializes the sort from the URL at load time for a descending sort', async () => { await setupForSorting({ extraParameters: 'sort=delta|desc' }); - expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 1.135 %, 0.12, , 25.00%', - 'improvement.html: 0.963 %, -0.05, , 50.00%', - 'browser.html: 0.963 %, -0.04, -, 15.00%', - 'dhtml.html: 1.135 %, 0.02, , 60.00%', - 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + expect(summarizeVisibleRows('mann-whitney-u', true)).toEqual([ + 'regression.html: +1.14%, 0.12, Real, 25.00%', + 'improvement.html: +1.14%, -0.05, Real, 50.00%', + 'browser.html: +1.14%, -0.04, Noise, 15.00%', + 'dhtml.html: +1.14%, 0.02, Real, 60.00%', + 'tablemutation.html: +0.98%, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. expect(screen.getByRole('button', { name: /CD/ })).toMatchSnapshot(); diff --git a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx index d8941e030..1b328e56a 100644 --- a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx +++ b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx @@ -7,7 +7,11 @@ import { loader } from '../../components/CompareResults/loader'; import SubtestsRevisionRow from '../../components/CompareResults/SubtestsResults/SubtestsRevisionRow'; import { MannWhitneyResultsItem } from '../../types/state'; import getTestData from '../utils/fixtures'; -import { screen, renderWithRouter } from '../utils/test-utils'; +import { + screen, + renderWithRouter, + enableAdvancedColumns, +} from '../utils/test-utils'; function renderWithRoute(component: ReactElement) { fetchMock @@ -178,6 +182,7 @@ describe('SubtestsRevisionRow Component', () => { }); it('should display cliffs delta, significance, and effects size in subtests for mann-whitney-u testVersion', async () => { + enableAdvancedColumns(); const { subtestsMannWhitneyResult } = getTestData(); const mockGridTemplateColumns = '1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr'; renderWithRoute( @@ -194,7 +199,7 @@ describe('SubtestsRevisionRow Component', () => { expect(effects).toHaveTextContent('60.00%'); const significanceCell = roles[8]; - expect(significanceCell?.querySelector('svg')).not.toBeNull(); + expect(significanceCell).toHaveTextContent('Real'); const cliffs_delta = roles[6]?.childNodes[1]; expect(cliffs_delta).toHaveTextContent('0.02'); @@ -213,7 +218,7 @@ describe('SubtestsRevisionRow Component', () => { ); const roles = await screen.findAllByRole('cell'); - const status = roles[5]?.childNodes[0]; + const status = roles[5]?.querySelector('.status-hint'); expect(status).toHaveTextContent('Regression'); expect(status).toHaveClass('status-hint-regression'); }); @@ -231,7 +236,7 @@ describe('SubtestsRevisionRow Component', () => { ); const roles1 = await screen.findAllByRole('cell'); - const status1 = roles1[5]?.childNodes[0]; + const status1 = roles1[5]?.querySelector('.status-hint'); expect(status1).toHaveTextContent('Improvement'); expect(status1).toHaveClass('status-hint-improvement'); }); @@ -253,7 +258,7 @@ describe('SubtestsRevisionRow Component', () => { }; } - it('shows dash when neither distribution is normal', async () => { + it('shows value with warning icon when neither distribution is normal', async () => { renderWithRoute( <SubtestsRevisionRow result={makeResult(tooFewRuns, tooFewRuns)} @@ -263,7 +268,10 @@ describe('SubtestsRevisionRow Component', () => { />, ); const roles = await screen.findAllByRole('cell'); - expect(roles[4]).toHaveTextContent('-'); + // The median difference is rank-based, so it's shown even for non-normal + // data; only a warning icon flags the shape. + expect(roles[4]).toHaveTextContent('%'); + expect(roles[4].querySelector('svg[role="img"]')).toBeTruthy(); }); it('shows value with warning icon when only one distribution is normal', async () => { @@ -276,7 +284,7 @@ describe('SubtestsRevisionRow Component', () => { />, ); const roles = await screen.findAllByRole('cell'); - expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4]).toHaveTextContent('%'); expect(roles[4].querySelector('svg[role="img"]')).toBeTruthy(); }); @@ -290,7 +298,7 @@ describe('SubtestsRevisionRow Component', () => { />, ); const roles = await screen.findAllByRole('cell'); - expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4]).toHaveTextContent('%'); expect(roles[4].querySelector('svg[role="img"]')).toBeFalsy(); }); }); diff --git a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap index dbd059e14..0d13e4064 100644 --- a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap @@ -10,343 +10,443 @@ exports[`Results View The table should match snapshot and other elements should class="MuiBox-root css-1rw0zd7" > <div - class="MuiGrid-root MuiGrid-container MuiGrid-direction-xs-row MuiGrid-spacing-xs-2 f1wpas00 css-13620ud-MuiGrid-root" + class="MuiGrid-root MuiGrid-container MuiGrid-direction-xs-row MuiGrid-spacing-xs-2 f1wpas00 results-controls css-13620ud-MuiGrid-root" > <div - class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-md-3 MuiGrid-grid-xs-12 css-11ufmbb-MuiGrid-root" + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-12 css-16nz7cf-MuiGrid-root" > - <form - aria-label="Search by title, platform, revision or options" - class="MuiBox-root css-1wxqtyp" + <div + class="results-controls-selections MuiBox-root css-1rh9huw" > - <div - class="MuiFormControl-root MuiTextField-root css-q16m8p-MuiFormControl-root-MuiTextField-root" + <label + aria-label="Show the "How to read the results" guide above the table" + class="MuiFormControlLabel-root MuiFormControlLabel-labelPlacementEnd css-1bsjtco-MuiFormControlLabel-root" data-mui-internal-clone-element="true" + > + <span + class="MuiButtonBase-root MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall PrivateSwitchBase-root MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall Mui-checked MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall css-1nff2up-MuiButtonBase-root-MuiSwitchBase-root-MuiCheckbox-root" + > + <input + checked="" + class="PrivateSwitchBase-input css-12xagqm-MuiSwitchBase-root" + data-indeterminate="false" + type="checkbox" + /> + <svg + aria-hidden="true" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-54rgmy-MuiSvgIcon-root" + data-testid="CheckBoxIcon" + focusable="false" + viewBox="0 0 24 24" + > + <path + d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" + /> + </svg> + </span> + <span + class="MuiTypography-root MuiTypography-body1 MuiFormControlLabel-label css-n290n7-MuiTypography-root" + > + How to read the results + </span> + </label> + <label + class="MuiFormControlLabel-root MuiFormControlLabel-labelPlacementEnd css-1bsjtco-MuiFormControlLabel-root" + > + <span + class="MuiButtonBase-root MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall PrivateSwitchBase-root MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall css-1nff2up-MuiButtonBase-root-MuiSwitchBase-root-MuiCheckbox-root" + > + <input + class="PrivateSwitchBase-input css-12xagqm-MuiSwitchBase-root" + data-indeterminate="false" + type="checkbox" + /> + <svg + aria-hidden="true" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-54rgmy-MuiSvgIcon-root" + data-testid="CheckBoxOutlineBlankIcon" + focusable="false" + viewBox="0 0 24 24" + > + <path + d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" + /> + </svg> + </span> + <span + class="MuiTypography-root MuiTypography-body1 MuiFormControlLabel-label css-n290n7-MuiTypography-root" + > + Expand all rows + </span> + </label> + </div> + </div> + <div + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-12 css-16nz7cf-MuiGrid-root" + > + <div + class="MuiGrid-root MuiGrid-container MuiGrid-direction-xs-row MuiGrid-spacing-xs-2 results-controls-inputs css-13620ud-MuiGrid-root" + > + <div + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-md-3 MuiGrid-grid-xs-12 css-11ufmbb-MuiGrid-root" + > + <form + aria-label="Search by title, platform, revision or options" + class="MuiBox-root css-1wxqtyp" + > + <div + class="MuiFormControl-root MuiTextField-root css-q16m8p-MuiFormControl-root-MuiTextField-root" + data-mui-internal-clone-element="true" + > + <div + class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall MuiInputBase-adornedStart MuiInputBase-adornedEnd css-1cqjfkd-MuiInputBase-root-MuiOutlinedInput-root" + > + <div + class="MuiInputAdornment-root MuiInputAdornment-positionStart MuiInputAdornment-outlined MuiInputAdornment-sizeSmall css-1nowbqt-MuiInputAdornment-root" + > + <span + aria-hidden="true" + class="notranslate" + > + ​ + </span> + <svg + aria-hidden="true" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" + data-testid="SearchIcon" + focusable="false" + viewBox="0 0 24 24" + > + <path + d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14" + /> + </svg> + </div> + <input + aria-description="Tip: You can search with multiple words (all must match). Use -word to exclude results containing that word." + aria-invalid="false" + aria-label="Search by title, platform, revision or options" + class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall MuiInputBase-inputAdornedStart MuiInputBase-inputAdornedEnd css-3v3un6-MuiInputBase-input-MuiOutlinedInput-input" + id="_r_c_" + placeholder="Filter results" + type="search" + value="" + /> + <div + class="MuiInputAdornment-root MuiInputAdornment-positionEnd MuiInputAdornment-outlined MuiInputAdornment-sizeSmall css-elo8k2-MuiInputAdornment-root" + > + <button + aria-label="Clear the search input" + class="MuiButtonBase-root MuiIconButton-root MuiIconButton-edgeEnd MuiIconButton-sizeSmall css-13mnts1-MuiButtonBase-root-MuiIconButton-root" + tabindex="0" + type="button" + > + <svg + aria-hidden="true" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" + data-testid="CloseIcon" + focusable="false" + viewBox="0 0 24 24" + > + <path + d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" + /> + </svg> + </button> + </div> + <fieldset + aria-hidden="true" + class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" + > + <legend + class="css-1nf2c5d-MuiNotchedOutlined-root" + > + <span + aria-hidden="true" + class="notranslate" + > + ​ + </span> + </legend> + </fieldset> + </div> + </div> + </form> + </div> + <div + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-md-2 MuiGrid-grid-xs-6 css-4yvdwt-MuiGrid-root" > <div - class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall MuiInputBase-adornedStart MuiInputBase-adornedEnd css-1cqjfkd-MuiInputBase-root-MuiOutlinedInput-root" + class="MuiFormControl-root css-7549ua-MuiFormControl-root" > <div - class="MuiInputAdornment-root MuiInputAdornment-positionStart MuiInputAdornment-outlined MuiInputAdornment-sizeSmall css-1nowbqt-MuiInputAdornment-root" + class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall framework-dropdown-select MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" + data-testid="framework-select" > - <span - aria-hidden="true" - class="notranslate" + <div + aria-expanded="false" + aria-haspopup="listbox" + aria-label="Framework" + aria-labelledby="mui-component-select-framework" + class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + id="mui-component-select-framework" + role="combobox" + tabindex="0" > - ​ - </span> + talos + </div> + <input + aria-hidden="true" + aria-invalid="false" + class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" + name="framework" + tabindex="-1" + value="1" + /> <svg aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" - data-testid="SearchIcon" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" + data-testid="ArrowDropDownIcon" focusable="false" viewBox="0 0 24 24" > <path - d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14" + d="M7 10l5 5 5-5z" /> </svg> - </div> - <input - aria-description="Tip: You can search with multiple words (all must match). Use -word to exclude results containing that word." - aria-invalid="false" - aria-label="Search by title, platform, revision or options" - class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall MuiInputBase-inputAdornedStart MuiInputBase-inputAdornedEnd css-3v3un6-MuiInputBase-input-MuiOutlinedInput-input" - id="_r_a_" - placeholder="Filter results" - type="search" - value="" - /> - <div - class="MuiInputAdornment-root MuiInputAdornment-positionEnd MuiInputAdornment-outlined MuiInputAdornment-sizeSmall css-elo8k2-MuiInputAdornment-root" - > - <button - aria-label="Clear the search input" - class="MuiButtonBase-root MuiIconButton-root MuiIconButton-edgeEnd MuiIconButton-sizeSmall css-13mnts1-MuiButtonBase-root-MuiIconButton-root" - tabindex="0" - type="button" + <fieldset + aria-hidden="true" + class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" > - <svg - aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" - data-testid="CloseIcon" - focusable="false" - viewBox="0 0 24 24" + <legend + class="css-1nf2c5d-MuiNotchedOutlined-root" > - <path - d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" - /> - </svg> - </button> + <span + aria-hidden="true" + class="notranslate" + > + ​ + </span> + </legend> + </fieldset> </div> - <fieldset - aria-hidden="true" - class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" - > - <legend - class="css-1nf2c5d-MuiNotchedOutlined-root" - > - <span - aria-hidden="true" - class="notranslate" - > - ​ - </span> - </legend> - </fieldset> </div> </div> - </form> - </div> - <div - class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-md-2 MuiGrid-grid-xs-6 css-4yvdwt-MuiGrid-root" - > - <div - class="MuiFormControl-root css-7549ua-MuiFormControl-root" - > <div - class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall framework-dropdown-select MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" - data-testid="framework-select" + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-md-2 MuiGrid-grid-xs-6 css-4yvdwt-MuiGrid-root" > <div - aria-expanded="false" - aria-haspopup="listbox" - aria-label="Framework" - aria-labelledby="mui-component-select-framework" - class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" - id="mui-component-select-framework" - role="combobox" - tabindex="0" - > - talos - </div> - <input - aria-hidden="true" - aria-invalid="false" - class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" - name="framework" - tabindex="-1" - value="1" - /> - <svg - aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" - data-testid="ArrowDropDownIcon" - focusable="false" - viewBox="0 0 24 24" - > - <path - d="M7 10l5 5 5-5z" - /> - </svg> - <fieldset - aria-hidden="true" - class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" + class="MuiFormControl-root css-7549ua-MuiFormControl-root" > - <legend - class="css-1nf2c5d-MuiNotchedOutlined-root" + <div + class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall test-version-select MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" + data-testid="test-version-select" > - <span + <div + aria-expanded="false" + aria-haspopup="listbox" + aria-label="Stats Test Version" + aria-labelledby="test-version-type mui-component-select-test_version" + class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + id="mui-component-select-test_version" + role="combobox" + tabindex="0" + > + Mann-Whitney-U + </div> + <input + aria-hidden="true" + aria-invalid="false" + class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" + name="test_version" + tabindex="-1" + value="mann-whitney-u" + /> + <svg aria-hidden="true" - class="notranslate" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" + data-testid="ArrowDropDownIcon" + focusable="false" + viewBox="0 0 24 24" > - ​ - </span> - </legend> - </fieldset> + <path + d="M7 10l5 5 5-5z" + /> + </svg> + <fieldset + aria-hidden="true" + class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" + > + <legend + class="css-1nf2c5d-MuiNotchedOutlined-root" + > + <span + aria-hidden="true" + class="notranslate" + > + ​ + </span> + </legend> + </fieldset> + </div> + </div> </div> - </div> - </div> - <div - class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-md-2 MuiGrid-grid-xs-6 css-4yvdwt-MuiGrid-root" - > - <div - class="MuiFormControl-root css-7549ua-MuiFormControl-root" - > <div - class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall test-version-select MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" - data-testid="test-version-select" + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-grow css-vvfr7q-MuiGrid-root" > <div - aria-expanded="false" - aria-haspopup="listbox" - aria-label="Stats Test Version" - aria-labelledby="test-version-type mui-component-select-test_version" - class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" - id="mui-component-select-test_version" - role="combobox" - tabindex="0" + class="MuiBox-root css-0" + data-testid="revision-select" > - Mann-Whitney-U - </div> - <input - aria-hidden="true" - aria-invalid="false" - class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" - name="test_version" - tabindex="-1" - value="mann-whitney-u" - /> - <svg - aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" - data-testid="ArrowDropDownIcon" - focusable="false" - viewBox="0 0 24 24" - > - <path - d="M7 10l5 5 5-5z" - /> - </svg> - <fieldset - aria-hidden="true" - class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" - > - <legend - class="css-1nf2c5d-MuiNotchedOutlined-root" + <div + class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-sizeSmall f96or0t MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" > - <span + <div + aria-expanded="false" + aria-haspopup="listbox" + aria-label="Filter by revision" + class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + role="combobox" + tabindex="0" + > + <div + class="fbc330 MuiBox-root css-0" + > + <svg + aria-hidden="true" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" + focusable="false" + viewBox="0 0 24 24" + > + <svg + aria-hidden="true" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" + data-testid="SortIcon" + focusable="false" + viewBox="0 0 24 24" + > + <path + d="M3 18h6v-2H3zM3 6v2h18V6zm0 7h12v-2H3z" + /> + </svg> + </svg> + All revisions + </div> + </div> + <input + aria-hidden="true" + aria-invalid="false" + class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" + tabindex="-1" + value="all-revisions" + /> + <svg aria-hidden="true" - class="notranslate" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" + data-testid="ArrowDropDownIcon" + focusable="false" + viewBox="0 0 24 24" > - ​ - </span> - </legend> - </fieldset> + <path + d="M7 10l5 5 5-5z" + /> + </svg> + <fieldset + aria-hidden="true" + class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" + > + <legend + class="css-1nf2c5d-MuiNotchedOutlined-root" + > + <span + aria-hidden="true" + class="notranslate" + > + ​ + </span> + </legend> + </fieldset> + </div> + </div> </div> - </div> - </div> - <div - class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-grow css-t3of1j-MuiGrid-root" - > - <div - class="MuiBox-root css-0" - data-testid="revision-select" - > <div - class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-sizeSmall f96or0t MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-auto css-zh2j38-MuiGrid-root" > <div - aria-expanded="false" - aria-haspopup="listbox" - aria-label="Filter by revision" - class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" - role="combobox" - tabindex="0" + aria-label="Show the advanced statistics columns (Cliff's Delta, CLES, Significance)" + class="MuiFormControl-root css-7549ua-MuiFormControl-root" + data-mui-internal-clone-element="true" > <div - class="fbc330 MuiBox-root css-0" + class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall advanced-columns-select MuiSelect-root css-fcr66i-MuiInputBase-root-MuiOutlinedInput-root-MuiSelect-root" + data-testid="advanced-columns-select" > + <div + aria-expanded="false" + aria-haspopup="listbox" + aria-label="Advanced columns" + class="MuiSelect-select MuiSelect-outlined MuiSelect-multiple MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + role="combobox" + tabindex="0" + > + Advanced columns + </div> + <input + aria-hidden="true" + aria-invalid="false" + class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" + tabindex="-1" + value="" + /> <svg aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" + class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" + data-testid="ArrowDropDownIcon" focusable="false" viewBox="0 0 24 24" > - <svg - aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-120he73-MuiSvgIcon-root" - data-testid="SortIcon" - focusable="false" - viewBox="0 0 24 24" - > - <path - d="M3 18h6v-2H3zM3 6v2h18V6zm0 7h12v-2H3z" - /> - </svg> + <path + d="M7 10l5 5 5-5z" + /> </svg> - All revisions + <fieldset + aria-hidden="true" + class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" + > + <legend + class="css-1nf2c5d-MuiNotchedOutlined-root" + > + <span + aria-hidden="true" + class="notranslate" + > + ​ + </span> + </legend> + </fieldset> </div> </div> - <input - aria-hidden="true" - aria-invalid="false" - class="MuiSelect-nativeInput css-j0riat-MuiSelect-nativeInput" - tabindex="-1" - value="all-revisions" - /> - <svg - aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiSelect-icon MuiSelect-iconOutlined css-h42w4p-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon" - data-testid="ArrowDropDownIcon" - focusable="false" - viewBox="0 0 24 24" - > - <path - d="M7 10l5 5 5-5z" - /> - </svg> - <fieldset - aria-hidden="true" - class="MuiOutlinedInput-notchedOutline css-18p5xg2-MuiNotchedOutlined-root-MuiOutlinedInput-notchedOutline" + </div> + <div + class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-grow css-wautn6-MuiGrid-root" + > + <div + class="f6hg2jo" > - <legend - class="css-1nf2c5d-MuiNotchedOutlined-root" + <button + class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedSecondary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorSecondary MuiButton-disableElevation css-14hwkrj-MuiButtonBase-root-MuiButton-root" + tabindex="0" + type="button" > - <span - aria-hidden="true" - class="notranslate" - > - ​ - </span> - </legend> - </fieldset> + Download JSON + </button> + </div> </div> </div> </div> - <div - class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-grow css-t3of1j-MuiGrid-root" - > - <div - class="f6hg2jo" - > - <button - class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedSecondary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorSecondary MuiButton-disableElevation css-14hwkrj-MuiButtonBase-root-MuiButton-root" - tabindex="0" - type="button" - > - Download JSON - </button> - </div> - </div> - <div - class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-auto css-zh2j38-MuiGrid-root" - > - <label - aria-label="Expand all rows" - class="MuiFormControlLabel-root MuiFormControlLabel-labelPlacementEnd css-1bsjtco-MuiFormControlLabel-root" - data-mui-internal-clone-element="true" - > - <span - class="MuiButtonBase-root MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall PrivateSwitchBase-root MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall MuiCheckbox-root MuiCheckbox-colorPrimary MuiCheckbox-sizeSmall css-1nff2up-MuiButtonBase-root-MuiSwitchBase-root-MuiCheckbox-root" - > - <input - class="PrivateSwitchBase-input css-12xagqm-MuiSwitchBase-root" - data-indeterminate="false" - type="checkbox" - /> - <svg - aria-hidden="true" - class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-54rgmy-MuiSvgIcon-root" - data-testid="CheckBoxOutlineBlankIcon" - focusable="false" - viewBox="0 0 24 24" - > - <path - d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" - /> - </svg> - </span> - <span - class="MuiTypography-root MuiTypography-body1 MuiFormControlLabel-label css-n290n7-MuiTypography-root" - > - Expand all - </span> - </label> - </div> </div> <div - class="fdtnfac f1l733lh" + class="f1ogd8ft f1l733lh table-header" data-testid="table-header" role="row" > @@ -357,7 +457,7 @@ exports[`Results View The table should match snapshot and other elements should <button aria-haspopup="true" aria-label="Platform (Click to filter values)" - class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedTableHeaderButton MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-colorTableHeaderButton MuiButton-disableElevation css-l81dbu-MuiButtonBase-root-MuiButton-root" + class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedTableHeaderButton MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-colorTableHeaderButton MuiButton-disableElevation css-kne8o5-MuiButtonBase-root-MuiButton-root" data-mui-internal-clone-element="true" tabindex="0" type="button" @@ -417,13 +517,13 @@ exports[`Results View The table should match snapshot and other elements should role="columnheader" > <span - aria-label="Median Diff %: The percentage change in median from Base to New: ((New − Base) / Base) × 100." + aria-label="Shows how much the middle result changed from Base to New. We line up all the runs from smallest to biggest and pick the middle one for each side, then show the change as a percent. A positive sign means New is higher; a negative sign means New is lower." class="MuiBox-root css-1tkq7a4" data-mui-internal-clone-element="true" > <button - aria-label="MD (%) (Click to sort by this column)" - class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedTableHeaderButton MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-colorTableHeaderButton MuiButton-disableElevation css-7upxw3-MuiButtonBase-root-MuiButton-root" + aria-label="Δ Median (Click to sort by this column)" + class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedTableHeaderButton MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-colorTableHeaderButton MuiButton-disableElevation css-1w0uvhi-MuiButtonBase-root-MuiButton-root" tabindex="0" type="button" > @@ -438,10 +538,10 @@ exports[`Results View The table should match snapshot and other elements should d="M16 17.01V10h-2v7.01h-3L15 21l4-3.99zM9 3 5 6.99h3V14h2V6.99h3z" /> <title> - Not sorted by MD (%) + Not sorted by Δ Median - MD (%) + Δ Median @@ -452,18 +552,18 @@ exports[`Results View The table should match snapshot and other elements should - - -
- - - -
-
- 0 % + +1.08%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1116,7 +1136,7 @@ exports[`Results View The table should match snapshot and other elements should data-testid="expand-revision-button" >
- 0 % + -2.40%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1315,7 +1327,7 @@ exports[`Results View The table should match snapshot and other elements should data-testid="expand-revision-button" >
- 0 % + -2.40%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1514,7 +1518,7 @@ exports[`Results View The table should match snapshot and other elements should data-testid="expand-revision-button" >
+
-
-
+ + + + + + How to read the results + + + +
+
+
+
+
+ +
+
+
+ + +
+ +
+ +
+ +
+
+ +
+
- + talos +
+ -
- -
- + + +
-
- -
-
-
- - -
+ + + +
+
-
-
-
-
- - -
+ + + +
+
-
-
-
-
- - - + Download JSON + +
-
-
- -
-
-
- -
@@ -1330,7 +1557,7 @@ exports[`Results Table Should match snapshot 1`] = `
@@ -1425,18 +1652,18 @@ exports[`Results Table Should match snapshot 1`] = `
- - - -
-
- - - -
-
- 0 % + +1.08%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -2089,7 +2236,7 @@ exports[`Results Table Should match snapshot 1`] = ` data-testid="expand-revision-button" >
- 0 % + -2.40%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -2288,7 +2427,7 @@ exports[`Results Table Should match snapshot 1`] = ` data-testid="expand-revision-button" >
+
+
+ + +
+
+
-
+ +
+
+
+ + +
+ +
+ +
+ +
+
+ +
+
- + talos +
+ -
- -
- + + +
-
- -
-
-
- - -
+ +
-
-
-
-
-
- - - - +
+
-
-
-
-
- - - + + + +
+
-
-
-
-
- -
-
-
- + +
+
+
@@ -4213,7 +4571,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion
@@ -4308,18 +4666,18 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion @@ -4409,7 +4767,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion > + + + + + + +
- + build_metrics +
+ -
- -
- + + +
-
- - -
-
- - -
+ + + +
+
- - -
-
- - -
+ + + +
+
- - -
-
- - - + Download JSON + +
-
-
- -
-
-
- -
@@ -1472,7 +1570,7 @@ exports[`Results View The table should match snapshot and other elements should
@@ -1567,18 +1665,18 @@ exports[`Results View The table should match snapshot and other elements should - - -
- - - -
-
- 0 % + +1.08%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -2231,7 +2249,7 @@ exports[`Results View The table should match snapshot and other elements should data-testid="expand-revision-button" >
- 0 % + -2.40%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -2430,7 +2440,7 @@ exports[`Results View The table should match snapshot and other elements should data-testid="expand-revision-button" >
- 0 % + -2.40%
-
-
- - -
-
- - + class="MuiBox-root css-izuqqr" + > +
+
- @@ -2629,7 +2631,7 @@ exports[`Results View The table should match snapshot and other elements should data-testid="expand-revision-button" >
+
+
+
+ + + + +
+
+
@@ -850,7 +908,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results >
@@ -939,18 +997,18 @@ exports[`SubtestsResultsView Component Tests should render the subtests results
- - - -
-
- - - -
-
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1252,7 +1237,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="cell" >
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1400,7 +1376,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="cell" >
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1548,7 +1515,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="cell" >
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1696,7 +1654,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="cell" >
- 0 % + +0.98%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -1844,7 +1793,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="cell" >
+
+
+
+ + + + +
+
+
@@ -2761,7 +2768,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi >
@@ -2850,18 +2857,18 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi
- - - -
-
- - - -
-
- 0.963 % + +1.14%
-
-
- - -0.04 -
-
- 15.00% + class="MuiBox-root css-izuqqr" + > +
+ Noise +
+
+
- - + Negligible
- 1.135 % + +1.14%
- - Regression + + Regression +
- - 0.02 -
-
- 60.00% -
-
- + Negligible
- 0.963 % + +1.14%
-
-
- - -0.05 -
-
- 50.00% + class="MuiBox-root css-izuqqr" + > +
+
- + Negligible
- 1.135 % + +1.14%
-
-
- - 0.12 -
-
- 25.00% + class="MuiBox-root css-izuqqr" + > +
+
- + Small
- 0.98 % + +0.98%
- - Improvement + + Improvement +
- - 0.01 -
-
- 45.00% -
-
- - + Negligible
+
+
+
+ + + + +
+
+
@@ -4363,7 +4285,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi >
@@ -4452,18 +4374,18 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi
- - - -
-
- - - -
-
- 0.963 % + +1.14%
-
-
- - -0.04 -
-
- 15.00% + class="MuiBox-root css-izuqqr" + > +
+ Noise +
+
+
- - + Negligible
- 1.135 % + +1.14%
- - Regression + + Regression +
- - 0.02 -
-
- 60.00% -
-
- + Negligible
- 0.963 % + +1.14%
-
-
- - -0.05 -
-
- 50.00% + class="MuiBox-root css-izuqqr" + > +
+
- + Negligible
- 1.135 % + +1.14%
-
-
- - 0.12 + class="MuiBox-root css-izuqqr" + > +
+
- 25.00% -
-
- + Small
- 0.98 % + +0.98%
- - Improvement + + Improvement +
- - 0.01 -
-
- 45.00% -
-
- - + Negligible
+
+
+
+ + + + +
+
+
@@ -5965,7 +5802,7 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when >
@@ -6054,18 +5891,18 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when
- - - -
-
- - - -
-
- 0.963 % + +1.14%
-
-
- - -0.04 -
-
- 15.00% + class="MuiBox-root css-izuqqr" + > +
+ Noise +
+
+
- - + Negligible
- 1.135 % + +1.14%
- - Regression -
-
-
- - 0.02 -
-
- 60.00% + + Regression +
+
- + Negligible
- 0.963 % + +1.14%
-
-
- - -0.05 -
-
- 50.00% + class="MuiBox-root css-izuqqr" + > +
+
- + Negligible
- 1.135 % + +1.14%
-
-
- - 0.12 -
-
- 25.00% + class="MuiBox-root css-izuqqr" + > +
+
- + Small
- 0.98 % + +0.98%
- - Improvement + + Improvement +
- - 0.01 -
-
- 45.00% -
-
- - + Negligible
+
+
+
+ + + + +
+
+
@@ -7567,7 +7319,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests >
@@ -7656,18 +7408,18 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests
- - - -
-
- - - -
-
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -7969,7 +7648,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests role="cell" >
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -8117,7 +7787,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests role="cell" >
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -8265,7 +7926,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests role="cell" >
- 0 % + +1.14%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -8413,7 +8065,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests role="cell" >
- 0 % + +0.98%
-
-
- - - -
-
- 0.00% + class="MuiBox-root css-izuqqr" + > +
+
- @@ -8561,7 +8204,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests role="cell" > +
@@ -1227,7 +1250,7 @@ exports[`Results Table Should match snapshot 1`] = ` aria-invalid="false" aria-label="Search by title, platform, revision or options" class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall MuiInputBase-inputAdornedStart MuiInputBase-inputAdornedEnd css-3v3un6-MuiInputBase-input-MuiOutlinedInput-input" - id="_r_m_" + id="_r_n_" placeholder="Filter results" type="search" value="" @@ -2045,7 +2068,7 @@ exports[`Results Table Should match snapshot 1`] = ` data-testid="expand-revision-button" > +
@@ -4241,7 +4287,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion aria-invalid="false" aria-label="Search by title, platform, revision or options" class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall MuiInputBase-inputAdornedStart MuiInputBase-inputAdornedEnd css-3v3un6-MuiInputBase-input-MuiOutlinedInput-input" - id="_r_rj_" + id="_r_rm_" placeholder="Filter results" type="search" value="" @@ -5153,7 +5199,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion data-testid="expand-revision-button" >
+
+
+
+
+
+
+
+
+
+
@@ -78,7 +181,7 @@ exports[`Results View Should display Base, New and Common graphs with tooltips 1
- This graph shows how the Base and New results are distributed. Two curves that mostly overlap mean the builds performed about the same; curves that sit apart suggest a real difference — the further apart, the bigger the change. +

+ Runs Density Distribution +

+
-

- Runs Density Distribution -

+ + Valley depth threshold + + : + + + + + + + + + + 50 + % + + +
@@ -401,7 +607,7 @@ exports[`Results View The table should match snapshot and other elements should aria-haspopup="listbox" aria-label="Framework" aria-labelledby="mui-component-select-framework" - class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1rcoerw-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" id="mui-component-select-framework" role="combobox" tabindex="0" @@ -460,7 +666,7 @@ exports[`Results View The table should match snapshot and other elements should aria-haspopup="listbox" aria-label="Stats Test Version" aria-labelledby="test-version-type mui-component-select-test_version" - class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1rcoerw-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" id="mui-component-select-test_version" role="combobox" tabindex="0" @@ -518,7 +724,7 @@ exports[`Results View The table should match snapshot and other elements should aria-expanded="false" aria-haspopup="listbox" aria-label="Filter by revision" - class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1hw1663-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" + class="MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputSizeSmall css-1rcoerw-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiOutlinedInput-input" role="combobox" tabindex="0" > @@ -586,9 +792,7 @@ exports[`Results View The table should match snapshot and other elements should class="MuiGrid-root MuiGrid-direction-xs-row MuiGrid-grid-xs-auto css-zh2j38-MuiGrid-root" >