diff --git a/next-env.d.ts b/next-env.d.ts
index a4a7b3f5..15849f6d 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,5 +1,7 @@
///
///
+import "./.next/types/routes.d.ts";
+import "./.next/types/root-params.d.ts";
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
diff --git a/next.config.js b/next.config.js
index 4c201544..7f45af5e 100644
--- a/next.config.js
+++ b/next.config.js
@@ -58,16 +58,10 @@ const buildId = Date.now().toString();
module.exports = {
//output: "standalone",
- eslint: {
- // Warning: This allows production builds to successfully complete even if
- // your project has ESLint errors.
- ignoreDuringBuilds: true
- },
reactStrictMode: false,
env: {
BUILD_ID_ENV: buildId
},
- swcMinify: false,
sassOptions: {
includePaths: [
"/styles/sass",
diff --git a/package-lock.json b/package-lock.json
index c7f76628..4dd4ef1f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,7 @@
"@microsoft/applicationinsights-react-js": "^17.3.2",
"@microsoft/applicationinsights-web": "^3.3.2",
"@next-auth/prisma-adapter": "^1.0.7",
- "@next/third-parties": "latest",
+ "@next/third-parties": "16.4.4",
"@prisma/client": "^5.7.0",
"@react-pdf/renderer": "^3.1.14",
"@redux-devtools/extension": "^3.3.0",
@@ -41,7 +41,7 @@
"moment": "^2.29.4",
"multiparty": "^4.2.3",
"mysql": "^2.18.1",
- "next": "^14.2.28",
+ "next": "16.4.4",
"next-auth": "4.24.15",
"next-build-id": "^3.0.0",
"next-connect": "^0.12.2",
@@ -515,10 +515,10 @@
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz",
- "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==",
- "dev": true,
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
+ "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
+ "license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
@@ -661,6 +661,507 @@
"deprecated": "Use @eslint/object-schema instead",
"dev": true
},
+ "node_modules/@img/colour": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz",
+ "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz",
+ "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-freebsd-wasm32": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz",
+ "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.5"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz",
+ "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz",
+ "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz",
+ "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz",
+ "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz",
+ "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz",
+ "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz",
+ "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz",
+ "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz",
+ "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz",
+ "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz",
+ "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz",
+ "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz",
+ "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz",
+ "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz",
+ "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz",
+ "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz",
+ "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz",
+ "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz",
+ "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-webcontainers-wasm32": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz",
+ "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.5"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz",
+ "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz",
+ "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz",
+ "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -1044,9 +1545,10 @@
}
},
"node_modules/@next/env": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.28.tgz",
- "integrity": "sha512-PAmWhJfJQlP+kxZwCjrVd9QnR5x0R3u0mTXTiZDgSd4h5LdXmjxCCWbN9kq6hkZBOax8Rm3xDW5HagWyJuT37g=="
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.4.4.tgz",
+ "integrity": "sha512-6/3ZuELR0tPLgNigvv8d/LAmfLIo1IpNfvrI/AHCAl9w9D0DNVGQGvo+OLPzAWR+WMW3vVyO7HaW0kfL97huBg==",
+ "license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
"version": "14.2.35",
@@ -1058,12 +1560,13 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.28.tgz",
- "integrity": "sha512-kzGChl9setxYWpk3H6fTZXXPFFjg7urptLq5o5ZgYezCrqlemKttwMT5iFyx/p1e/JeglTwDFRtb923gTJ3R1w==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.4.4.tgz",
+ "integrity": "sha512-1KlZ5IJ7zcLBZvqG1q7nuRWm2LAAN4C3iBqqoBCRRl1UEv0A4k6Rek+x3j23UiWf8Gz+VsN+M/LylAWkxpm2mg==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -1073,12 +1576,13 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.28.tgz",
- "integrity": "sha512-z6FXYHDJlFOzVEOiiJ/4NG8aLCeayZdcRSMjPDysW297Up6r22xw6Ea9AOwQqbNsth8JNgIK8EkWz2IDwaLQcw==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.4.4.tgz",
+ "integrity": "sha512-Tb7efFdhbS/ph74RS7wob84gXGM58qxoO/WrkiMsTmy/JZktKOKBeiM45W0E/b8JfBzZJdexQqSmvedBwDK0PA==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -1088,12 +1592,13 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.28.tgz",
- "integrity": "sha512-9ARHLEQXhAilNJ7rgQX8xs9aH3yJSj888ssSjJLeldiZKR4D7N08MfMqljk77fAwZsWwsrp8ohHsMvurvv9liQ==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.4.4.tgz",
+ "integrity": "sha512-wojSfLnH8RRImhtbcn3Dlx9JICh6aQHgDA33XDr+EPua2tt7Q/yjDn0FTAbqfNlLrBmOASAGhLh6NvBk9L3gzw==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -1103,12 +1608,13 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.28.tgz",
- "integrity": "sha512-p6gvatI1nX41KCizEe6JkF0FS/cEEF0u23vKDpl+WhPe/fCTBeGkEBh7iW2cUM0rvquPVwPWdiUR6Ebr/kQWxQ==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.4.4.tgz",
+ "integrity": "sha512-zgxpGOZaR+2O6dOk5ZAUkKgH92ZtqNg3ohzyg2HmWc2N+AZH4dEpTwdpB0e5MR9YRVdVDUkEM5g6c3TWWn8g1g==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -1118,12 +1624,13 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.28.tgz",
- "integrity": "sha512-nsiSnz2wO6GwMAX2o0iucONlVL7dNgKUqt/mDTATGO2NY59EO/ZKnKEr80BJFhuA5UC1KZOMblJHWZoqIJddpA==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.4.4.tgz",
+ "integrity": "sha512-fg3Wr030Y3BDkCXi6HGsPz0BUPTGZJS8TZSrCO0tS3O/KBsCyx4eP6aeaizCpGmcUKhtb4l7JoMc88QO2qBl2g==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -1133,12 +1640,13 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.28.tgz",
- "integrity": "sha512-+IuGQKoI3abrXFqx7GtlvNOpeExUH1mTIqCrh1LGFf8DnlUcTmOOCApEnPJUSLrSbzOdsF2ho2KhnQoO0I1RDw==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.4.4.tgz",
+ "integrity": "sha512-40cr71PSdCV9zU2g0B1XG27af10tYU+9g8F+FtF3qSguQg0jSZDoxn0NrAvgFQ0cy9s0ZBA/00P9g/XL1O43xg==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -1148,27 +1656,13 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.28.tgz",
- "integrity": "sha512-l61WZ3nevt4BAnGksUVFKy2uJP5DPz2E0Ma/Oklvo3sGj9sw3q7vBWONFRgz+ICiHpW5mV+mBrkB3XEubMrKaA==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.4.4.tgz",
+ "integrity": "sha512-vFMiEbRZ+LYNeswslf4LuGuoPHE8JbtqV0GnmzbpnGNMs0uWaR2q98hu8M/UWGycNJERBXIUss+BGd3PIJ8VZg==",
"cpu": [
"arm64"
],
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-ia32-msvc": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.28.tgz",
- "integrity": "sha512-+Kcp1T3jHZnJ9v9VTJ/yf1t/xmtFAc/Sge4v7mVc1z+NYfYzisi8kJ9AsY8itbgq+WgEwMtOpiLLJsUy2qnXZw==",
- "cpu": [
- "ia32"
- ],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -1178,12 +1672,13 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.28.tgz",
- "integrity": "sha512-1gCmpvyhz7DkB1srRItJTnmR2UwQPAUXXIg9r0/56g3O8etGmwlX68skKXJOp9EejW3hhv7nSQUJ2raFiz4MoA==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.4.4.tgz",
+ "integrity": "sha512-jy2P4V8BDZ+CFCzYABHYRZ1CmyFhfmYe22i8KA4uEafdYPrUjJ3Ot+lx265mLWLHiZRIfBzCn3V1F17m0vzl9Q==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -1193,15 +1688,16 @@
}
},
"node_modules/@next/third-parties": {
- "version": "14.2.13",
- "resolved": "https://registry.npmjs.org/@next/third-parties/-/third-parties-14.2.13.tgz",
- "integrity": "sha512-OSqD2E9JO0/GE8HT5QAUsYVXwjWtPLScAX70kO2xopwDAdRzakrsQS55Cihd862X/4bUB37ApVZ9DlHcExzeOg==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/@next/third-parties/-/third-parties-16.4.4.tgz",
+ "integrity": "sha512-dIdxOALEfAnOs2yU0RmYfHgz0SvlLbzp8QOL8+q7TcFWb24vwPsL7i+MLiHK1Drt7C3oecTczs5ysMoaZpY5iA==",
+ "license": "MIT",
"dependencies": {
"third-party-capital": "1.0.20"
},
"peerDependencies": {
- "next": "^13.0.0 || ^14.0.0",
- "react": "^18.2.0"
+ "next": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0"
}
},
"node_modules/@nodelib/fs.scandir": {
@@ -2172,16 +2668,13 @@
"node": ">=12.20.0"
}
},
- "node_modules/@swc/counter": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
- "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
- },
"node_modules/@swc/helpers": {
- "version": "0.5.13",
+ "version": "0.5.23",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
+ "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
"license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.4.0"
+ "tslib": "^2.8.0"
}
},
"node_modules/@tokenizer/inflate": {
@@ -3401,6 +3894,18 @@
],
"license": "MIT"
},
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.35",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.35.tgz",
+ "integrity": "sha512-GNk8KX52CHqeNKGk8+7tZnQab/2k1t/BgrUHPKNdijzpEhF1saPQZHVKb6m5loSAxB39gyrTYw34Qf9CQ3u1qQ==",
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/bidi-js": {
"version": "1.0.3",
"license": "MIT",
@@ -3543,15 +4048,6 @@
"version": "1.1.2",
"license": "MIT"
},
- "node_modules/busboy": {
- "version": "1.6.0",
- "dependencies": {
- "streamsearch": "^1.1.0"
- },
- "engines": {
- "node": ">=10.16.0"
- }
- },
"node_modules/bytes": {
"version": "3.1.2",
"license": "MIT",
@@ -3781,6 +4277,8 @@
},
"node_modules/client-only": {
"version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/clone": {
@@ -4269,7 +4767,9 @@
}
},
"node_modules/detect-libc": {
- "version": "2.0.3",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"optional": true,
"engines": {
@@ -7406,15 +7906,16 @@
"optional": true
},
"node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "version": "3.3.20",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz",
+ "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -7462,40 +7963,41 @@
}
},
"node_modules/next": {
- "version": "14.2.28",
- "resolved": "https://registry.npmjs.org/next/-/next-14.2.28.tgz",
- "integrity": "sha512-QLEIP/kYXynIxtcKB6vNjtWLVs3Y4Sb+EClTC/CSVzdLD1gIuItccpu/n1lhmduffI32iPGEK2cLLxxt28qgYA==",
+ "version": "16.4.4",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.4.4.tgz",
+ "integrity": "sha512-Hu4pOw2x0RQ0TQabNWbpsNg/3+SZf+rLQwvfhBLnptv98GS4dcIVMlfEyn9jb2/ZJDSahhnUKEs0YrfarjGX3A==",
+ "license": "MIT",
"dependencies": {
- "@next/env": "14.2.28",
- "@swc/helpers": "0.5.5",
- "busboy": "1.6.0",
+ "@next/env": "16.4.4",
+ "@swc/helpers": "0.5.23",
+ "baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
- "graceful-fs": "^4.2.11",
- "postcss": "8.4.31",
- "styled-jsx": "5.1.1"
+ "postcss": "8.5.23",
+ "styled-jsx": "5.1.6"
},
"bin": {
"next": "dist/bin/next"
},
"engines": {
- "node": ">=18.17.0"
+ "node": ">=20.9.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "14.2.28",
- "@next/swc-darwin-x64": "14.2.28",
- "@next/swc-linux-arm64-gnu": "14.2.28",
- "@next/swc-linux-arm64-musl": "14.2.28",
- "@next/swc-linux-x64-gnu": "14.2.28",
- "@next/swc-linux-x64-musl": "14.2.28",
- "@next/swc-win32-arm64-msvc": "14.2.28",
- "@next/swc-win32-ia32-msvc": "14.2.28",
- "@next/swc-win32-x64-msvc": "14.2.28"
+ "@next/swc-darwin-arm64": "16.4.4",
+ "@next/swc-darwin-x64": "16.4.4",
+ "@next/swc-linux-arm64-gnu": "16.4.4",
+ "@next/swc-linux-arm64-musl": "16.4.4",
+ "@next/swc-linux-x64-gnu": "16.4.4",
+ "@next/swc-linux-x64-musl": "16.4.4",
+ "@next/swc-win32-arm64-msvc": "16.4.4",
+ "@next/swc-win32-x64-msvc": "16.4.4",
+ "sharp": "^0.35.5"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
- "@playwright/test": "^1.41.2",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
+ "@playwright/test": "^1.51.1",
+ "babel-plugin-react-compiler": "*",
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
"sass": "^1.3.0"
},
"peerDependenciesMeta": {
@@ -7505,6 +8007,9 @@
"@playwright/test": {
"optional": true
},
+ "babel-plugin-react-compiler": {
+ "optional": true
+ },
"sass": {
"optional": true
}
@@ -7659,15 +8164,6 @@
"node": ">=4.2.0"
}
},
- "node_modules/next/node_modules/@swc/helpers": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
- "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
- "dependencies": {
- "@swc/counter": "^0.1.3",
- "tslib": "^2.4.0"
- }
- },
"node_modules/node-abort-controller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
@@ -8306,7 +8802,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.1.0",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC"
},
"node_modules/picomatch": {
@@ -8375,7 +8873,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.31",
+ "version": "8.5.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz",
+ "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
"funding": [
{
"type": "opencollective",
@@ -8392,9 +8892,9 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.16",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -9505,9 +10005,10 @@
"license": "MIT"
},
"node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "version": "7.8.6",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz",
+ "integrity": "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -9658,6 +10159,56 @@
"version": "1.2.1",
"license": "MIT"
},
+ "node_modules/sharp": {
+ "version": "0.35.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz",
+ "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/colour": "^1.1.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.8.5"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.35.5",
+ "@img/sharp-darwin-x64": "0.35.5",
+ "@img/sharp-freebsd-wasm32": "0.35.5",
+ "@img/sharp-libvips-darwin-arm64": "1.3.4",
+ "@img/sharp-libvips-darwin-x64": "1.3.4",
+ "@img/sharp-libvips-linux-arm": "1.3.4",
+ "@img/sharp-libvips-linux-arm64": "1.3.4",
+ "@img/sharp-libvips-linux-ppc64": "1.3.4",
+ "@img/sharp-libvips-linux-riscv64": "1.3.4",
+ "@img/sharp-libvips-linux-s390x": "1.3.4",
+ "@img/sharp-libvips-linux-x64": "1.3.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.4",
+ "@img/sharp-linux-arm": "0.35.5",
+ "@img/sharp-linux-arm64": "0.35.5",
+ "@img/sharp-linux-ppc64": "0.35.5",
+ "@img/sharp-linux-riscv64": "0.35.5",
+ "@img/sharp-linux-s390x": "0.35.5",
+ "@img/sharp-linux-x64": "0.35.5",
+ "@img/sharp-linuxmusl-arm64": "0.35.5",
+ "@img/sharp-linuxmusl-x64": "0.35.5",
+ "@img/sharp-webcontainers-wasm32": "0.35.5",
+ "@img/sharp-win32-arm64": "0.35.5",
+ "@img/sharp-win32-ia32": "0.35.5",
+ "@img/sharp-win32-x64": "0.35.5"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -9903,12 +10454,6 @@
"npm": ">=6"
}
},
- "node_modules/streamsearch": {
- "version": "1.1.0",
- "engines": {
- "node": ">=10.0.0"
- }
- },
"node_modules/string_decoder": {
"version": "1.3.0",
"license": "MIT",
@@ -10124,7 +10669,9 @@
}
},
"node_modules/styled-jsx": {
- "version": "5.1.1",
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
+ "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
"license": "MIT",
"dependencies": {
"client-only": "0.0.1"
@@ -10133,7 +10680,7 @@
"node": ">= 12.0.0"
},
"peerDependencies": {
- "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
},
"peerDependenciesMeta": {
"@babel/core": {
@@ -10694,7 +11241,9 @@
}
},
"node_modules/tslib": {
- "version": "2.7.0",
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.9.1.tgz",
+ "integrity": "sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==",
"license": "0BSD"
},
"node_modules/type-check": {
diff --git a/package.json b/package.json
index abed6912..726ec68f 100644
--- a/package.json
+++ b/package.json
@@ -3,10 +3,10 @@
"version": "0.1.0",
"private": true,
"scripts": {
- "dev": "next dev",
+ "dev": "next dev --webpack",
"debugdev": "NODE_OPTIONS='--inspect' next dev",
"dev:app": "node ./server/server.js",
- "build": "NODE_ENV=production node_modules/next/dist/bin/next build",
+ "build": "NODE_ENV=production node_modules/next/dist/bin/next build --webpack",
"start2": "NODE_ENV=production node ./server.js",
"start3": "NODE_ENV=production next start",
"start": "NODE_ENV=production node_modules/next/dist/bin/next start",
@@ -29,7 +29,7 @@
"@microsoft/applicationinsights-react-js": "^17.3.2",
"@microsoft/applicationinsights-web": "^3.3.2",
"@next-auth/prisma-adapter": "^1.0.7",
- "@next/third-parties": "latest",
+ "@next/third-parties": "16.4.4",
"@prisma/client": "^5.7.0",
"@react-pdf/renderer": "^3.1.14",
"@redux-devtools/extension": "^3.3.0",
@@ -55,7 +55,7 @@
"moment": "^2.29.4",
"multiparty": "^4.2.3",
"mysql": "^2.18.1",
- "next": "^14.2.28",
+ "next": "16.4.4",
"next-auth": "4.24.15",
"next-build-id": "^3.0.0",
"next-connect": "^0.12.2",
diff --git a/pwe2e/tests/apiTests/api.spec.js b/pwe2e/tests/apiTests/api.spec.js
deleted file mode 100644
index 0e5847bd..00000000
--- a/pwe2e/tests/apiTests/api.spec.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import { test, expect } from "@playwright/test";
-
-// TO DO - build PEDW API playwright harness
-
-// Define a base URL for the mock API
-const BASE_URL = process.env.BASE_URL;
-
-test.describe("User API Validation Suite", () => {
- // 1. GET Request Example
- test("should fetch a list of users and validate headers", async ({
- request,
- }) => {
- const response = await request.get(`${BASE_URL}/users/1`);
-
- // Assert the HTTP status code is 200 OK
- expect(response.ok()).toBeTruthy();
- expect(response.status()).toBe(200);
-
- // Parse the JSON response body
- const responseBody = await response.json();
-
- // Assert specific data fields inside the JSON
- expect(responseBody.id).toBe(1);
- expect(responseBody.name).toBe("Leanne Graham");
- expect(responseBody.email).toBe("Sincere@april.biz");
-
- // Assert response headers
- expect(response.headers()["content-type"]).toContain("application/json");
- });
-
- // 2. POST Request Example
- test("should successfully create a new post", async ({ request }) => {
- const response = await request.post(`${BASE_URL}/posts`, {
- headers: {
- "Content-type": "application/json; charset=UTF-8",
- // 'Authorization': `Bearer ${process.env.API_TOKEN}` <-- Example for CI/CD tokens
- },
- data: {
- title: "Automation Test",
- body: "Testing APIs with Playwright in DevOps pipelines.",
- userId: 99,
- },
- });
-
- // Assert creation status code (201 Created)
- expect(response.status()).toBe(201);
-
- const responseBody = await response.json();
-
- // Assert the API returned our sent data with a new generated ID
- expect(responseBody).toMatchObject({
- title: "Automation Test",
- body: "Testing APIs with Playwright in DevOps pipelines.",
- userId: 99,
- id: 101, // Mock database increments ID to 101
- });
- });
-
- // 3. PUT Request Example (Update)
- test("should update an existing post", async ({ request }) => {
- const response = await request.put(`${BASE_URL}/posts/1`, {
- data: {
- id: 1,
- title: "Updated Title",
- body: "Updated body content",
- userId: 1,
- },
- });
-
- expect(response.ok()).toBeTruthy();
- const responseBody = await response.json();
- expect(responseBody.title).toBe("Updated Title");
- });
-
- // 4. DELETE Request Example
- test("should delete a post", async ({ request }) => {
- const response = await request.delete(`${BASE_URL}/posts/1`);
-
- // Assert successful deletion response status
- expect(response.status()).toBe(200);
- });
-});
diff --git a/pwe2e/tests/loggedin/downloadFile.spec.js b/pwe2e/tests/loggedin/downloadFile.spec.js
deleted file mode 100644
index 5ccc673d..00000000
--- a/pwe2e/tests/loggedin/downloadFile.spec.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { test, expect } from "@playwright/test";
-import { login } from "../../helpers";
-
-test("Download a file when logged in", async ({ page }) => {
- await login(page);
-
- await page
- .getByRole("textbox", { name: "Use the case reference or DNS" })
- .click();
- await page
- .getByRole("textbox", { name: "Use the case reference or DNS" })
- .fill("gaerwen");
- await page.getByRole("button", { name: "Submit search" }).click();
- // await page
- // .getByRole("link", { name: "DNS3276735 - Gaerwen Wind Farm (test)" })
- // .click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- const downloadPromise = page.waitForEvent("download");
-
- await page.locator(".documentLink").first().click();
-
- const download = await downloadPromise;
- await page.getByText("Download complete!").click();
- await page.getByRole("link", { name: "Home" }).click();
-});
diff --git a/pwe2e/tests/loggedin/newappeal.spec.js b/pwe2e/tests/loggedin/newappeal.spec.js
deleted file mode 100644
index 53ecfc51..00000000
--- a/pwe2e/tests/loggedin/newappeal.spec.js
+++ /dev/null
@@ -1,149 +0,0 @@
-import { test, expect } from "@playwright/test";
-import path from "path";
-import { login } from "../../helpers";
-
-const date = new Date();
-date.setDate(date.getDate() - 1); // 👈 subtract 1 day
-
-const day = date.getDate();
-
-const ordinal = (n) => {
- if (n > 3 && n < 21) return "th";
- switch (n % 10) {
- case 1:
- return "st";
- case 2:
- return "nd";
- case 3:
- return "rd";
- default:
- return "th";
- }
-};
-
-const weekday = date.toLocaleDateString("en-GB", { weekday: "long" });
-const month = date.toLocaleDateString("en-GB", { month: "long" });
-
-const finalDate = `${weekday}, ${month} ${day}${ordinal(day)}`;
-
-test("Login and Raise new appeal", async ({ page }) => {
- await login(page);
-
- // create new appeal
- await page.getByRole("link", { name: "Make a new appeal" }).click();
- await page
- .getByRole("textbox", { name: "Appellant or organisation's" })
- .click();
- await page
- .getByRole("textbox", { name: "Appellant or organisation's" })
- .fill("Bob");
- await page.getByText("Appellant", { exact: true }).click();
- await page.getByText("English").click();
- await page.getByText("I confirm that I am making an").click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByLabel("Select your Local Planning")
- .selectOption("b9aee444-6ff0-eb11-aac7-00224800be9c");
- await page.getByLabel("Select a case type").selectOption("846040000");
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- const step2 = page.locator('[aria-controls="step-panel-appeal-details"]');
- await step2.click();
-
- await page.getByRole("textbox", { name: "Development description" }).click();
- await page
- .getByRole("textbox", { name: "Development description" })
- .fill("Something in here");
- await page.getByText("No", { exact: true }).click();
- await page
- .getByRole("textbox", { name: "LPA's application reference" })
- .click();
- await page
- .getByRole("textbox", { name: "LPA's application reference" })
- .fill("AB1234");
- await page.getByRole("textbox", { name: "Application form dated" }).click();
-
- await page.getByRole("option", { name: `Choose ${finalDate}` }).click();
- await page.getByLabel("Reason for appeal").selectOption("846040005");
- await page.getByRole("textbox", { name: "Site address line 1" }).click();
- await page
- .getByRole("textbox", { name: "Site address line 1" })
- .fill("1 High Road");
- await page.getByRole("textbox", { name: "Site address line 1" }).press("Tab");
- await page.getByRole("textbox", { name: "Site address line 2" }).press("Tab");
- await page
- .getByRole("textbox", { name: "Site address town" })
- .fill("Big town");
- await page.getByRole("textbox", { name: "Site address town" }).press("Tab");
- await page
- .getByRole("textbox", { name: "Site address county" })
- .fill("Cardiff");
- await page.getByRole("textbox", { name: "Site address county" }).press("Tab");
- await page
- .getByRole("textbox", { name: "Site address postcode" })
- .fill("cf21 3qa");
- await page
- .getByRole("textbox", { name: "Site address postcode" })
- .press("Tab");
- await page
- .getByRole("textbox", { name: "Size of overall appeal site (" })
- .fill("1");
- await page
- .getByRole("textbox", { name: "Size of overall appeal site (" })
- .press("Tab");
- await page
- .getByRole("textbox", { name: "What is the area of floor" })
- .fill("1");
- await page
- .getByRole("textbox", { name: "What is the area of floor" })
- .press("Tab");
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("Certificate A - (for sole").click();
- await page.getByText("(a) None of the land to which").click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("No").first().click();
- await page.getByText("No").nth(1).click();
- await page.getByText("No").nth(2).click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("No").first().click();
- await page.getByRole("button", { name: "Continue" }).click();
- // await page
- // .getByRole("paragraph")
- // .filter({ hasText: /^$/ })
- // .click();
- await page.locator(".ql-editor").fill("something here");
- await page.getByText("No").nth(1).click();
- await page
- .getByLabel("What procedure would you like")
- .selectOption("846040000");
- await page.getByText("No").nth(3).click();
- await page.getByText("No").nth(4).click();
- await page.getByText("YesNo").nth(2).click();
- await page.getByRole("button", { name: "Continue" }).click();
- // upload files to statement of case
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#pinswg_fileUpload");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Submit" }).click();
- await page
- .getByRole("checkbox", { name: "I wish to download a copy of the form" })
- .check();
- await page
- .getByRole("checkbox", { name: "I confirm that all sections" })
- .check();
- await page.getByText("Submit appeal").click();
- await page.getByRole("link", { name: "Home" }).click();
- await page.goto("/");
- await page.waitForTimeout(20000);
-});
diff --git a/pwe2e/tests/loggedin/raiserep.spec.js b/pwe2e/tests/loggedin/raiserep.spec.js
deleted file mode 100644
index 08aaac1e..00000000
--- a/pwe2e/tests/loggedin/raiserep.spec.js
+++ /dev/null
@@ -1,729 +0,0 @@
-import { test, expect } from "@playwright/test";
-import {
- login,
- loginAgent,
- generatePlanningText,
- loginLPA,
- loginIP,
-} from "../../helpers";
-import path from "path";
-
-const today = new Date();
-
-// Add ordinal (st, nd, rd, th)
-const day = today.getDate();
-const ordinal = (n) => {
- if (n > 3 && n < 21) return "th";
- switch (n % 10) {
- case 1:
- return "st";
- case 2:
- return "nd";
- case 3:
- return "rd";
- default:
- return "th";
- }
-};
-const weekday = today.toLocaleDateString("en-GB", { weekday: "long" });
-const month = today.toLocaleDateString("en-GB", { month: "long" });
-
-const finalDate = `${weekday}, ${month} ${day}${ordinal(day)}`;
-
-const finalCommentsCase = process.env.FINAL_COMMENTS;
-const statementCase = process.env.STATEMENT;
-const questionnaireCase = process.env.QUESTIONNAIRE;
-const consultationCase = process.env.CONSULTATION;
-
-test("Raise Final Comments representation as an Appellant", async ({
- page,
-}) => {
- await login(page);
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- console.log("Value to fill:", finalCommentsCase);
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(finalCommentsCase);
- await page.getByRole("button", { name: "Submit search" }).click();
- // await page
- // .getByRole("link", { name: "DNS3276735 - Gaerwen Wind Farm (test)" })
- // .click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Appellant" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("radio", { name: "Final comments" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page
- .getByRole("group")
- .locator("div")
- .filter({ hasText: "Please note that all" })
- .locator("div")
- .nth(3)
- .fill("s");
- await page
- .locator("div")
- .filter({ hasText: /^s$/ })
- .nth(2)
- .fill("some text to go here.....");
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise Final Comments representation as an Interested Party", async ({
- page,
-}) => {
- await loginIP(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(finalCommentsCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Interested Party" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("radio", { name: "Final comments" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page.locator(".ql-editor").fill(generatePlanningText(5));
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise Statement representation as an Interested Party", async ({
- page,
-}) => {
- await loginIP(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(statementCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Interested Party" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("radio", { name: "Statement" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page.locator(".ql-editor").fill(generatePlanningText(5));
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise Consultation Response as an Interested Party", async ({ page }) => {
- await loginIP(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(consultationCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page
- .getByRole("link", { name: "Submit a Consultation Response" })
- .click();
-
- await page.getByRole("radio", { name: "Interested Party" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("radio", { name: "Consultation Response" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page.locator(".ql-editor").fill(generatePlanningText(5));
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise LIR as an Interested Party", async ({ page }) => {
- await loginIP(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(consultationCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page
- .getByRole("link", { name: "Submit a Consultation Response" })
- .click();
-
- await page.getByRole("radio", { name: "Interested Party" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("radio", { name: "Local Impact Report" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise MIR as an Interested Party", async ({ page }) => {
- await loginIP(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(consultationCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page
- .getByRole("link", { name: "Submit a Consultation Response" })
- .click();
-
- await page.getByRole("radio", { name: "Interested Party" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("radio", { name: "Marine Impact Report" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise Final Comments representation as an Agent", async ({ page }) => {
- await loginAgent(page);
- //raise rep
-
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
-
- if (await acceptButton.isVisible()) {
- await acceptButton.click();
- }
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(finalCommentsCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Agent" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("radio", { name: "Final comments" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
-
- await page.locator(".ql-editor").fill(generatePlanningText(4));
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise Statement representation as an Agent", async ({ page }) => {
- await loginAgent(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(statementCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Agent" }).check();
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("radio", { name: "Statement" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByText("Yes").click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .click();
- await page
- .getByRole("textbox", { name: "Enter the name of the company" })
- .fill("Big Company");
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page.locator(".ql-editor").fill(generatePlanningText(5));
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise questionnaire as an LPA", async ({ page }) => {
- await loginLPA(page);
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(questionnaireCase);
- await page.getByRole("textbox", { name: "Use the case reference," }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference," })
- .fill(questionnaireCase);
- await page.getByRole("button", { name: "Submit Search" }).click();
- await page.getByRole("link", { name: questionnaireCase }).click();
- // await page.getByRole("button", { name: "Submit search" }).click();
-
- //await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Questionnaire" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("combobox").selectOption("Written representations");
- await page.getByText("No").first().click();
- await page.getByText("No").nth(1).click();
- await page.getByText("No").nth(2).click();
- await page.getByText("Yes").nth(2).click();
- await page.getByText("No").nth(3).click();
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- // await page.locator(".ql-editor").fill(generatePlanningText(2));
- // await page
- // .locator("div")
- // .filter({ hasText: /^w$/ })
- // .nth(2)
- // .fill(generatePlanningText(2));
- await page.getByRole("button", { name: "Continue" }).click();
- await page.locator(".ql-editor").first().fill(generatePlanningText(2));
- await page.locator(".ql-editor").nth(1).fill(generatePlanningText(2));
- await page.locator(".ql-editor").nth(2).fill(generatePlanningText(2));
-
- // // await page.getByRole("paragraph").nth(4).click();
- // await page
- // .locator(".ql-editor.ql-blank")
- // .first()
- // .fill(generatePlanningText(2));
- // await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- // await page
- // .locator(".ql-editor.ql-blank")
- // .first()
- // .fill(generatePlanningText(2));
- // await page.locator(".ql-editor.ql-blank").fill("w e");
- // await page
- // .locator("div")
- // .filter({ hasText: /^w e$/ })
- // .nth(2)
- // .fill(generatePlanningText(2));
- // await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- // await page
- // .locator("div")
- // .filter({ hasText: /^w e$/ })
- // .nth(2)
- // .fill(generatePlanningText(2));
- await page.getByText("No", { exact: true }).first().click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("No").first().click();
- await page.getByText("No").nth(1).click();
- await page.getByText("No").nth(2).click();
- await page.getByText("No").nth(3).click();
- await page.getByText("No").nth(4).click();
- await page.getByText("No").nth(5).click();
- await page
- .locator(
- "div:nth-child(8) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label",
- )
- .click();
- await page
- .locator(
- "div:nth-child(9) > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-label",
- )
- .click();
- await page
- .locator(
- "div:nth-child(10) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label",
- )
- .click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("No").nth(2).click();
- await page.getByText("No").nth(3).click();
- await page.getByText("No").nth(5).click();
- await page.getByText("No", { exact: true }).nth(3).click();
- await page.getByText("No", { exact: true }).nth(4).click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("Yes").first().click();
- await page.getByText("Yes").nth(1).click();
- await page.getByText("No", { exact: true }).nth(2).click();
- await page.getByText("Yes").nth(2).click();
- await page.getByText("No", { exact: true }).nth(3).click();
- await page.getByText("No", { exact: true }).nth(4).click();
- await page.getByText("No", { exact: true }).nth(5).click();
- await page
- .locator(
- "div:nth-child(9) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label",
- )
- .click();
- await page
- .locator(
- "div:nth-child(10) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label",
- )
- .click();
- await page.getByRole("button", { name: "Continue" }).click();
- // await page.getByText("Drag and drop your files here").click();
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("textbox", { name: "Signed" }).click();
- await page.getByRole("textbox", { name: "Signed" }).fill("Bob Bob");
- await page.getByRole("textbox", { name: "Date" }).click();
- await page.getByRole("option", { name: `Choose ${finalDate}` }).click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByText("I wish to download a copy of").click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- const downloadPromise = page.waitForEvent("download");
- await page.getByRole("button", { name: "Continue" }).click();
- const download = await downloadPromise;
- await page.getByRole("link", { name: "Continue" }).click();
-
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise Statement representation as an LPA", async ({ page }) => {
- await loginLPA(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(statementCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page.getByRole("link", { name: "Make representation" }).click();
-
- await page.getByRole("radio", { name: "Statement" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page.locator(".ql-editor").fill(generatePlanningText(5));
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Raise LIR as an LPA", async ({ page }) => {
- await loginLPA(page);
- //raise rep
-
- await page.getByRole("textbox", { name: "Use the case reference" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference" })
- .fill(consultationCase);
- await page.getByRole("button", { name: "Submit search" }).click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- await page
- .getByRole("link", { name: "Submit a Consultation Response" })
- .click();
-
- await page.getByRole("radio", { name: "Local Impact Report" }).check();
- await page.getByRole("button", { name: "Continue" }).click();
-
- await page.getByRole("paragraph").filter({ hasText: /^$/ }).click();
- await page.locator(".ql-editor").fill(generatePlanningText(5));
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const fileInput = page.locator("#representationDocuments");
-
- await fileInput.setInputFiles(files);
- const uploadedFiles = page.locator("h4", { hasText: "Uploaded files" });
-
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
-
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByRole("checkbox", { name: "I confirm I have read the" })
- .check();
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("link", { name: "Continue" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
-
-test("Open Saved Rep as an Interested Party", async ({ page }) => {
- await loginIP(page);
- //raise rep
-
- const firstCaseLink = page
- .locator("#my-representations-card .govuk-link--no-underline")
- .first();
-
- await firstCaseLink.click();
-
- await page.getByRole("button", { name: "Save and exit" }).click();
- await page.goto("/");
-
- await page.waitForTimeout(2000);
-});
diff --git a/pwe2e/tests/loggedin/s78newappeal.spec.js b/pwe2e/tests/loggedin/s78newappeal.spec.js
deleted file mode 100644
index 6f9629ea..00000000
--- a/pwe2e/tests/loggedin/s78newappeal.spec.js
+++ /dev/null
@@ -1,377 +0,0 @@
-import { test, expect } from "@playwright/test";
-import path from "path";
-import * as XLSX from "xlsx";
-
-import {
- login,
- fillYesNoConditional,
- fillQuillEditor,
- toDDMMYYYY,
-} from "../../helpers";
-
-const workbook = XLSX.readFile("./testFiles/newappeals_s78.xlsx");
-const sheetName = workbook.SheetNames[0];
-const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {
- defval: "",
- cellDates: true,
-});
-
-// console.log("sheetName :", sheetName);
-// console.log("Loaded rows:", data);
-
-data.forEach((row, index) => {
- test(`Import new appeal for ${row["Appellant / Organisation"]}`, async ({
- page,
- }) => {
- await login(page);
-
- await page.getByRole("link", { name: "Make a new appeal" }).click();
- await page
- .getByRole("textbox", { name: "Appellant or organisation's" })
- .click();
- await page
- .getByRole("textbox", { name: "Appellant or organisation's" })
- .fill(row["Appellant / Organisation"]);
-
- await page
- .getByRole("radio", { name: row["Appellant / Agent Radio Button"] })
- .click();
-
- await page.locator("#pinswg_appellantfirstname").fill(row["First Name"]);
- await page.locator("#pinswg_appellantlastname").fill(row["Last Name"]);
- await page.locator("#pinswg_appellantaddress").fill(row["Address"]);
- await page
- .locator("#pinswg_appellantemailaddress")
- .fill(row["Email Address"]);
- await page
- .locator("#pinswg_appellantphonenumber")
- .fill(row["Telephone Number"]);
-
- // Excel value: "English" or "Welsh"
- const languageText = row["Language Preference Radio Button"]?.trim();
-
- // Map Excel text to radio button value
- const radioValueLang = languageText === "Welsh" ? "846040001" : "846040000";
-
- // Select the radio by name and value
- await page
- .locator(
- `input[name="pinswg_languagepreference"][value="${radioValueLang}"]`
- )
- .check();
-
- if (row["Appellant / Agent Radio Button"] == "Agent") {
- await page.locator("#pinswg_agentcompanyname").fill(row["Company Name"]);
- await page
- .locator("#pinswg_agentreference")
- .fill(row["Agent's Reference"]);
-
- await page.locator("#pinswg_agentfirstname").fill(row["First Name_1"]);
- await page.locator("#pinswg_agentlastname").fill(row["Last Name_1"]);
- await page.locator("#pinswg_agentaddress").fill(row["Address_1"]);
- await page
- .locator("#pinswg_agentemailaddress")
- .fill(row["Email Address_1"]);
- await page
- .locator("#pinswg_agentphonenumber")
- .fill(row["Telephone Number_1"]);
-
- const agentLanguageText =
- row["Agent Language Preference Radio Button"]?.trim();
- const agentRadioValue =
- agentLanguageText === "Welsh" ? "846040001" : "846040000";
-
- await page
- .locator(
- `input[name="pinswg_agentlanguagepreference"][value="${agentRadioValue}"]`
- )
- .check();
- }
- await page.getByText("I confirm that I am making an").click();
- await page.getByRole("button", { name: "Continue" }).click();
- await page
- .getByLabel("Select your Local Planning")
- .selectOption({ label: row["Select LPA"] });
- await page.getByLabel("Select a case type").selectOption("846040000");
- await page.getByRole("button", { name: "Continue" }).click();
- await page.getByRole("button", { name: "Continue" }).click();
-
- const step2 = page.locator('[aria-controls="step-panel-appeal-details"]');
- await step2.click();
-
- await page
- .getByRole("textbox", { name: "Development description" })
- .click();
- await page
- .getByRole("textbox", { name: "Development description" })
- .fill(row["Development Description"]);
- await page.getByText("No", { exact: true }).click();
- await page
- .getByRole("textbox", { name: "LPA's application reference" })
- .fill(row["LPA's Application Ref Num"]);
-
- await page
- .locator("#pinswg_dateofapplication")
- .fill(toDDMMYYYY(row["App Form Dated"]));
- await page
- .getByLabel("Reason for appeal")
- .selectOption({ label: row["Reason for Appeal"] });
-
- await page.getByRole("textbox", { name: "Site address line 1" }).click();
- await page
- .getByRole("textbox", { name: "Site address line 1" })
- .fill(row["Site Address Line 1"]);
- await page
- .getByRole("textbox", { name: "Site address line 2" })
- .fill(row["Site Address Line 2"]);
- await page
- .getByRole("textbox", { name: "Site address town" })
- .fill(row["Site Address Town"]);
- await page
- .getByRole("textbox", { name: "Site address county" })
- .fill(row["Site Address County"]);
-
- await page
- .getByRole("textbox", { name: "Site address postcode" })
- .fill(row["Site Address Postcode"]);
-
- await page
- .getByRole("textbox", { name: "Size of overall appeal site (" })
- .fill(String(row["Size of Overall Appeal Site"]));
-
- await page
- .getByRole("textbox", { name: "What is the area of floor" })
- .fill(String(row["Floor Space (Sq Metres)"]));
- await page.getByRole("button", { name: "Continue" }).click();
-
- // Ownership Certificate selection and conditional fields
- const ownershipMap = {
- "Certificate A": "846040001",
- "Certificate B": "846040002",
- "Certificate C": "846040003",
- "Certificate D": "846040003", // C and D share same option
- };
-
- const cert = row["Ownership Certificate"]?.trim();
- const value = ownershipMap[cert];
-
- if (!value) throw new Error(`Unknown ownership certificate: ${cert}`);
-
- // Select the certificate radio
- await page
- .locator(`input[name="pinswg_ownershipcertificate"][value="${value}"]`)
- .check();
-
- // Conditional fields for Certificate B
- if (cert === "Certificate B") {
- // Wait for Owner Name input to appear (dynamic rendering)
- const ownerInput = page.locator(
- 'input[id^="pinswg_owners"][id$=".pinswg_owners"]'
- );
- await ownerInput.waitFor({ state: "visible", timeout: 5000 });
- await ownerInput.fill(row["Owner Name"] || "");
-
- // Wait for Date Served input to appear
- const dateServedInput = page.locator(
- ".react-datepicker__input-container input"
- );
- await dateServedInput.waitFor({ state: "visible", timeout: 5000 });
- await dateServedInput.fill(toDDMMYYYY(row["Date Served"]) || "");
- }
-
- // Ownership Certificate selection and conditional fields
- const agHoldingMap = {
- "(a)": "846040002",
- "(b) (i)": "846040001",
- "(b) (ii)": "846040000",
- };
-
- const agriculturalHolding = row["Agricultural Holding"]?.trim();
- const agValue = agHoldingMap[agriculturalHolding];
-
- if (!agValue) throw new Error(`Unknown ownership certificate: ${cert}`);
-
- // Select the certificate radio
- await page
- .locator(`input[name="pinswg_agriculturalholding"][value="${agValue}"]`)
- .check();
-
- // Conditional fields for b (ii)
- if (agriculturalHolding === "(b) (ii)") {
- // Wait for Owner Name input to appear (dynamic rendering)
- const tenantInput = page.locator(
- 'input[id^="pinswg_agriculturaltenantname"][id$=".pinswg_agriculturaltenantname"]'
- );
- await tenantInput.waitFor({ state: "visible", timeout: 5000 });
- await tenantInput.fill(row["Tenant Name"] || "");
-
- // Wait for Date Served input to appear
- const dateServedInput = page.locator(
- ".react-datepicker__input-container input"
- );
- await dateServedInput.waitFor({ state: "visible", timeout: 5000 });
- await dateServedInput.fill(toDDMMYYYY(row["Date Served_1"]) || "");
- }
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- // Site viewable from road
- await fillYesNoConditional(
- page,
- "pinswg_siteviewablefromroad",
- row["See Relevant Parts?"],
- null,
- null
- );
-
- // Inspector needed on site
- await fillYesNoConditional(
- page,
- "pinswg_inspectorneededonsite",
- row["Essential to Enter?"],
- "#pinswg_whyisinspectorneededonsite",
- row["Please Explain (Enter)"]
- );
-
- // Health & safety issues
- await fillYesNoConditional(
- page,
- "pinswg_healthandsafetyissuesonsite",
- row["Any H&S Issues?"],
- "#pinswg_outlinehealthandsafetyissuesonsite",
- row["Set out H&S Issues"]
- );
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- // Step 5 Other Appeals
-
- await fillYesNoConditional(
- page,
- "pinswg_additionalappealsmade", // radio name
- row["Any Other Appeals?"], // "Y" or blank from Excel
- "#pinswg_additionalappealsmadedetails", // Quill editor selector
- row["Other Appeal Details"], // text to fill
- false // flag that it's a Quill editor
- );
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- // Step 6 Submission of Case
-
- // Q.1
- const subnissionOfCaseInput = page.locator(".ql-editor");
- await subnissionOfCaseInput.waitFor({ state: "visible", timeout: 100000 });
- await subnissionOfCaseInput.fill(row["Submit Statement of Case"]);
-
- // Q.2
- const attachSocValue = (row["Attached Separate Case Doc?"] || "")
- .trim()
- .toUpperCase();
-
- const radioValue = attachSocValue === "Y" ? "true" : "false";
-
- // Select the radio
- await page
- .locator(`input[name="pinswg_attachsoc"][value="${radioValue}"]`)
- .check();
-
- // Q.3
- const procedureValue = row["What Procedure?"]?.trim(); // e.g., "Written representation"
-
- // Wait for the dropdown to appear
- const procedureSelect = page.locator("#pinswg_procedure");
- await procedureSelect.waitFor({ state: "visible", timeout: 5000 });
-
- // Select by label (the visible text)
- await procedureSelect.selectOption({ label: procedureValue });
-
- // If not "Written representation", fill the explanation box
- if (
- procedureValue &&
- procedureValue.toLowerCase() !== "written representation"
- ) {
- const explanation =
- row["Procedure Explanation"] ||
- "Default explanation: A hearing/inquiry is required due to case complexity and witnesses.";
-
- const textArea = page.locator("#pinswg_chosenprocedureexplanation");
- await textArea.waitFor({ state: "visible", timeout: 5000 });
- await textArea.fill(explanation);
- }
-
- // Q.4
- await fillYesNoConditional(
- page,
- "pinswg_costappliedforindicator", // radio name
- row["Cost Applied For"], // "Y" or blank from Excel
- ".ql-editor", // Quill editor selector
- row["Cost Application"], // text to fill
- true // flag that it's a Quill editor
- );
-
- // Q.5
- await fillYesNoConditional(
- page,
- "pinswg_s106unilateralsubmitted", // radio name
- row["Submit S106?"] // "Y" or blank from Excel
- );
-
- await page.getByRole("button", { name: "Continue" }).click();
-
- // Step 7 Upload Documents
-
- const files = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- path.resolve(__dirname, "../../testFiles/file2.pdf"),
- ];
-
- const firstInputFiles = [
- path.resolve(__dirname, "../../testFiles/file1.pdf"),
- ];
-
- const fileInputs = [
- "#pinswg_fileUpload",
- "#pinswg_fileUpload1",
- "#pinswg_fileUpload2",
- "#pinswg_fileUpload3",
- "#pinswg_fileUpload4",
- "#pinswg_fileUpload5",
- "#pinswg_fileUpload6",
- "#pinswg_fileUpload7",
- "#pinswg_fileUpload8",
- "#pinswg_fileUpload9",
- "#pinswg_fileUpload10",
- "#pinswg_fileUpload11",
- "#pinswg_fileUpload12",
- "#pinswg_fileUpload13",
- "#pinswg_fileUpload14",
- "#pinswg_fileUpload15",
- ];
-
- for (let i = 0; i < fileInputs.length; i++) {
- const selector = fileInputs[i];
- if (i === 0) {
- // First input gets its specific files
- await page.locator(selector).setInputFiles(firstInputFiles);
- } else {
- // All other inputs get the common files
- await page.locator(selector).setInputFiles(files);
- }
- const uploadedFiles = page
- .locator("h4", { hasText: "Uploaded files" })
- .first();
- await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
- }
-
- await page.getByRole("button", { name: "Submit" }).click();
-
- // Check and Confirm
- await page
- .getByRole("checkbox", { name: "I confirm that all sections" })
- .check();
- await page.getByText("Submit appeal").click();
-
- await page.waitForTimeout(20000);
- });
-});
diff --git a/pwe2e/tests/loggedout/downloadFile.spec.js b/pwe2e/tests/loggedout/downloadFile.spec.js
deleted file mode 100644
index 28d654e3..00000000
--- a/pwe2e/tests/loggedout/downloadFile.spec.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { test, expect } from "@playwright/test";
-
-test("Download a file", async ({ page }) => {
- await page.goto("/");
- await page.getByRole("button", { name: "Accept cookies" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference or DNS" })
- .click();
- await page
- .getByRole("textbox", { name: "Use the case reference or DNS" })
- .fill("gaerwen");
- await page.getByRole("button", { name: "Submit search" }).click();
- // await page
- // .getByRole("link", { name: "DNS3276735 - Gaerwen Wind Farm (test)" })
- // .click();
-
- await page.locator("dd a.govuk-link--no-underline").first().click();
-
- const downloadPromise = page.waitForEvent("download");
-
- await page.locator(".documentLink").first().click();
-
- const download = await downloadPromise;
- await page.getByText("Download complete!").click();
- await page.getByRole("link", { name: "Home" }).click();
-});
diff --git a/pwe2e/tests/loggedout/homepageLinks.spec.js b/pwe2e/tests/loggedout/homepageLinks.spec.js
deleted file mode 100644
index 15c945e9..00000000
--- a/pwe2e/tests/loggedout/homepageLinks.spec.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { test, expect } from "@playwright/test";
-import { handleSearchResults } from "../../helpers/index";
-
-test("Check for DNS applications", async ({ page }) => {
- await page.goto("/");
- await page.getByRole("button", { name: "Accept cookies" }).click();
- await page.getByRole("link", { name: "View all DNS applications" }).click();
-
- async function handleSearchResults(page) {
- const results = page.locator("dd a.govuk-link--no-underline");
-
- await Promise.race([
- results.first().waitFor({ state: "visible", timeout: 15000 }),
- ]);
-
- if ((await results.count()) > 0) {
- await results.first().click({ timeout: 15000 });
- await expect(page.locator("#main-content")).toContainText("Reference:", {
- timeout: 15000,
- });
- return "clicked";
- } else if ((await noResultsMessage.count()) > 0) {
- console.log("ℹ️ No results found. Test passes.");
- return "no-results";
- } else {
- throw new Error(
- "⚠️ Unexpected search page state: neither results nor zero-results message found."
- );
- }
- }
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for DNS":`, outcome);
-});
diff --git a/pwe2e/tests/loggedout/searches.spec.js b/pwe2e/tests/loggedout/searches.spec.js
deleted file mode 100644
index 4966be7c..00000000
--- a/pwe2e/tests/loggedout/searches.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-import { test, expect } from "@playwright/test";
-import * as XLSX from "xlsx";
-import { handleSearchResults } from "../../helpers/index";
-test.use({ headless: true });
-
-test("Basic search", async ({ page }) => {
- await page.goto("/");
- await page.getByRole("button", { name: "Accept cookies" }).click();
- await page
- .getByRole("textbox", { name: "Use the case reference or DNS" })
- .click();
- await page
- .getByRole("textbox", { name: "Use the case reference or DNS" })
- .fill("cas-");
- await page.getByRole("button", { name: "Submit search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for basic search":`, outcome);
-});
-
-const workbook = XLSX.readFile("./testFiles/appealList.xlsx");
-const sheetName = workbook.SheetNames[0];
-const rawData = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {
- defval: "",
-});
-
-const data = rawData
- .map((row) => ({
- Values: row["Values"]?.trim(),
- AppealTypes: row["AppealType"]?.trim(),
- }))
- .filter((r) => r.Values && r.AppealTypes);
-
-test.describe("Advanced Search Appeal Types", () => {
- if (data.length === 0) {
- test("No data found in spreadsheet", async () => {
- console.warn("No valid rows found in appealList.xlsx");
- });
- }
-
- data.forEach((row, index) => {
- test(`Advanced search - ${row.AppealTypes} #${index + 1}`, async ({
- page,
- }) => {
- await page.goto("/");
-
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
-
- await page.getByRole("link", { name: "Advanced search" }).click();
- await page.getByLabel("Select a case type").selectOption(row.Values);
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for "${row.AppealTypes}":`, outcome);
- });
- });
-});
-
-const sheetName2 = workbook.SheetNames[1];
-const rawData2 = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName2], {
- defval: "",
-});
-
-const data2 = rawData2
- .map((row) => ({
- Values: row["Values"]?.trim(),
- LPA: row["LPA"]?.trim(),
- }))
- .filter((r) => r.Values && r.LPA);
-
-test.describe("Advanced Search LPA", () => {
- if (data2.length === 0) {
- test("No data found in spreadsheet", async () => {
- console.warn("⚠️ No valid rows found in lpaList.xlsx");
- });
- }
-
- data2.forEach((row, index) => {
- test(`Advanced search LPA - ${row.LPA} #${index + 1}`, async ({ page }) => {
- await page.goto("/");
-
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
-
- await page.getByRole("link", { name: "Advanced search" }).click();
- await page
- .getByLabel("Local Planning Authority")
- .selectOption(row.Values);
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for "${row.LPA}":`, outcome);
- });
- });
-});
-
-const sheetName3 = workbook.SheetNames[2];
-const rawData3 = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName3], {
- defval: "",
-});
-
-const data3 = rawData3
- .map((row) => ({
- Values: row["Values"],
- Status: row["Status"]?.trim(),
- }))
- .filter((r) => r.Values && r.Status);
-
-test.describe("Advanced Search Case Status", () => {
- if (data3.length === 0) {
- test("No data found in spreadsheet", async () => {
- console.warn("⚠️ No valid rows found in lpaList.xlsx");
- });
- }
-
- data3.forEach((row, index) => {
- test(`Advanced search Case Status - ${row.Status} #${index + 1}`, async ({
- page,
- }) => {
- await page.goto("/");
-
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
-
- await page.getByRole("link", { name: "Advanced search" }).click();
- await page.getByLabel("Case Status").selectOption(String(row.Values));
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for "${row.Status}":`, outcome);
- });
- });
-});
-
-test.describe("Address search", () => {
- test("Address search AddressLine1", async ({ page }) => {
- await page.goto("/");
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
- await page.getByRole("link", { name: "Address search" }).click();
- await page.locator("#addressline1").click();
- await page.locator("#addressline1").fill("street");
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for AddressLine1":`, outcome);
- });
- test("Address search Town", async ({ page }) => {
- await page.goto("/");
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
- await page.getByRole("link", { name: "Address search" }).click();
- await page.locator("#town").click();
- await page.locator("#town").fill("Cardiff");
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for Town":`, outcome);
- });
- test("Address search County", async ({ page }) => {
- await page.goto("/");
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
- await page.getByRole("link", { name: "Address search" }).click();
- await page.locator("#county").click();
- await page.locator("#county").fill("Cardiff");
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for County":`, outcome);
- });
- test("Address search Postcode", async ({ page }) => {
- await page.goto("/");
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
- await page.getByRole("link", { name: "Address search" }).click();
- await page.locator("#postcode").click();
- await page.locator("#postcode").fill("cf24");
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for Postcode":`, outcome);
- });
- test("Address search Appellant or Applicant", async ({ page }) => {
- await page.goto("/");
- const acceptButton = page.getByRole("button", { name: "Accept cookies" });
- if (await acceptButton.isVisible()) await acceptButton.click();
- await page.getByRole("link", { name: "Address search" }).click();
- await page.locator("#appellantname").click();
- await page.locator("#appellantname").fill("David");
- await page.locator("#addressline1").click();
- await page.locator("#addressline1").fill("Street");
- await page.getByRole("button", { name: "Search" }).click();
-
- // Handle search results safely
- const outcome = await handleSearchResults(page);
- console.log(`Search outcome for Postcode":`, outcome);
- });
-});
diff --git a/pwe2e/tests/test-1.spec.ts b/pwe2e/tests/test-1.spec.ts
deleted file mode 100644
index b915e038..00000000
--- a/pwe2e/tests/test-1.spec.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { test, expect } from '@playwright/test';
-
-test('test', async ({ page }) => {
- await page.locator('body').click();
- await page.goto('http://localhost:3000/auth/error?error=Verification
- await page.getByRole('link', { name: 'Home', exact: true }).click();
- await page.goto('http://localhost:3000/myportal');
- await page.goto('http://localhost:3000/myportal/case/CAS-01085-K4R4X0?q=CAS-01085-K4R4X0&adv=false');
- await page.getByRole('link', { name: 'Make representation' }).click();
- await page.getByRole('combobox').selectOption('Questionnaire');
- await page.getByRole('combobox').selectOption('Written representations');
- await page.getByText('No').first().click();
- await page.getByText('No').nth(1).click();
- await page.getByText('No').nth(2).click();
- await page.getByText('Yes').nth(2).click();
- await page.getByText('No').nth(3).click();
- await page.getByRole('paragraph').filter({ hasText: /^$/ }).click();
- await page.locator('.ql-editor').fill('w');
- await page.locator('div').filter({ hasText: /^w$/ }).nth(2).fill('wdwdwdwdwdw ');
- await page.getByRole('button', { name: 'Continue' }).click();
- await page.locator('.ql-editor').first().click();
- await page.locator('.ql-editor').first().fill('wwwqwqeq wefqewr qwerq');
- await page.getByRole('paragraph').nth(4).click();
- await page.locator('.ql-editor.ql-blank').first().fill('qweqwe qwrqrt qwe qweqwqwe');
- await page.getByRole('paragraph').filter({ hasText: /^$/ }).click();
- await page.locator('.ql-editor.ql-blank').first().fill('qweqwe qwrqrt qwe qweqwqweq');
- await page.locator('.ql-editor.ql-blank').fill('w e');
- await page.locator('div').filter({ hasText: /^w e$/ }).nth(2).fill('w eqewrqwe q');
- await page.getByRole('paragraph').filter({ hasText: /^$/ }).click();
- await page.locator('div').filter({ hasText: /^w e$/ }).nth(2).fill('w eqewrqwe qweqwe ');
- await page.getByText('No').nth(1).click();
- await page.getByText('No').nth(2).click();
- await page.getByText('No').nth(3).click();
- await page.getByText('No').nth(4).click();
- await page.getByText('No').nth(5).click();
- await page.locator('div:nth-child(8) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label').click();
- await page.locator('div:nth-child(9) > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-label').click();
- await page.locator('div:nth-child(10) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label').click();
- await page.getByRole('button', { name: 'Continue' }).click();
- await page.getByText('No').nth(2).click();
- await page.getByText('No').nth(3).click();
- await page.getByText('No').nth(5).click();
- await page.getByText('No', { exact: true }).nth(3).click();
- await page.getByText('No', { exact: true }).nth(4).click();
- await page.getByRole('button', { name: 'Continue' }).click();
- await page.getByRole('group', { name: '26. A copy of the applicant’s' }).click();
- await page.getByText('No').nth(4).click();
- await page.getByText('Yes').nth(1).click();
- await page.getByText('No', { exact: true }).nth(2).click();
- await page.getByText('Yes').nth(2).click();
- await page.getByText('No', { exact: true }).nth(3).click();
- await page.getByText('No', { exact: true }).nth(4).click();
- await page.getByText('No', { exact: true }).nth(5).click();
- await page.locator('div:nth-child(9) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label').click();
- await page.locator('div:nth-child(10) > .govuk-form-group > .govuk-fieldset > .govuk-radios > div:nth-child(2) > .govuk-radios__item > .govuk-label').click();
- await page.getByRole('button', { name: 'Continue' }).click();
- await page.getByText('Drag and drop your files here').click();
- await page.getByRole('button', { name: 'Continue' }).click();
- await page.getByRole('textbox', { name: 'Signed' }).click();
- await page.getByRole('textbox', { name: 'Signed' }).fill('Bob Bob');
- await page.getByRole('textbox', { name: 'Date' }).click();
- await page.getByRole('option', { name: 'Choose Tuesday, April 14th,' }).click();
- await page.getByRole('button', { name: 'Continue' }).click();
- await page.getByText('I wish to download a copy of').click();
- await page.getByRole('checkbox', { name: 'I confirm I have read the' }).check();
- const downloadPromise = page.waitForEvent('download');
- await page.getByRole('button', { name: 'Continue' }).click();
- const download = await downloadPromise;
- await page.getByRole('link', { name: 'Continue' }).click();
- await page.goto('http://localhost:3000/myportal');');
-});
\ No newline at end of file
diff --git a/pwe2e/tests/test-2.spec.ts b/pwe2e/tests/test-2.spec.ts
deleted file mode 100644
index 5b3d48cf..00000000
--- a/pwe2e/tests/test-2.spec.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { test, expect } from '@playwright/test';
-
-test('test', async ({ page }) => {
- // Recording...
-});
\ No newline at end of file
diff --git a/pwe2e/tests/test-3.spec.ts b/pwe2e/tests/test-3.spec.ts
deleted file mode 100644
index 9f3b9b0e..00000000
--- a/pwe2e/tests/test-3.spec.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { test, expect } from "@playwright/test";
-
-test("test", async ({ page }) => {
- // Recording...
- await page.goto("http://localhost:3000/auth/error?error=Verification");
- await page.getByRole("link", { name: "Home", exact: true }).click();
- await page.goto("http://localhost:3000/myportal");
- await page.getByRole("heading", { name: "Representations awaiting" }).click();
-
- const containerLink = page
- .locator("div", { hasText: "Representations awaiting" })
- .locator("a")
- .first()
- .click();
-
- await page.getByText("CAS-01085-K4R4X0").first().click();
- await page.goto(
- "http://localhost:3000/myportal/representation?case=CAS-01085-K4R4X0&state=edit&created=2026-04-15-12%3A32%3A23_-_LPA_-_Questionnaire_-_CardiffCouncil",
- );
- await page.getByRole("button", { name: "Save and exit" }).click();
- await page.goto("http://localhost:3000/myportal");
-});
diff --git a/styles/sass/styles.scss b/styles/sass/styles.scss
index 20a3ce6c..253da49d 100644
--- a/styles/sass/styles.scss
+++ b/styles/sass/styles.scss
@@ -1,4 +1,4 @@
-@import "node_modules/govuk-frontend/dist/govuk/all";
+@import "govuk-frontend/dist/govuk/all";
// Add extra styles here, or re-organise the Sass files in whichever way makes most sense to you
@import "welshgov/_variables";
diff --git a/tsconfig.json b/tsconfig.json
index 8a5672e6..8f6d8664 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -15,7 +15,7 @@
"moduleResolution": "Node16",
"resolveJsonModule": true,
"isolatedModules": true,
- "jsx": "preserve"
+ "jsx": "react-jsx"
},
"include": [
"next-env.d.ts",