From 30bfdfc1ab394462e27c7846e050c6a1bdef7be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Dobrzy=C5=84ski?= Date: Fri, 7 Mar 2025 19:02:04 +0100 Subject: [PATCH 01/10] [105] create URL params for time, names, motion, and clock images --- package-lock.json | 184 ++++++++++++++------------ package.json | 10 +- src/app/oxford-debate/page.tsx | 4 +- src/app/oxford-debate/setup/page.tsx | 43 +++++- src/components/DebatecoreFooter.tsx | 2 +- src/lib/imageToBase64.ts | 9 +- tests/assets/black_mesa_lambda.png | Bin 0 -> 2919 bytes tests/e2e/url-params-parsing.test.ts | 187 +++++++++++++++++++++++++++ 8 files changed, 349 insertions(+), 90 deletions(-) create mode 100644 tests/assets/black_mesa_lambda.png create mode 100644 tests/e2e/url-params-parsing.test.ts diff --git a/package-lock.json b/package-lock.json index 3bd37fa..62b1669 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@jest/globals": "^29.7.0", "@types/jest": "^29.5.12", "flag-icons": "^7.2.2", + "fs": "^0.0.1-security", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jsdom": "24.1.0", @@ -23,7 +24,7 @@ "use-sound": "^4.0.1" }, "devDependencies": { - "@playwright/test": "^1.45.1", + "@playwright/test": "^1.51.0", "@testing-library/dom": "^10.1.0", "@testing-library/react": "^16.0.0", "@types/node": "^20", @@ -1327,9 +1328,9 @@ } }, "node_modules/@next/env": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.4.tgz", - "integrity": "sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.24.tgz", + "integrity": "sha512-LAm0Is2KHTNT6IT16lxT+suD0u+VVfYNQqM+EJTKuFRRuY2z+zj01kueWXPCxbMBDt0B5vONYzabHGUNbZYAhA==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -1342,12 +1343,13 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.4.tgz", - "integrity": "sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.24.tgz", + "integrity": "sha512-7Tdi13aojnAZGpapVU6meVSpNzgrFwZ8joDcNS8cJVNuP3zqqrLqeory9Xec5TJZR/stsGJdfwo8KeyloT3+rQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1357,12 +1359,13 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.4.tgz", - "integrity": "sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.24.tgz", + "integrity": "sha512-lXR2WQqUtu69l5JMdTwSvQUkdqAhEWOqJEYUQ21QczQsAlNOW2kWZCucA6b3EXmPbcvmHB1kSZDua/713d52xg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1372,12 +1375,13 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.4.tgz", - "integrity": "sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.24.tgz", + "integrity": "sha512-nxvJgWOpSNmzidYvvGDfXwxkijb6hL9+cjZx1PVG6urr2h2jUqBALkKjT7kpfurRWicK6hFOvarmaWsINT1hnA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1387,12 +1391,13 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.4.tgz", - "integrity": "sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.24.tgz", + "integrity": "sha512-PaBgOPhqa4Abxa3y/P92F3kklNPsiFjcjldQGT7kFmiY5nuFn8ClBEoX8GIpqU1ODP2y8P6hio6vTomx2Vy0UQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1402,9 +1407,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.4.tgz", - "integrity": "sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.24.tgz", + "integrity": "sha512-vEbyadiRI7GOr94hd2AB15LFVgcJZQWu7Cdi9cWjCMeCiUsHWA0U5BkGPuoYRnTxTn0HacuMb9NeAmStfBCLoQ==", "cpu": [ "x64" ], @@ -1418,12 +1423,13 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.4.tgz", - "integrity": "sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.24.tgz", + "integrity": "sha512-df0FC9ptaYsd8nQCINCzFtDWtko8PNRTAU0/+d7hy47E0oC17tI54U/0NdGk7l/76jz1J377dvRjmt6IUdkpzQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1433,12 +1439,13 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.4.tgz", - "integrity": "sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.24.tgz", + "integrity": "sha512-ZEntbLjeYAJ286eAqbxpZHhDFYpYjArotQ+/TW9j7UROh0DUmX7wYDGtsTPpfCV8V+UoqHBPU7q9D4nDNH014Q==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1448,12 +1455,13 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.4.tgz", - "integrity": "sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.24.tgz", + "integrity": "sha512-9KuS+XUXM3T6v7leeWU0erpJ6NsFIwiTFD5nzNg8J5uo/DMIPvCp3L1Ao5HjbHX0gkWPB1VrKoo/Il4F0cGK2Q==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1463,12 +1471,13 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.4.tgz", - "integrity": "sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.24.tgz", + "integrity": "sha512-cXcJ2+x0fXQ2CntaE00d7uUH+u1Bfp/E0HsNQH79YiLaZE5Rbm7dZzyAYccn3uICM7mw+DxoMqEfGXZtF4Fgaw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1523,13 +1532,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz", - "integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.0.tgz", + "integrity": "sha512-dJ0dMbZeHhI+wb77+ljx/FeC8VBP6j/rj9OAojO08JI80wTZy6vRk9KvHKiDCUh4iMpEiseMgqRBIeW+eKX6RA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.45.1" + "playwright": "1.51.0" }, "bin": { "playwright": "cli.js" @@ -2912,9 +2921,10 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3933,9 +3943,10 @@ "dev": true }, "node_modules/fast-loops": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.3.tgz", - "integrity": "sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.4.tgz", + "integrity": "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==", + "license": "MIT" }, "node_modules/fast-shallow-equal": { "version": "1.0.0", @@ -4082,11 +4093,31 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==", + "license": "ISC" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6482,11 +6513,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6588,15 +6620,16 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -6610,12 +6643,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/next": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.4.tgz", - "integrity": "sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ==", + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.24.tgz", + "integrity": "sha512-En8VEexSJ0Py2FfVnRRh8gtERwDRaJGNvsvad47ShkC2Yi8AXQPXEA2vKoDJlGFSj5WE5SyF21zNi4M5gyi+SQ==", "license": "MIT", "dependencies": { - "@next/env": "14.2.4", + "@next/env": "14.2.24", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -6630,15 +6663,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.4", - "@next/swc-darwin-x64": "14.2.4", - "@next/swc-linux-arm64-gnu": "14.2.4", - "@next/swc-linux-arm64-musl": "14.2.4", - "@next/swc-linux-x64-gnu": "14.2.4", - "@next/swc-linux-x64-musl": "14.2.4", - "@next/swc-win32-arm64-msvc": "14.2.4", - "@next/swc-win32-ia32-msvc": "14.2.4", - "@next/swc-win32-x64-msvc": "14.2.4" + "@next/swc-darwin-arm64": "14.2.24", + "@next/swc-darwin-x64": "14.2.24", + "@next/swc-linux-arm64-gnu": "14.2.24", + "@next/swc-linux-arm64-musl": "14.2.24", + "@next/swc-linux-x64-gnu": "14.2.24", + "@next/swc-linux-x64-musl": "14.2.24", + "@next/swc-win32-arm64-msvc": "14.2.24", + "@next/swc-win32-ia32-msvc": "14.2.24", + "@next/swc-win32-x64-msvc": "14.2.24" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -7131,13 +7164,13 @@ } }, "node_modules/playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.0.tgz", + "integrity": "sha512-442pTfGM0xxfCYxuBa/Pu6B2OqxqqaYq39JS8QDMGThUvIOCd6s0ANDog3uwA0cHavVlnTQzGCN7Id2YekDSXA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.1" + "playwright-core": "1.51.0" }, "bin": { "playwright": "cli.js" @@ -7150,9 +7183,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.0.tgz", + "integrity": "sha512-x47yPE3Zwhlil7wlNU/iktF7t2r/URR3VLbH6EknJd/04Qc/PSJ0EY3CMXipmglLG+zyRxW6HNo2EGbKLHPWMg==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -7162,21 +7195,6 @@ "node": ">=18" } }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/postcss": { "version": "8.4.33", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", diff --git a/package.json b/package.json index a2f8ea2..fc4ba41 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,10 @@ "@jest/globals": "^29.7.0", "@types/jest": "^29.5.12", "flag-icons": "^7.2.2", + "fs": "^0.0.1-security", "jest": "^29.7.0", - "jsdom": "24.1.0", "jest-environment-jsdom": "^29.7.0", + "jsdom": "24.1.0", "next": "^14.1.0", "react": "^18", "react-dom": "^18", @@ -25,9 +26,9 @@ "use-sound": "^4.0.1" }, "devDependencies": { + "@playwright/test": "^1.51.0", "@testing-library/dom": "^10.1.0", "@testing-library/react": "^16.0.0", - "@playwright/test": "^1.45.1", "@types/node": "^20", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", @@ -37,5 +38,10 @@ "postcss": "^8", "tailwindcss": "^3.3.0", "typescript": "^5" + }, + "browser": { + "fs": false, + "path": false, + "os": false } } diff --git a/src/app/oxford-debate/page.tsx b/src/app/oxford-debate/page.tsx index 5e7ffe5..a09949f 100644 --- a/src/app/oxford-debate/page.tsx +++ b/src/app/oxford-debate/page.tsx @@ -156,7 +156,9 @@ export default function OxfordDebate() { {/* debate finished */} {stage === 8 && (
-

{debateFinishedEnthusiastic}

+

+ {debateFinishedEnthusiastic} +

{"馃帀"}

)} diff --git a/src/app/oxford-debate/setup/page.tsx b/src/app/oxford-debate/setup/page.tsx index 71f062a..249e621 100644 --- a/src/app/oxford-debate/setup/page.tsx +++ b/src/app/oxford-debate/setup/page.tsx @@ -10,7 +10,12 @@ import { IconPlayCircle } from "@/components/icons/PlayCircle"; import { IconX } from "@/components/icons/X"; import { DebateContext } from "@/contexts/DebateContext"; import { useLang } from "@/lib/useLang"; -import { displayImageType, displayImageTypeArray } from "@/types/debate"; +import { + debateConf, + defaultDebateConf, + displayImageType, + displayImageTypeArray, +} from "@/types/debate"; import { useContext, useEffect, useState } from "react"; import { defaultSoundPack, @@ -68,7 +73,41 @@ export default function OxfordDebateSetup() { } else { setCustomClockImageSelected(false); } - }); + }, [setCustomClockImageSelected, debateContext.conf.clockImageName]); + + useEffect(() => { + debateContext.setConf(parseUrlParams()); + }, []); + + const parseUrlParams = () => { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const conf: debateConf = { + motion: urlParams.get("motion") || defaultDebateConf.motion, + proTeam: urlParams.get("propositionName") || defaultDebateConf.proTeam, + oppTeam: urlParams.get("oppositionName") || defaultDebateConf.oppTeam, + speechTime: + parseInt(urlParams.get("speechTime") || "") || + defaultDebateConf.speechTime, + adVocemTime: + parseInt(urlParams.get("adVocemTime") || "") || + defaultDebateConf.adVocemTime, + endProtectedTime: + parseInt(urlParams.get("protectedTime") || "") || + defaultDebateConf.endProtectedTime, + startProtectedTime: + parseInt(urlParams.get("startProtectedTime") || "") || + defaultDebateConf.startProtectedTime, + beepOnSpeechEnd: true, + beepProtectedTime: true, + visualizeProtectedTimes: false, + clockImageName: + urlParams.get("clockImage") != undefined ? "custom" : "null", + customClockImageBase64: urlParams.get("clockImage") || "", + soundPack: defaultSoundPack, + }; + return conf; + }; return (
diff --git a/src/components/DebatecoreFooter.tsx b/src/components/DebatecoreFooter.tsx index 1e6d45e..1c1ef3e 100644 --- a/src/components/DebatecoreFooter.tsx +++ b/src/components/DebatecoreFooter.tsx @@ -54,7 +54,7 @@ const DebatecoreFooter = (props: {}) => {
{useLang("disclaimer")} - {" 漏聽2023-2024 Jakub聽Ma艅czak & Mateusz聽Dobrzy艅ski"} + {" 漏聽2023-2025 Jakub聽Ma艅czak & Mateusz聽Dobrzy艅ski"}
); diff --git a/src/lib/imageToBase64.ts b/src/lib/imageToBase64.ts index 3021531..dd0e3a2 100644 --- a/src/lib/imageToBase64.ts +++ b/src/lib/imageToBase64.ts @@ -1,3 +1,5 @@ +import * as fs from "fs"; + const convertImageToBase64 = (file: File): Promise => { return new Promise((resolve) => { const fileReader = new FileReader(); @@ -19,4 +21,9 @@ const convertImageToBase64 = (file: File): Promise => { }); }; -export { convertImageToBase64 }; +const getBase64ImageFromPath = (imagePath: string): string => { + const imageBuffer = fs.readFileSync(imagePath); + return imageBuffer.toString("base64"); +}; + +export { convertImageToBase64, getBase64ImageFromPath }; diff --git a/tests/assets/black_mesa_lambda.png b/tests/assets/black_mesa_lambda.png new file mode 100644 index 0000000000000000000000000000000000000000..f816b06576988e7a69ea10c27007b400601b3f29 GIT binary patch literal 2919 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 { + // GIVEN + await page.goto("http://localhost:3000/oxford-debate/setup"); + + // WHEN + const minutes = await getTime("Speech", "minute", page); + const protectedTime = await getTime("Protected", "minute", page); + const adVocem = await getTime("Ad vocem", "minute", page); + + // THEN + expect(minutes).toBe("5 minutes"); + expect(protectedTime).toBe("0 minutes"); + expect(adVocem).toBe("1 minute"); +}); + +test("default setup: seconds", async ({ page }) => { + // GIVEN + await page.goto("http://localhost:3000/oxford-debate/setup"); + + // WHEN + const minutes = await getTime("Speech", "second", page); + const protectedTime = await getTime("Protected", "second", page); + const adVocem = await getTime("Ad vocem", "second", page); + + // THEN + expect(minutes).toBe("0 seconds"); + expect(protectedTime).toBe("30 seconds"); + expect(adVocem).toBe("0 seconds"); +}); + +test("default setup: names", async ({ page }) => { + // GIVEN + await page.goto("http://localhost:3000/oxford-debate/setup"); + + // WHEN + const proposition = await getTeamName("Proposition", page); + const opposition = await getTeamName("Opposition", page); + + // THEN + expect(proposition).toBe(""); + expect(opposition).toBe(""); +}); + +test("default setup: motion", async ({ page }) => { + // GIVEN + await page.goto("http://localhost:3000/oxford-debate/setup"); + + // WHEN + const motion = await getMotion(page); + + // THEN + expect(motion).toBe(""); +}); + +test("url params: team names", async ({ page }) => { + // GIVEN + await page.goto( + "http://localhost:3000/oxford-debate/setup?propositionName=Debate%20Team%20Buster&oppositionName=Dru偶yna%20Kamienia" + ); + + // WHEN + const propositionName = await getTeamName("Proposition", page); + const oppositionName = await getTeamName("Opposition", page); + + // THEN + expect(propositionName).toBe("Debate Team Buster"); + expect(oppositionName).toBe("Dru偶yna Kamienia"); +}); + +test("url params: English motion", async ({ page }) => { + // GIVEN + const motionInput = "This House Would abolish the UN Security Council."; + await page.goto( + `http://localhost:3000/oxford-debate/setup?motion=${motionInput}` + ); + + // WHEN + const motionOutput = await getMotion(page); + + // THEN + expect(motionOutput).toBe(motionInput); +}); + +test("url params: Polish motion", async ({ page }) => { + // GIVEN + const motionInput = "Nale偶y 偶a艂owa膰 popularno艣ci astrologii."; + await page.goto( + `http://localhost:3000/oxford-debate/setup?motion=${motionInput}` + ); + + // WHEN + const motionOutput = await getMotion(page); + + // THEN + expect(motionOutput).toBe(motionInput); +}); + +test("url params: time inputs", async ({ page }) => { + // GIVEN + await page.goto( + "http://localhost:3000/oxford-debate/setup?speechTime=240&protectedTime=15&adVocemTime=90" + ); + + // WHEN + const speechTimeMinutes = await getTime("Speech", "minute", page); + const protectedTimeSeconds = await getTime("Protected", "second", page); + const adVocemMinutes = await getTime("Ad vocem", "minute", page); + const adVocemSeconds = await getTime("Ad vocem", "second", page); + + // THEN + expect(speechTimeMinutes).toBe("4 minutes"); + expect(protectedTimeSeconds).toBe("15 seconds"); + expect(adVocemMinutes).toBe("1 minute"); + expect(adVocemSeconds).toBe("30 seconds"); +}); + +test("url params: clock image", async ({ page }, testinfo) => { + // GIVEN + const base64Image = getBase64ImageFromPath( + "tests/assets/black_mesa_lambda.png" + ); + await page.goto( + `http://localhost:3000/oxford-debate/setup?clockImage=data:image/png;base64, ${base64Image}` + ); + + // WHEN + await page.getByRole("button", { name: "Start debate" }).click(); + await page.waitForURL("http://localhost:3000/oxford-debate"); + + // THEN + const img = await page.getByRole("img", { name: "custom" }); + await expect(img).toHaveJSProperty("complete", true); + await expect(img).toHaveAttribute("data-loaded", "true"); + + const screenshot = await page.screenshot({ fullPage: true }); + await testinfo.attach( + `setup->display of image: "custom" test - full page screenshot`, + { + body: screenshot, + contentType: "image/jpg", + } + ); +}); + +async function getTime( + value: "Speech" | "Ad vocem" | "Protected", + time: "minute" | "second", + page: Page +): Promise { + const element = await page.getByText(`${value} time-`).getByText(time); + const text = await element.textContent(); + if (text) { + return text; + } else { + throw Error(`Failed to read ${value} ${time}s`); + } +} + +async function getTeamName( + side: "Proposition" | "Opposition", + page: Page +): Promise { + const name = await page.getByPlaceholder(`${side} Team`).inputValue(); + if (name || name == "") { + return name; + } else { + throw Error(`Failed to read ${side} name`); + } +} + +async function getMotion(page: Page): Promise { + const motion = await page.getByPlaceholder("Debate motion").inputValue(); + if (motion || motion == "") { + return motion; + } else { + throw Error("Failed to read motion"); + } +} From b87855e666757334ea58a6c77145c654e736b0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Dobrzy=C5=84ski?= Date: Sun, 9 Mar 2025 09:17:16 +0100 Subject: [PATCH 02/10] [105] parse time inputs and strings TO-DO: parse boolean inputs, clock images, and sound packs --- src/app/oxford-debate/setup/page.tsx | 46 +++++++++++++++++++++------ src/components/ClockDisplayImage.tsx | 17 +++++++++- src/data/strings.json | 5 +++ src/types/debate.ts | 2 ++ tests/e2e/url-params-parsing.test.ts | 47 +++++++++++++++++++--------- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/src/app/oxford-debate/setup/page.tsx b/src/app/oxford-debate/setup/page.tsx index 249e621..4a9bc1a 100644 --- a/src/app/oxford-debate/setup/page.tsx +++ b/src/app/oxford-debate/setup/page.tsx @@ -16,7 +16,7 @@ import { displayImageType, displayImageTypeArray, } from "@/types/debate"; -import { useContext, useEffect, useState } from "react"; +import { useContext, useEffect, useRef, useState } from "react"; import { defaultSoundPack, soundPackName, @@ -25,6 +25,7 @@ import { } from "@/types/soundPack"; import { convertImageToBase64 } from "@/lib/imageToBase64"; import { DebatecoreFooter } from "@/components/DebatecoreFooter"; +import { IconClipboard } from "@/components/icons/Clipboard"; export default function OxfordDebateSetup() { const debateContext = useContext(DebateContext); @@ -36,6 +37,7 @@ export default function OxfordDebateSetup() { const soundPackDefault = useLang("defaultSoundsOption"); const [customClockImageSelected, setCustomClockImageSelected] = useState(false); + const initializedRef = useRef(false); const getDisplayNameOfClockImage = (clockImageName: string) => { switch (clockImageName) { @@ -73,12 +75,9 @@ export default function OxfordDebateSetup() { } else { setCustomClockImageSelected(false); } + initializedRef.current = true; }, [setCustomClockImageSelected, debateContext.conf.clockImageName]); - useEffect(() => { - debateContext.setConf(parseUrlParams()); - }, []); - const parseUrlParams = () => { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); @@ -98,17 +97,39 @@ export default function OxfordDebateSetup() { startProtectedTime: parseInt(urlParams.get("startProtectedTime") || "") || defaultDebateConf.startProtectedTime, - beepOnSpeechEnd: true, - beepProtectedTime: true, + beepOnSpeechEnd: + parseAsBooleanValue(urlParams.get("beepOnSpeechEnd")) || + defaultDebateConf.beepOnSpeechEnd, + beepProtectedTime: + parseAsBooleanValue(urlParams.get("beepProtectedTime")) || + defaultDebateConf.beepProtectedTime, visualizeProtectedTimes: false, - clockImageName: - urlParams.get("clockImage") != undefined ? "custom" : "null", - customClockImageBase64: urlParams.get("clockImage") || "", + clockImageName: urlParams.get("clockImage") ? "custom" : "null", + customClockImageBase64: "", + customClockImageLink: urlParams.get("clockImage") || "", soundPack: defaultSoundPack, }; return conf; }; + useEffect(() => { + let confFromParams = parseUrlParams(); + if (debateContext.conf != confFromParams) { + debateContext.setConf(parseUrlParams()); + } + }, []); + + function parseAsBooleanValue(value: string | null): boolean | undefined { + console.log(value); + if (value == "true") { + return true; + } else if (value == "false") { + return false; + } else { + return undefined; + } + } + return (
@@ -235,6 +256,11 @@ export default function OxfordDebateSetup() { }); }} /> + {}} + text={useLang("copyDebateConfiguration")} + icon={IconClipboard} + />
diff --git a/src/components/ClockDisplayImage.tsx b/src/components/ClockDisplayImage.tsx index a7755f3..d56bbd5 100644 --- a/src/components/ClockDisplayImage.tsx +++ b/src/components/ClockDisplayImage.tsx @@ -11,6 +11,21 @@ const ClockDisplayImage = () => { const [clockImageLoaded, setClockImageLoaded] = useState(false); const loadingText = useLang("loading"); + const getImageSource = () => { + if ( + currentDebateConf.clockImageName == "custom" && + currentDebateConf.customClockImageBase64 != "" + ) { + return `data:image/png;base64, ${currentDebateConf.customClockImageBase64}`; + } else if ( + currentDebateConf.clockImageName == "custom" && + currentDebateConf.customClockImageLink != "" + ) { + console.log("clock image", currentDebateConf.customClockImageLink); + return currentDebateConf.customClockImageLink; + } + }; + return (
{ {clockImageName === "custom" && currentDebateConf.customClockImageBase64 != "" && ( Custom logo { expect(adVocemSeconds).toBe("30 seconds"); }); -test("url params: clock image", async ({ page }, testinfo) => { +test("url params: booleanInputs", async ({ page }) => { // GIVEN - const base64Image = getBase64ImageFromPath( - "tests/assets/black_mesa_lambda.png" + await page.goto( + "http://localhost:3000/oxford-debate/setup?beepOnSpeechEnd=false&beepOnProtectedTime=false&startProtectedTime=30&endProtectedTime=30" + ); + + // WHEN + const beepOnSpeechEndButton = page.getByText("Beep on speech end"); + const beepOnSpeechEndCross = await beepOnSpeechEndButton.locator("svg"); + + const beepOnProtectedTimeButton = page.getByText("Beep on protected time"); + const beepOnProtectedTimeCross = await beepOnProtectedTimeButton.locator( + "svg" ); + + const startProtectedTimeButton = page.getByText( + "Protect time on speech start" + ); + const startProtectedTimeCheck = await startProtectedTimeButton.locator("svg"); + const image = await beepOnSpeechEndButton.evaluate((el: Element) => { + return window.getComputedStyle(el).getPropertyValue("background-image"); + }); + + // THEN + expect(beepOnSpeechEndCross).toBeVisible(); + expect(beepOnProtectedTimeCross).toBeVisible(); + expect(startProtectedTimeCheck).toBeVisible(); +}); + +test("url params: clock image", async ({ page }) => { + // GIVEN await page.goto( - `http://localhost:3000/oxford-debate/setup?clockImage=data:image/png;base64, ${base64Image}` + "http://localhost:3000/oxford-debate/setup?clockImage=https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Orange_lambda.svg/459px-Orange_lambda.svg.png" ); // WHEN await page.getByRole("button", { name: "Start debate" }).click(); await page.waitForURL("http://localhost:3000/oxford-debate"); - - // THEN const img = await page.getByRole("img", { name: "custom" }); + await expect(img).toHaveJSProperty("complete", true); await expect(img).toHaveAttribute("data-loaded", "true"); - - const screenshot = await page.screenshot({ fullPage: true }); - await testinfo.attach( - `setup->display of image: "custom" test - full page screenshot`, - { - body: screenshot, - contentType: "image/jpg", - } - ); + // THEN }); async function getTime( From 67d702338cc24a535998bbaead5c7e5dc66c7e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Dobrzy=C5=84ski?= Date: Sun, 9 Mar 2025 14:11:08 +0100 Subject: [PATCH 03/10] [105] fix boolean url params and clock image --- src/app/oxford-debate/setup/page.tsx | 39 +++-- src/components/ClockDisplayImage.tsx | 28 +++- src/components/TimeInput.tsx | 2 +- tests/e2e/debate-setup.test.ts | 83 ++++++++++ tests/e2e/debate-view.test.ts | 64 ++++++++ tests/e2e/url-params-parsing.test.ts | 226 +++++++++++++++++---------- 6 files changed, 343 insertions(+), 99 deletions(-) create mode 100644 tests/e2e/debate-setup.test.ts create mode 100644 tests/e2e/debate-view.test.ts diff --git a/src/app/oxford-debate/setup/page.tsx b/src/app/oxford-debate/setup/page.tsx index 4a9bc1a..0deeebe 100644 --- a/src/app/oxford-debate/setup/page.tsx +++ b/src/app/oxford-debate/setup/page.tsx @@ -26,6 +26,7 @@ import { import { convertImageToBase64 } from "@/lib/imageToBase64"; import { DebatecoreFooter } from "@/components/DebatecoreFooter"; import { IconClipboard } from "@/components/icons/Clipboard"; +import { useEffectOnce } from "react-use"; export default function OxfordDebateSetup() { const debateContext = useContext(DebateContext); @@ -97,12 +98,8 @@ export default function OxfordDebateSetup() { startProtectedTime: parseInt(urlParams.get("startProtectedTime") || "") || defaultDebateConf.startProtectedTime, - beepOnSpeechEnd: - parseAsBooleanValue(urlParams.get("beepOnSpeechEnd")) || - defaultDebateConf.beepOnSpeechEnd, - beepProtectedTime: - parseAsBooleanValue(urlParams.get("beepProtectedTime")) || - defaultDebateConf.beepProtectedTime, + beepOnSpeechEnd: getBooleanParamValue("beepOnSpeechEnd", urlParams), + beepProtectedTime: getBooleanParamValue("beepProtectedTime", urlParams), visualizeProtectedTimes: false, clockImageName: urlParams.get("clockImage") ? "custom" : "null", customClockImageBase64: "", @@ -112,14 +109,34 @@ export default function OxfordDebateSetup() { return conf; }; - useEffect(() => { + useEffectOnce(() => { let confFromParams = parseUrlParams(); - if (debateContext.conf != confFromParams) { - debateContext.setConf(parseUrlParams()); + if ( + debateContext.conf == defaultDebateConf && + confFromParams != defaultDebateConf + ) { + debateContext.setConf(confFromParams); + console.log(confFromParams); } - }, []); + }); + + function getBooleanParamValue( + param: "beepOnSpeechEnd" | "beepProtectedTime", + urlParams: URLSearchParams + ): boolean { + const paramValue = parseAsBoolean(urlParams.get(param)); + if (paramValue != undefined) { + return paramValue; + } else if (param == "beepOnSpeechEnd") { + return defaultDebateConf.beepOnSpeechEnd; + } else if (param == "beepProtectedTime") { + return defaultDebateConf.beepProtectedTime; + } else { + throw Error("Invalid boolean param"); + } + } - function parseAsBooleanValue(value: string | null): boolean | undefined { + function parseAsBoolean(value: string | null): boolean | undefined { console.log(value); if (value == "true") { return true; diff --git a/src/components/ClockDisplayImage.tsx b/src/components/ClockDisplayImage.tsx index d56bbd5..658f5df 100644 --- a/src/components/ClockDisplayImage.tsx +++ b/src/components/ClockDisplayImage.tsx @@ -11,7 +11,12 @@ const ClockDisplayImage = () => { const [clockImageLoaded, setClockImageLoaded] = useState(false); const loadingText = useLang("loading"); - const getImageSource = () => { + function getImageSource() { + console.log( + "loading clock image", + currentDebateConf.customClockImageBase64, + currentDebateConf.customClockImageLink + ); if ( currentDebateConf.clockImageName == "custom" && currentDebateConf.customClockImageBase64 != "" @@ -23,8 +28,10 @@ const ClockDisplayImage = () => { ) { console.log("clock image", currentDebateConf.customClockImageLink); return currentDebateConf.customClockImageLink; + } else { + return ""; } - }; + } return (
{ /> )} {clockImageName === "custom" && - currentDebateConf.customClockImageBase64 != "" && ( + currentDebateConf.customClockImageBase64 != "" && + currentDebateConf.customClockImageLink == "" && ( Custom logo setClockImageLoaded(true)} + data-loaded={clockImageLoaded} + /> + )} + {clockImageName === "custom" && + currentDebateConf.customClockImageLink != "" && ( + Custom logo
{minutesCount} - {` ${minutesGrammaticalNumber}`} + {` ${minutesGrammaticalNumber}`}