From 2a3d7bcad9b5617bcfa00092f3adc6de43bfb7ef Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Tue, 1 Jul 2025 11:27:59 +0200
Subject: [PATCH 01/30] 4565: Added playwright github action
---
.github/workflows/pr.yaml | 28 ++++++++++++++++++++++++++++
CHANGELOG.md | 1 +
2 files changed, 29 insertions(+)
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 87882f18..f54def6a 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -263,3 +263,31 @@ jobs:
- name: Check for changes in specifications (json)
run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.json
+
+ frontend-build-and-test:
+ name: Playwright
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup network
+ run: docker network create frontend
+
+ - name: Run playwright
+ env:
+ CI: 'true'
+ run: |
+ docker compose run --rm node npm install
+ docker compose run --rm node npm run install
+ docker compose run --rm playwright npx playwright install --with-deps
+ docker compose run --rm playwright npx playwright test --retries 3
+
+ - uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: playwright-report
+ path: playwright-report/
+ retention-days: 30
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91ad6d86..3e9902fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
* Added ADRs 008 and 009.
* Cleaned up Github Actions workflows.
* Updated PHP dependencies.
+* Added Playwright github action.
### NB! Prior to 3.x the project was split into separate repositories
From 8afd022f32550ecd7f8027a78af60f93131f3f21 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Tue, 1 Jul 2025 11:31:31 +0200
Subject: [PATCH 02/30] 4565: Fixed npm run build
---
.github/workflows/pr.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index f54def6a..04155328 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -281,7 +281,7 @@ jobs:
CI: 'true'
run: |
docker compose run --rm node npm install
- docker compose run --rm node npm run install
+ docker compose run --rm node npm run build
docker compose run --rm playwright npx playwright install --with-deps
docker compose run --rm playwright npx playwright test --retries 3
From b3e99c8b49dc83e4211dbf4bab47a3e9d5b95ac9 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Wed, 2 Jul 2025 17:50:51 +0200
Subject: [PATCH 03/30] 4565: Fixed playwright github setup. Added test readme.
Changed to @vitejs/plugin-react-oxc
---
.github/workflows/composer.yaml | 3 +-
.github/workflows/pr.yaml | 1 -
docker-compose.override.yml | 6 +-
docs/test.md | 45 ++++++
package-lock.json | 270 +++-----------------------------
package.json | 4 +-
playwright.config.ts | 6 +-
vite.config.js | 9 +-
8 files changed, 81 insertions(+), 263 deletions(-)
create mode 100644 docs/test.md
diff --git a/.github/workflows/composer.yaml b/.github/workflows/composer.yaml
index 1bdcc571..6e60167b 100644
--- a/.github/workflows/composer.yaml
+++ b/.github/workflows/composer.yaml
@@ -65,5 +65,4 @@ jobs:
- uses: actions/checkout@v4
- run: |
docker network create frontend
- docker compose run --rm phpfpm composer install
- docker compose run --rm phpfpm composer audit
+ docker compose run --rm phpfpm composer audit --locked
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 04155328..3e498363 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -282,7 +282,6 @@ jobs:
run: |
docker compose run --rm node npm install
docker compose run --rm node npm run build
- docker compose run --rm playwright npx playwright install --with-deps
docker compose run --rm playwright npx playwright test --retries 3
- uses: actions/upload-artifact@v4
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index a831755c..e4b15ad3 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -1,8 +1,4 @@
services:
- phpfpm:
- environment:
- - PHP_MEMORY_LIMIT=512M
-
nginx:
labels:
# HTTPS config - uncomment to enable redirect from :80 to :443
@@ -30,7 +26,7 @@ services:
playwright:
# https://playwright.dev/docs/docker
# This Playwright version should match the one in `package.json`.
- image: mcr.microsoft.com/playwright:v1.52.0
+ image: mcr.microsoft.com/playwright:v1.53.2-noble
networks:
- app
depends_on:
diff --git a/docs/test.md b/docs/test.md
new file mode 100644
index 00000000..1fb947d9
--- /dev/null
+++ b/docs/test.md
@@ -0,0 +1,45 @@
+# Test
+
+## Playwright
+
+To test the React apps we use playwright.
+
+### Updating Playwright
+
+It is important that the versions of the playwright container and the library imported in package.json align.
+
+See the `docker-compose.override.yml` playwright entry and the version imported in package.json.
+
+### Dev mode
+
+To run tests locally, there are a few options.
+
+To run from the developer machine:
+
+```shell
+BASE_URL="https://display.local.itkdev.dk" npx playwright test template
+```
+
+In interactive mode:
+
+```shell
+BASE_URL="https://display.local.itkdev.dk" npx playwright test template --ui
+```
+
+### Prod mode
+
+Another option is to run the tests on the built javascript assets through the playwright container.
+This is the option that runs in Github Actions.
+
+```shell
+# Stop the node container, to avoid Vite build dev assets.
+docker compose stop node
+
+# Build the assets
+docker compose run --rm node npm run build
+
+# Run the test
+docker compose run --rm playwright npx playwright test
+
+# To return to vite dev mode, restart the node container.
+```
diff --git a/package-lock.json b/package-lock.json
index 74f6a777..5a6cc0d9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -57,10 +57,10 @@
"ulid": "^2.3.0"
},
"devDependencies": {
- "@playwright/test": "^1.52.0",
+ "@playwright/test": "1.53.2",
"@reduxjs/toolkit": "^1.6.1",
"@vitejs/plugin-react": "^4.6.0",
- "@vitejs/plugin-react-swc": "^3.10.2",
+ "@vitejs/plugin-react-oxc": "^0.2.3",
"sass": "^1.88.9",
"typescript": "^4.4.2",
"vite": "npm:rolldown-vite@^7.0.3",
@@ -1721,13 +1721,13 @@
}
},
"node_modules/@playwright/test": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz",
- "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==",
+ "version": "1.53.2",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz",
+ "integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "playwright": "1.52.0"
+ "playwright": "1.53.2"
},
"bin": {
"playwright": "cli.js"
@@ -2614,232 +2614,6 @@
"@svgr/core": "*"
}
},
- "node_modules/@swc/core": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.12.7.tgz",
- "integrity": "sha512-bcpllEihyUSnqp0UtXTvXc19CT4wp3tGWLENhWnjr4B5iEOkzqMu+xHGz1FI5IBatjfqOQb29tgIfv6IL05QaA==",
- "dev": true,
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@swc/counter": "^0.1.3",
- "@swc/types": "^0.1.23"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/swc"
- },
- "optionalDependencies": {
- "@swc/core-darwin-arm64": "1.12.7",
- "@swc/core-darwin-x64": "1.12.7",
- "@swc/core-linux-arm-gnueabihf": "1.12.7",
- "@swc/core-linux-arm64-gnu": "1.12.7",
- "@swc/core-linux-arm64-musl": "1.12.7",
- "@swc/core-linux-x64-gnu": "1.12.7",
- "@swc/core-linux-x64-musl": "1.12.7",
- "@swc/core-win32-arm64-msvc": "1.12.7",
- "@swc/core-win32-ia32-msvc": "1.12.7",
- "@swc/core-win32-x64-msvc": "1.12.7"
- },
- "peerDependencies": {
- "@swc/helpers": ">=0.5.17"
- },
- "peerDependenciesMeta": {
- "@swc/helpers": {
- "optional": true
- }
- }
- },
- "node_modules/@swc/core-darwin-arm64": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.12.7.tgz",
- "integrity": "sha512-w6BBT0hBRS56yS+LbReVym0h+iB7/PpCddqrn1ha94ra4rZ4R/A91A/rkv+LnQlPqU/+fhqdlXtCJU9mrhCBtA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-darwin-x64": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.12.7.tgz",
- "integrity": "sha512-jN6LhFfGOpm4DY2mXPgwH4aa9GLOwublwMVFFZ/bGnHYYCRitLZs9+JWBbyWs7MyGcA246Ew+EREx36KVEAxjA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.12.7.tgz",
- "integrity": "sha512-rHn8XXi7G2StEtZRAeJ6c7nhJPDnqsHXmeNrAaYwk8Tvpa6ZYG2nT9E1OQNXj1/dfbSFTjdiA8M8ZvGYBlpBoA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.12.7.tgz",
- "integrity": "sha512-N15hKizSSh+hkZ2x3TDVrxq0TDcbvDbkQJi2ZrLb9fK+NdFUV/x+XF16ZDPlbxtrGXl1CT7VD439SNaMN9F7qw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.12.7.tgz",
- "integrity": "sha512-jxyINtBezpxd3eIUDiDXv7UQ87YWlPsM9KumOwJk09FkFSO4oYxV2RT+Wu+Nt5tVWue4N0MdXT/p7SQsDEk4YA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.12.7.tgz",
- "integrity": "sha512-PR4tPVwU1BQBfFDk2XfzXxsEIjF3x/bOV1BzZpYvrlkU0TKUDbR4t2wzvsYwD/coW7/yoQmlL70/qnuPtTp1Zw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-x64-musl": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.12.7.tgz",
- "integrity": "sha512-zy7JWfQtQItgMfUjSbbcS3DZqQUn2d9VuV0LSGpJxtTXwgzhRpF1S2Sj7cU9hGpbM27Y8RJ4DeFb3qbAufjbrw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.12.7.tgz",
- "integrity": "sha512-52PeF0tyX04ZFD8nibNhy/GjMFOZWTEWPmIB3wpD1vIJ1po+smtBnEdRRll5WIXITKoiND8AeHlBNBPqcsdcwA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.12.7.tgz",
- "integrity": "sha512-WzQwkNMuhB1qQShT9uUgz/mX2j7NIEPExEtzvGsBT7TlZ9j1kGZ8NJcZH/fwOFcSJL4W7DnkL7nAhx6DBlSPaA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.12.7.tgz",
- "integrity": "sha512-R52ivBi2lgjl+Bd3XCPum0YfgbZq/W1AUExITysddP9ErsNSwnreYyNB3exEijiazWGcqHEas2ChiuMOP7NYrA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/counter": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
- "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/@swc/types": {
- "version": "0.1.23",
- "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz",
- "integrity": "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@swc/counter": "^0.1.3"
- }
- },
"node_modules/@tybys/wasm-util": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
@@ -3054,21 +2828,23 @@
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0"
}
},
- "node_modules/@vitejs/plugin-react-swc": {
- "version": "3.10.2",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.10.2.tgz",
- "integrity": "sha512-xD3Rdvrt5LgANug7WekBn1KhcvLn1H3jNBfJRL3reeOIua/WnZOEV5qi5qIBq5T8R0jUDmRtxuvk4bPhzGHDWw==",
+ "node_modules/@vitejs/plugin-react-oxc": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-oxc/-/plugin-react-oxc-0.2.3.tgz",
+ "integrity": "sha512-ONriHoEGQv+ITmeJQsHIpx7u1ms8Z68oIo3AdKCoaBTvZtF+AfDVviQ3tKgCTnIbz9NW8V2Rd/Q+5zjzpsht1g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@rolldown/pluginutils": "1.0.0-beta.11",
- "@swc/core": "^1.11.31"
+ "@rolldown/pluginutils": "1.0.0-beta.11"
+ },
+ "engines": {
+ "node": ">=20.0.0"
},
"peerDependencies": {
- "vite": "^4 || ^5 || ^6 || ^7.0.0-beta.0"
+ "vite": "^6.3.0 || ^7.0.0-beta.0"
}
},
- "node_modules/@vitejs/plugin-react-swc/node_modules/@rolldown/pluginutils": {
+ "node_modules/@vitejs/plugin-react-oxc/node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.11",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz",
"integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==",
@@ -5356,13 +5132,13 @@
"license": "MIT"
},
"node_modules/playwright": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz",
- "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==",
+ "version": "1.53.2",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz",
+ "integrity": "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "playwright-core": "1.52.0"
+ "playwright-core": "1.53.2"
},
"bin": {
"playwright": "cli.js"
@@ -5375,9 +5151,9 @@
}
},
"node_modules/playwright-core": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz",
- "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==",
+ "version": "1.53.2",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz",
+ "integrity": "sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
diff --git a/package.json b/package.json
index 4102d20f..0573d5d2 100644
--- a/package.json
+++ b/package.json
@@ -8,9 +8,9 @@
"build": "vite build"
},
"devDependencies": {
- "@playwright/test": "^1.52.0",
+ "@playwright/test": "1.53.2",
"@vitejs/plugin-react": "^4.6.0",
- "@vitejs/plugin-react-swc": "^3.10.2",
+ "@vitejs/plugin-react-oxc": "^0.2.3",
"@reduxjs/toolkit": "^1.6.1",
"sass": "^1.88.9",
"typescript": "^4.4.2",
diff --git a/playwright.config.ts b/playwright.config.ts
index dde1c703..0a2463bb 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -6,6 +6,8 @@ import { defineConfig, devices } from '@playwright/test';
*/
// require('dotenv').config();
+const BASE_URL = process.env.BASE_URL ?? 'http://nginx:8080';
+
/**
* See https://playwright.dev/docs/test-configuration.
*/
@@ -26,9 +28,7 @@ export default defineConfig({
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
// Docker baseurl
- baseURL: 'http://nginx:8080/',
- // for testing locally
- // baseURL: 'https://display.local.itkdev.dk/',
+ baseURL: BASE_URL,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
diff --git a/vite.config.js b/vite.config.js
index 1a956033..f4d5ef62 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,6 +1,6 @@
import {defineConfig} from "vite";
import symfonyPlugin from "vite-plugin-symfony";
-import react from "@vitejs/plugin-react-swc";
+import react from "@vitejs/plugin-react-oxc";
import svgr from "vite-plugin-svgr";
export default defineConfig(({command}) => {
@@ -13,6 +13,9 @@ export default defineConfig(({command}) => {
},
}
},
+ experimental: {
+ enableNativePlugin: true,
+ },
plugins: [
react(),
symfonyPlugin(),
@@ -21,7 +24,6 @@ export default defineConfig(({command}) => {
svgrOptions: {exportType: "default", ref: true, svgo: false, titleProp: true},
include: "**/*.svg",
}),
-
],
build: {
outDir: "./public/build",
@@ -45,7 +47,8 @@ export default defineConfig(({command}) => {
host: "display.local.itkdev.dk",
protocol: "wss",
clientPort: 443,
- }
+ },
+ cors: true,
},
}
});
From 2413ff0e45928e68ff3391ed85613f0cf66e37bb Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 11:09:12 +0200
Subject: [PATCH 04/30] 4565: Changed to a traeficless setup
---
.docker/templates/default.conf.template | 11 -----------
.github/workflows/pr.yaml | 4 ++--
docker-compose.override.yml | 9 +++------
public/error.html | 8 ++++++++
vite.config.js | 9 +--------
5 files changed, 14 insertions(+), 27 deletions(-)
create mode 100644 public/error.html
diff --git a/.docker/templates/default.conf.template b/.docker/templates/default.conf.template
index 991a5294..61c4e648 100644
--- a/.docker/templates/default.conf.template
+++ b/.docker/templates/default.conf.template
@@ -37,17 +37,6 @@ server {
internal;
}
- location /vite {
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header Host $http_host;
- proxy_pass http://node:3000;
- proxy_http_version 1.1;
-
- # Enable WebSocket support for HMR
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- }
-
location ~ \.php$ {
return 404;
}
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 3e498363..19923150 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -278,11 +278,11 @@ jobs:
- name: Run playwright
env:
- CI: 'true'
+ CI: "true"
run: |
docker compose run --rm node npm install
docker compose run --rm node npm run build
- docker compose run --rm playwright npx playwright test --retries 3
+ docker compose run --rm playwright npx playwright test
- uses: actions/upload-artifact@v4
if: always()
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index e4b15ad3..211eb08a 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -1,10 +1,4 @@
services:
- nginx:
- labels:
- # HTTPS config - uncomment to enable redirect from :80 to :443
- - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=redirect-to-https"
- - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
-
redis:
image: "redis:6"
networks:
@@ -15,8 +9,11 @@ services:
node:
image: node:24
command: npm run dev
+ ports:
+ - "5173:5173"
networks:
- app
+ - frontend
working_dir: /app
environment:
- NODE_ENV=development
diff --git a/public/error.html b/public/error.html
new file mode 100644
index 00000000..895c5106
--- /dev/null
+++ b/public/error.html
@@ -0,0 +1,8 @@
+
+
+ Error
+
+
+ Error
+
+
diff --git a/vite.config.js b/vite.config.js
index f4d5ef62..4886cdc6 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -5,7 +5,7 @@ import svgr from "vite-plugin-svgr";
export default defineConfig(({command}) => {
return {
- base: command === 'serve' ? '/vite' : '/build',
+ base: "/build",
css: {
preprocessorOptions: {
scss: {
@@ -40,14 +40,7 @@ export default defineConfig(({command}) => {
},
},
server: {
- strictPort: true,
- port: 3000,
host: "0.0.0.0",
- hmr: {
- host: "display.local.itkdev.dk",
- protocol: "wss",
- clientPort: 443,
- },
cors: true,
},
}
From 8389d8a0298e4653128f5ad723fc4837e4fe6f6b Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 11:23:11 +0200
Subject: [PATCH 05/30] 4565: Added composer install
---
.github/workflows/pr.yaml | 3 +++
public/error.html | 8 --------
2 files changed, 3 insertions(+), 8 deletions(-)
delete mode 100644 public/error.html
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 19923150..4693d1b3 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -276,6 +276,9 @@ jobs:
- name: Setup network
run: docker network create frontend
+ - name: Composer install
+ run: docker compose run --rm phpfpm composer install
+
- name: Run playwright
env:
CI: "true"
diff --git a/public/error.html b/public/error.html
deleted file mode 100644
index 895c5106..00000000
--- a/public/error.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- Error
-
-
- Error
-
-
From 0d29dcaea3e3322185f1fe9fd9837c99c199354e Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 12:15:57 +0200
Subject: [PATCH 06/30] 4565: Split pr.yaml into more files
---
.github/workflows/apispec.yaml | 50 ++++
.github/workflows/composer_install.yaml | 40 ++++
.github/workflows/doctrine.yaml | 57 +++++
.github/workflows/phpunit.yaml | 59 +++++
.github/workflows/playwright.yaml | 41 ++++
.github/workflows/pr.yaml | 295 ------------------------
.github/workflows/psalm.yaml | 39 ++++
.github/workflows/rector.yaml | 39 ++++
8 files changed, 325 insertions(+), 295 deletions(-)
create mode 100644 .github/workflows/apispec.yaml
create mode 100644 .github/workflows/composer_install.yaml
create mode 100644 .github/workflows/doctrine.yaml
create mode 100644 .github/workflows/phpunit.yaml
create mode 100644 .github/workflows/playwright.yaml
delete mode 100644 .github/workflows/pr.yaml
create mode 100644 .github/workflows/psalm.yaml
create mode 100644 .github/workflows/rector.yaml
diff --git a/.github/workflows/apispec.yaml b/.github/workflows/apispec.yaml
new file mode 100644
index 00000000..81de9fed
--- /dev/null
+++ b/.github/workflows/apispec.yaml
@@ -0,0 +1,50 @@
+on: pull_request
+
+name: Api Spec
+
+jobs:
+ apispec:
+ runs-on: ubuntu-latest
+ name: API Specification validation
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ["8.3"]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php}}
+ extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
+ coverage: none
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ matrix.php }}-composer-
+
+ - name: Install Dependencies
+ run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
+
+ - name: Export specifications (yaml)
+ run: bin/console api:openapi:export --yaml --output=public/api-spec-v2.yaml --no-interaction
+
+ - name: Check for changes in specifications (yaml)
+ run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.yaml
+
+ - name: Export specifications (json)
+ run: bin/console api:openapi:export --output=public/api-spec-v2.json --no-interaction
+
+ - name: Check for changes in specifications (json)
+ run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.json
diff --git a/.github/workflows/composer_install.yaml b/.github/workflows/composer_install.yaml
new file mode 100644
index 00000000..7954e2a0
--- /dev/null
+++ b/.github/workflows/composer_install.yaml
@@ -0,0 +1,40 @@
+on: pull_request
+
+name: PHP install
+
+jobs:
+ test-composer-install:
+ runs-on: ubuntu-latest
+ env:
+ COMPOSER_ALLOW_SUPERUSER: 1
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ["8.3"]
+ name: Composer install in prod mode (PHP ${{ matrix.php}})
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php}}
+ extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
+ coverage: none
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ matrix.php }}-composer-
+
+ - name: "[prod] Composer install with exported .env variables"
+ run: |
+ set -a && source .env && set +a
+ APP_ENV=prod composer install --no-dev -o
diff --git a/.github/workflows/doctrine.yaml b/.github/workflows/doctrine.yaml
new file mode 100644
index 00000000..411acc50
--- /dev/null
+++ b/.github/workflows/doctrine.yaml
@@ -0,0 +1,57 @@
+on: pull_request
+
+name: Doctrine
+
+jobs:
+ validate-doctrine-shema:
+ runs-on: ubuntu-latest
+ env:
+ DATABASE_URL: mysql://db:db@127.0.0.1:3306/db?serverVersion=mariadb-10.5.13
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ["8.3"]
+ name: Validate Schema (PHP ${{ matrix.php}})
+ services:
+ mariadb:
+ image: mariadb:10.5.13
+ env:
+ MYSQL_USER: db
+ MYSQL_PASSWORD: db
+ MYSQL_DATABASE: db
+ MYSQL_ROOT_PASSWORD: db
+ ports:
+ - 3306:3306
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php}}
+ extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
+ coverage: none
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ matrix.php }}-composer-
+
+ - name: "Composer install with exported .env variables"
+ run: |
+ set -a && source .env && set +a
+ APP_ENV=prod composer install --no-dev -o
+
+ - name: Run Doctrine Migrations
+ run: APP_ENV=prod php bin/console doctrine:migrations:migrate --no-interaction
+
+ - name: Validate Doctrine schema
+ run: APP_ENV=prod php bin/console doctrine:schema:validate
diff --git a/.github/workflows/phpunit.yaml b/.github/workflows/phpunit.yaml
new file mode 100644
index 00000000..2a2e5488
--- /dev/null
+++ b/.github/workflows/phpunit.yaml
@@ -0,0 +1,59 @@
+on: pull_request
+
+name: Test
+
+jobs:
+ phpunit:
+ runs-on: ubuntu-latest
+ services:
+ mariadb:
+ image: mariadb:lts
+ ports:
+ - 3306
+ env:
+ MYSQL_USER: db
+ MYSQL_PASSWORD: db
+ MYSQL_DATABASE: db_test
+ MYSQL_ROOT_PASSWORD: password
+ # https://mariadb.org/mariadb-server-docker-official-images-healthcheck-without-mysqladmin/
+ options: >-
+ --health-cmd="healthcheck.sh --connect --innodb_initialized"
+ --health-interval=5s
+ --health-timeout=2s
+ --health-retries=3
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ["8.3"]
+ name: PHP Unit tests (PHP ${{ matrix.php }})
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php}}
+ extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
+ coverage: none
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ matrix.php }}-composer-
+
+ - name: Install Dependencies
+ run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
+
+ - name: PHP Unit - Test setup
+ env:
+ PORT: ${{ job.services.mariadb.ports[3306] }}
+ run: |
+ DATABASE_URL="mysql://db:db@127.0.0.1:$PORT/db_test" composer run test-setup
+ DATABASE_URL="mysql://db:db@127.0.0.1:$PORT/db_test" composer run test
diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml
new file mode 100644
index 00000000..7d2802df
--- /dev/null
+++ b/.github/workflows/playwright.yaml
@@ -0,0 +1,41 @@
+on: pull_request
+
+name: Test
+
+env:
+ COMPOSE_USER: root
+
+jobs:
+ frontend-build-and-test:
+ name: Playwright
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: true
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup network
+ run: docker network create frontend
+
+ - name: Composer install
+ run: |
+ docker compose run --rm phpfpm composer install
+
+ - name: Build assets
+ run: |
+ docker compose run --rm node npm install
+ docker compose run --rm node npm run build
+
+ - name: Run playwright
+ env:
+ CI: "true"
+ run: |
+ docker compose run --rm playwright npx playwright test
+
+ - uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: playwright-report
+ path: playwright-report/
+ retention-days: 30
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
deleted file mode 100644
index 4693d1b3..00000000
--- a/.github/workflows/pr.yaml
+++ /dev/null
@@ -1,295 +0,0 @@
-on: pull_request
-name: Pull Request Review
-jobs:
- test-composer-install:
- runs-on: ubuntu-latest
- env:
- COMPOSER_ALLOW_SUPERUSER: 1
- strategy:
- fail-fast: false
- matrix:
- php: ["8.3"]
- name: Validate composer (PHP ${{ matrix.php}})
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php}}
- extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
- coverage: none
-
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Cache composer dependencies
- uses: actions/cache@v4
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ matrix.php }}-composer-
-
- - name: "[prod] Composer install with exported .env variables"
- run: |
- set -a && source .env && set +a
- APP_ENV=prod composer install --no-dev -o
-
- validate-doctrine-shema:
- runs-on: ubuntu-latest
- env:
- DATABASE_URL: mysql://db:db@127.0.0.1:3306/db?serverVersion=mariadb-10.5.13
- strategy:
- fail-fast: false
- matrix:
- php: ["8.3"]
- name: Validate Doctrine Schema (PHP ${{ matrix.php}})
- services:
- mariadb:
- image: mariadb:10.5.13
- env:
- MYSQL_USER: db
- MYSQL_PASSWORD: db
- MYSQL_DATABASE: db
- MYSQL_ROOT_PASSWORD: db
- ports:
- - 3306:3306
- options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php}}
- extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
- coverage: none
-
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Cache composer dependencies
- uses: actions/cache@v4
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ matrix.php }}-composer-
-
- - name: "Composer install with exported .env variables"
- run: |
- set -a && source .env && set +a
- APP_ENV=prod composer install --no-dev -o
-
- - name: Run Doctrine Migrations
- run: APP_ENV=prod php bin/console doctrine:migrations:migrate --no-interaction
-
- - name: Validate Doctrine schema
- run: APP_ENV=prod php bin/console doctrine:schema:validate
-
- psalm:
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- php: ["8.3"]
- name: Psalm (PHP ${{ matrix.php }})
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php}}
- extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
- coverage: none
-
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Cache composer dependencies
- uses: actions/cache@v4
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ matrix.php }}-composer-
-
- - name: Install Dependencies
- run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
-
- - name: Psalm
- run: phpdbg -qrr ./vendor/bin/psalm
-
- rector:
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- php: ["8.3"]
- name: Rector (PHP ${{ matrix.php }})
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php}}
- extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
- coverage: none
-
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Cache composer dependencies
- uses: actions/cache@v4
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ matrix.php }}-composer-
-
- - name: Install Dependencies
- run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
-
- - name: Rector
- run: phpdbg -qrr ./vendor/bin/rector --dry-run
-
- phpunit:
- runs-on: ubuntu-latest
- services:
- mariadb:
- image: mariadb:lts
- ports:
- - 3306
- env:
- MYSQL_USER: db
- MYSQL_PASSWORD: db
- MYSQL_DATABASE: db_test
- MYSQL_ROOT_PASSWORD: password
- # https://mariadb.org/mariadb-server-docker-official-images-healthcheck-without-mysqladmin/
- options: >-
- --health-cmd="healthcheck.sh --connect --innodb_initialized"
- --health-interval=5s
- --health-timeout=2s
- --health-retries=3
- strategy:
- fail-fast: false
- matrix:
- php: ["8.3"]
- name: PHP Unit tests (PHP ${{ matrix.php }})
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php}}
- extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
- coverage: none
-
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Cache composer dependencies
- uses: actions/cache@v4
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ matrix.php }}-composer-
-
- - name: Install Dependencies
- run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
-
- - name: PHP Unit - Test setup
- env:
- PORT: ${{ job.services.mariadb.ports[3306] }}
- run: DATABASE_URL="mysql://db:db@127.0.0.1:$PORT/db_test" composer run test-setup
-
- - name: PHP Unit - Test
- env:
- PORT: ${{ job.services.mariadb.ports[3306] }}
- run: DATABASE_URL="mysql://db:db@127.0.0.1:$PORT/db_test" composer run test
-
- apispec:
- runs-on: ubuntu-latest
- name: API Specification validation
- strategy:
- fail-fast: false
- matrix:
- php: ["8.3"]
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 2
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php}}
- extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
- coverage: none
-
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Cache composer dependencies
- uses: actions/cache@v4
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ matrix.php }}-composer-
-
- - name: Install Dependencies
- run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
-
- - name: Export specifications (yaml)
- run: bin/console api:openapi:export --yaml --output=public/api-spec-v2.yaml --no-interaction
-
- - name: Check for changes in specifications (yaml)
- run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.yaml
-
- - name: Export specifications (json)
- run: bin/console api:openapi:export --output=public/api-spec-v2.json --no-interaction
-
- - name: Check for changes in specifications (json)
- run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.json
-
- frontend-build-and-test:
- name: Playwright
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup network
- run: docker network create frontend
-
- - name: Composer install
- run: docker compose run --rm phpfpm composer install
-
- - name: Run playwright
- env:
- CI: "true"
- run: |
- docker compose run --rm node npm install
- docker compose run --rm node npm run build
- docker compose run --rm playwright npx playwright test
-
- - uses: actions/upload-artifact@v4
- if: always()
- with:
- name: playwright-report
- path: playwright-report/
- retention-days: 30
diff --git a/.github/workflows/psalm.yaml b/.github/workflows/psalm.yaml
new file mode 100644
index 00000000..6cbb222c
--- /dev/null
+++ b/.github/workflows/psalm.yaml
@@ -0,0 +1,39 @@
+on: pull_request
+
+name: Psalm
+
+jobs:
+ psalm:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ["8.3"]
+ name: Psalm (PHP ${{ matrix.php }})
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php}}
+ extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
+ coverage: none
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ matrix.php }}-composer-
+
+ - name: Install Dependencies
+ run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
+
+ - name: Psalm
+ run: phpdbg -qrr ./vendor/bin/psalm
diff --git a/.github/workflows/rector.yaml b/.github/workflows/rector.yaml
new file mode 100644
index 00000000..aa482e70
--- /dev/null
+++ b/.github/workflows/rector.yaml
@@ -0,0 +1,39 @@
+on: pull_request
+
+name: Rector
+
+jobs:
+ rector:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ["8.3"]
+ name: Rector (PHP ${{ matrix.php }})
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php}}
+ extensions: apcu, ctype, iconv, imagick, json, redis, soap, xmlreader, zip
+ coverage: none
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ matrix.php }}-composer-
+
+ - name: Install Dependencies
+ run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
+
+ - name: Rector
+ run: phpdbg -qrr ./vendor/bin/rector --dry-run
From 8dd2101399152a4aa3abbe454a9533cad2bff82d Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 12:29:12 +0200
Subject: [PATCH 07/30] 4565: Set COMPOSE_USER
---
.github/workflows/composer.yaml | 2 +-
.github/workflows/composer_install.yaml | 2 +-
.github/workflows/php.yaml | 2 +-
.github/workflows/playwright.yaml | 2 +-
.github/workflows/twig.yaml | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/composer.yaml b/.github/workflows/composer.yaml
index 6e60167b..b93b0d81 100644
--- a/.github/workflows/composer.yaml
+++ b/.github/workflows/composer.yaml
@@ -26,7 +26,7 @@
name: Composer
env:
- COMPOSE_USER: root
+ COMPOSE_USER: runner
on:
pull_request:
diff --git a/.github/workflows/composer_install.yaml b/.github/workflows/composer_install.yaml
index 7954e2a0..569a71b3 100644
--- a/.github/workflows/composer_install.yaml
+++ b/.github/workflows/composer_install.yaml
@@ -1,6 +1,6 @@
on: pull_request
-name: PHP install
+name: Composer install
jobs:
test-composer-install:
diff --git a/.github/workflows/php.yaml b/.github/workflows/php.yaml
index 60fb70eb..ee967977 100644
--- a/.github/workflows/php.yaml
+++ b/.github/workflows/php.yaml
@@ -34,7 +34,7 @@
name: Symfony PHP
env:
- COMPOSE_USER: root
+ COMPOSE_USER: runner
on:
pull_request:
diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml
index 7d2802df..0f67fe03 100644
--- a/.github/workflows/playwright.yaml
+++ b/.github/workflows/playwright.yaml
@@ -3,7 +3,7 @@ on: pull_request
name: Test
env:
- COMPOSE_USER: root
+ COMPOSE_USER: runner
jobs:
frontend-build-and-test:
diff --git a/.github/workflows/twig.yaml b/.github/workflows/twig.yaml
index 9b0e3431..9dc424b4 100644
--- a/.github/workflows/twig.yaml
+++ b/.github/workflows/twig.yaml
@@ -24,7 +24,7 @@
name: Twig
env:
- COMPOSE_USER: root
+ COMPOSE_USER: runner
on:
pull_request:
From c6cce532e3734f07b5d2671e4e673cc0b0328ab7 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 12:41:35 +0200
Subject: [PATCH 08/30] 4565: Changed playwright container
---
.github/workflows/playwright.yaml | 1 +
docker-compose.override.yml | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml
index 0f67fe03..02550e4e 100644
--- a/.github/workflows/playwright.yaml
+++ b/.github/workflows/playwright.yaml
@@ -31,6 +31,7 @@ jobs:
env:
CI: "true"
run: |
+ docker compose run --rm playwright npx playwright install --with-deps
docker compose run --rm playwright npx playwright test
- uses: actions/upload-artifact@v4
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 211eb08a..323243a2 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -23,7 +23,7 @@ services:
playwright:
# https://playwright.dev/docs/docker
# This Playwright version should match the one in `package.json`.
- image: mcr.microsoft.com/playwright:v1.53.2-noble
+ image: mcr.microsoft.com/playwright:v1.53.2
networks:
- app
depends_on:
From b92d561a1651ce55fc2c56b779955966c670631c Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 13:17:21 +0200
Subject: [PATCH 09/30] 4565: Added default login methods to .env
---
.env | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.env b/.env
index e25463ff..3d119537 100644
--- a/.env
+++ b/.env
@@ -115,7 +115,7 @@ TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300
ADMIN_REJSEPLANEN_APIKEY=
ADMIN_SHOW_SCREEN_STATUS=false
ADMIN_TOUCH_BUTTON_REGIONS=false
-ADMIN_LOGIN_METHODS="[]"
+ADMIN_LOGIN_METHODS='"[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]'"'
ADMIN_ENHANCED_PREVIEW=false
###< Admin configuration ###
From 73ecbd50e4b63f3ffc9e96d1eef51bbc5733e6ee Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 13:18:40 +0200
Subject: [PATCH 10/30] 4565: Removed typos
---
.env | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.env b/.env
index 3d119537..ab0e35b3 100644
--- a/.env
+++ b/.env
@@ -115,7 +115,7 @@ TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300
ADMIN_REJSEPLANEN_APIKEY=
ADMIN_SHOW_SCREEN_STATUS=false
ADMIN_TOUCH_BUTTON_REGIONS=false
-ADMIN_LOGIN_METHODS='"[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]'"'
+ADMIN_LOGIN_METHODS='[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]'
ADMIN_ENHANCED_PREVIEW=false
###< Admin configuration ###
From 32ec83d3777876e9ee657a9c18c71125cb6b1166 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 18:19:29 +0200
Subject: [PATCH 11/30] 4565: Fixed issues with tests
---
assets/tests/admin/admin-app.spec.js | 3 +-
assets/tests/admin/admin-campaign.spec.js | 5 +-
assets/tests/admin/admin-feed-sources.spec.js | 3 +-
assets/tests/admin/admin-media.spec.js | 1 +
assets/tests/admin/admin-playlist.spec.js | 1 +
.../tests/admin/admin-screen-groups.spec.js | 1 +
assets/tests/admin/admin-screens.spec.js | 60 +++++++------------
assets/tests/admin/admin-shared-list.spec.js | 1 +
assets/tests/admin/admin-slides.spec.js | 1 +
assets/tests/admin/admin-theme.spec.js | 1 +
assets/tests/admin/admin-top-bar.spec.js | 1 +
config/routes.yaml | 2 +-
12 files changed, 34 insertions(+), 46 deletions(-)
diff --git a/assets/tests/admin/admin-app.spec.js b/assets/tests/admin/admin-app.spec.js
index 32bceda7..bf99dcce 100644
--- a/assets/tests/admin/admin-app.spec.js
+++ b/assets/tests/admin/admin-app.spec.js
@@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test";
test("Basic app runs", async ({ page }) => {
await page.goto(
- "/admin/slide/list?published=all&page=1&order=asc&sort=title",
+ "/admin/slide/list",
);
await page.route("**/slides*", async (route) => {
@@ -31,6 +31,7 @@ test("Basic app runs", async ({ page }) => {
};
await route.fulfill({ json });
});
+
await page.route("**/token", async (route) => {
const json = {
token: "1",
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index f607a6ba..d66978ad 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -40,6 +40,7 @@ test.describe("Campaign pages work", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Opret ny kampagne")).toBeVisible();
});
test("It loads create campaign page", async ({ page }) => {
@@ -340,10 +341,8 @@ test.describe("Campaign pages work", () => {
// Remove slide
await page
- .locator("#slides-section")
- .locator("tbody")
.locator(".remove-from-list")
- .click();
+ .click({ force: true });
await expect(
page.locator("#slides-section").locator("tbody"),
).not.toBeVisible();
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index d8539cc2..8db54a96 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -186,7 +186,7 @@ const feedSourcesJson = {
],
};
-test.describe("fest", () => {
+test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/admin/feed-sources/list");
await page.route("**/feed-sources*", async (route) => {
@@ -215,6 +215,7 @@ test.describe("fest", () => {
await page.getByLabel("Email").fill("admin@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Datakilder")).toBeVisible();
});
test("It loads create datakilde page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-media.spec.js b/assets/tests/admin/admin-media.spec.js
index 06c932d6..d421a5b4 100644
--- a/assets/tests/admin/admin-media.spec.js
+++ b/assets/tests/admin/admin-media.spec.js
@@ -84,6 +84,7 @@ test.describe("media list tests", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Medier")).toBeVisible();
});
test("It loads media list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index 21807e4c..34ed86a2 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -36,6 +36,7 @@ test.describe("Playlist create tests", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Opret ny spilleliste")).toBeVisible();
});
test("It loads create playlist page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index d4c2d07e..720dcf61 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -27,6 +27,7 @@ test.describe("Create group page works", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Opret ny gruppe")).toBeVisible();
});
test("It loads create group page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index d61292b7..e11eee13 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -1,7 +1,7 @@
import { test, expect } from "@playwright/test";
test.describe("Screen list tests", () => {
- test.beforeEach(async ({ page }) => {
+ test("Test list", async ({ page }) => {
await page.goto("/admin/screen/list");
await page.route("**/token", async (route) => {
const json = {
@@ -25,6 +25,7 @@ test.describe("Screen list tests", () => {
await page.route("**/screens*", async (route) => {
const json = {
"@id": "/v2/screens",
+ "hydra:totalItems": 2,
"hydra:member": [
{
"@type": "Screen",
@@ -70,53 +71,32 @@ test.describe("Screen list tests", () => {
},
],
};
-
await route.fulfill({ json });
});
+ await page.route("**/campaigns*", async (route) => {
+ await route.fulfill({ json: {
+ "hydra:member": [],
+ "hydra:totalItems": 0,
+ }
+ });
+ });
+ await page.route("**/screen-groups*", async (route) => {
+ await route.fulfill({ json: {
+ "hydra:member": [],
+ "hydra:totalItems": 0,
+ }
+ });
+ });
+
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- });
- test("It loads screens list", async ({ page }) => {
- await page.getByText("Skærme");
+ await expect(page.locator('h1').getByText("Skærme")).toBeVisible();
await expect(page.locator("table").locator("tbody")).not.toBeEmpty();
- await expect(page.locator("tbody").locator("tr td")).toHaveCount(14);
- });
-
- test("It goes to screen edit", async ({ page }) => {
- await page.route("**/screens/*", async (route) => {
- const json = {
- "@id": "/v2/screens/00APXK73HQ11PM0X3P12EG14DZ",
- title: "Ab eos dolorum minima inventore.",
- description:
- "Non inventore ab vitae. Voluptatem assumenda aliquam sunt nulla sint corrupti et. Nihil consectetur facere cum modi aliquid. Non aut voluptas voluptas laudantium.",
- size: "42",
- created: "1981-09-01T17:22:18+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- layout: "/v2/layouts/009S1H8VER00GK086N0M1J16K9",
- location:
- "Natus aut est eveniet deleniti nihil voluptatum. Accusamus similique adipisci at qui molestiae quia nihil eligendi. Delectus repellendus ut asperiores ut debitis.",
- regions: [],
- inScreenGroups: "/v2/screens/00APXK73HQ11PM0X3P12EG14DZ/groups",
- dimensions: {
- width: 1920,
- height: 1200,
- },
- };
-
- await route.fulfill({ json });
- });
- await expect(page.locator("#screenTitle")).not.toBeVisible();
- await page.locator("tbody").locator("#edit_button").nth(0).click();
- await expect(page.locator("#screenTitle")).toBeVisible();
- });
-
- test("The correct amount of column headers loaded", async ({ page }) => {
- await expect(page.locator("thead").locator("th")).toHaveCount(7);
+ await expect(page.locator("tbody").locator("tr td")).toHaveCount(16);
+ await expect(page.locator("thead").locator("th")).toHaveCount(8);
});
});
diff --git a/assets/tests/admin/admin-shared-list.spec.js b/assets/tests/admin/admin-shared-list.spec.js
index b85f18db..76ee7133 100644
--- a/assets/tests/admin/admin-shared-list.spec.js
+++ b/assets/tests/admin/admin-shared-list.spec.js
@@ -82,6 +82,7 @@ test.describe("Shared list tests", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Delte spillelister")).toBeVisible();
});
test("It loads shared playlist list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-slides.spec.js b/assets/tests/admin/admin-slides.spec.js
index 529f6757..519415e4 100644
--- a/assets/tests/admin/admin-slides.spec.js
+++ b/assets/tests/admin/admin-slides.spec.js
@@ -119,6 +119,7 @@ test.describe("Create slide page works", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Opret nyt slide")).toBeVisible();
});
test("It loads create slide page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-theme.spec.js b/assets/tests/admin/admin-theme.spec.js
index ab3dd1d6..e5bf1ae9 100644
--- a/assets/tests/admin/admin-theme.spec.js
+++ b/assets/tests/admin/admin-theme.spec.js
@@ -302,6 +302,7 @@ test.describe("Theme pages work", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Temaer")).toBeVisible();
});
test("It loads create theme page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index ef754dd6..e9a336a0 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -33,6 +33,7 @@ test.describe("Nav items loads", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
+ await expect(page.locator('h1').getByText("Opret ny skærm")).toBeVisible();
});
test("It loads", async ({ page }) => {
diff --git a/config/routes.yaml b/config/routes.yaml
index 505235fa..f1185ed4 100644
--- a/config/routes.yaml
+++ b/config/routes.yaml
@@ -34,7 +34,7 @@ client:
# https://symfony.com/doc/current/routing.html#slash-characters-in-route-parameters
subroutes: '.*'
methods: ['GET']
- controller: App\Controller\Client\ClientController'
+ controller: App\Controller\Client\ClientController
when@dev:
templates:
From 118e965d2d0252b3c72d77c74f39aa8c8293fd98 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 18:21:06 +0200
Subject: [PATCH 12/30] 4565: Applied coding standards
---
assets/tests/admin/admin-app.spec.js | 4 +---
assets/tests/admin/admin-campaign.spec.js | 8 ++++----
assets/tests/admin/admin-feed-sources.spec.js | 2 +-
assets/tests/admin/admin-media.spec.js | 2 +-
assets/tests/admin/admin-playlist.spec.js | 4 +++-
assets/tests/admin/admin-screen-groups.spec.js | 2 +-
assets/tests/admin/admin-screens.spec.js | 12 +++++++-----
assets/tests/admin/admin-shared-list.spec.js | 4 +++-
assets/tests/admin/admin-slides.spec.js | 2 +-
assets/tests/admin/admin-theme.spec.js | 2 +-
assets/tests/admin/admin-top-bar.spec.js | 2 +-
11 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/assets/tests/admin/admin-app.spec.js b/assets/tests/admin/admin-app.spec.js
index bf99dcce..134316dc 100644
--- a/assets/tests/admin/admin-app.spec.js
+++ b/assets/tests/admin/admin-app.spec.js
@@ -1,9 +1,7 @@
import { test, expect } from "@playwright/test";
test("Basic app runs", async ({ page }) => {
- await page.goto(
- "/admin/slide/list",
- );
+ await page.goto("/admin/slide/list");
await page.route("**/slides*", async (route) => {
const json = {
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index d66978ad..563bbbcb 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -40,7 +40,9 @@ test.describe("Campaign pages work", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Opret ny kampagne")).toBeVisible();
+ await expect(
+ page.locator("h1").getByText("Opret ny kampagne"),
+ ).toBeVisible();
});
test("It loads create campaign page", async ({ page }) => {
@@ -340,9 +342,7 @@ test.describe("Campaign pages work", () => {
).toHaveCount(6);
// Remove slide
- await page
- .locator(".remove-from-list")
- .click({ force: true });
+ await page.locator(".remove-from-list").click({ force: true });
await expect(
page.locator("#slides-section").locator("tbody"),
).not.toBeVisible();
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 8db54a96..5547f4d7 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -215,7 +215,7 @@ test.describe("feed sources", () => {
await page.getByLabel("Email").fill("admin@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Datakilder")).toBeVisible();
+ await expect(page.locator("h1").getByText("Datakilder")).toBeVisible();
});
test("It loads create datakilde page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-media.spec.js b/assets/tests/admin/admin-media.spec.js
index d421a5b4..312a18b7 100644
--- a/assets/tests/admin/admin-media.spec.js
+++ b/assets/tests/admin/admin-media.spec.js
@@ -84,7 +84,7 @@ test.describe("media list tests", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Medier")).toBeVisible();
+ await expect(page.locator("h1").getByText("Medier")).toBeVisible();
});
test("It loads media list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index 34ed86a2..add7f5c1 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -36,7 +36,9 @@ test.describe("Playlist create tests", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Opret ny spilleliste")).toBeVisible();
+ await expect(
+ page.locator("h1").getByText("Opret ny spilleliste"),
+ ).toBeVisible();
});
test("It loads create playlist page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index 720dcf61..fc5c047c 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -27,7 +27,7 @@ test.describe("Create group page works", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Opret ny gruppe")).toBeVisible();
+ await expect(page.locator("h1").getByText("Opret ny gruppe")).toBeVisible();
});
test("It loads create group page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index e11eee13..e7821d98 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -74,17 +74,19 @@ test.describe("Screen list tests", () => {
await route.fulfill({ json });
});
await page.route("**/campaigns*", async (route) => {
- await route.fulfill({ json: {
+ await route.fulfill({
+ json: {
"hydra:member": [],
"hydra:totalItems": 0,
- }
+ },
});
});
await page.route("**/screen-groups*", async (route) => {
- await route.fulfill({ json: {
+ await route.fulfill({
+ json: {
"hydra:member": [],
"hydra:totalItems": 0,
- }
+ },
});
});
@@ -93,7 +95,7 @@ test.describe("Screen list tests", () => {
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Skærme")).toBeVisible();
+ await expect(page.locator("h1").getByText("Skærme")).toBeVisible();
await expect(page.locator("table").locator("tbody")).not.toBeEmpty();
await expect(page.locator("tbody").locator("tr td")).toHaveCount(16);
await expect(page.locator("thead").locator("th")).toHaveCount(8);
diff --git a/assets/tests/admin/admin-shared-list.spec.js b/assets/tests/admin/admin-shared-list.spec.js
index 76ee7133..94adf5bf 100644
--- a/assets/tests/admin/admin-shared-list.spec.js
+++ b/assets/tests/admin/admin-shared-list.spec.js
@@ -82,7 +82,9 @@ test.describe("Shared list tests", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Delte spillelister")).toBeVisible();
+ await expect(
+ page.locator("h1").getByText("Delte spillelister"),
+ ).toBeVisible();
});
test("It loads shared playlist list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-slides.spec.js b/assets/tests/admin/admin-slides.spec.js
index 519415e4..c44060e2 100644
--- a/assets/tests/admin/admin-slides.spec.js
+++ b/assets/tests/admin/admin-slides.spec.js
@@ -119,7 +119,7 @@ test.describe("Create slide page works", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Opret nyt slide")).toBeVisible();
+ await expect(page.locator("h1").getByText("Opret nyt slide")).toBeVisible();
});
test("It loads create slide page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-theme.spec.js b/assets/tests/admin/admin-theme.spec.js
index e5bf1ae9..640d5fc2 100644
--- a/assets/tests/admin/admin-theme.spec.js
+++ b/assets/tests/admin/admin-theme.spec.js
@@ -302,7 +302,7 @@ test.describe("Theme pages work", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Temaer")).toBeVisible();
+ await expect(page.locator("h1").getByText("Temaer")).toBeVisible();
});
test("It loads create theme page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index e9a336a0..2111aa95 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -33,7 +33,7 @@ test.describe("Nav items loads", () => {
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
- await expect(page.locator('h1').getByText("Opret ny skærm")).toBeVisible();
+ await expect(page.locator("h1").getByText("Opret ny skærm")).toBeVisible();
});
test("It loads", async ({ page }) => {
From a551ed6eb182e3c43fac66527411520a1597f28d Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 3 Jul 2025 20:19:00 +0200
Subject: [PATCH 13/30] 4565: Added retries to playwright action
---
.github/workflows/playwright.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml
index 02550e4e..68395203 100644
--- a/.github/workflows/playwright.yaml
+++ b/.github/workflows/playwright.yaml
@@ -32,7 +32,7 @@ jobs:
CI: "true"
run: |
docker compose run --rm playwright npx playwright install --with-deps
- docker compose run --rm playwright npx playwright test
+ docker compose run --rm playwright npx playwright test --retries 3
- uses: actions/upload-artifact@v4
if: always()
From f4bfc386018612456b547acad0b6522cb8df478d Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Fri, 4 Jul 2025 10:31:44 +0200
Subject: [PATCH 14/30] 4565: Removed retry
---
.github/workflows/playwright.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml
index 68395203..02550e4e 100644
--- a/.github/workflows/playwright.yaml
+++ b/.github/workflows/playwright.yaml
@@ -32,7 +32,7 @@ jobs:
CI: "true"
run: |
docker compose run --rm playwright npx playwright install --with-deps
- docker compose run --rm playwright npx playwright test --retries 3
+ docker compose run --rm playwright npx playwright test
- uses: actions/upload-artifact@v4
if: always()
From c3deee2a98d270b22e61f3aff7d457c53228d934 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Sat, 5 Jul 2025 15:26:35 +0200
Subject: [PATCH 15/30] 4565: Started work on refactor
---
assets/tests/admin/admin-app.spec.js | 105 ++---
assets/tests/admin/admin-campaign.spec.js | 38 +-
.../tests/admin/admin-content-string.spec.js | 1 +
assets/tests/admin/admin-feed-sources.spec.js | 380 +-----------------
assets/tests/admin/data-fixtures.js | 343 ++++++++++++++++
5 files changed, 425 insertions(+), 442 deletions(-)
create mode 100644 assets/tests/admin/data-fixtures.js
diff --git a/assets/tests/admin/admin-app.spec.js b/assets/tests/admin/admin-app.spec.js
index 134316dc..d68ac70b 100644
--- a/assets/tests/admin/admin-app.spec.js
+++ b/assets/tests/admin/admin-app.spec.js
@@ -1,58 +1,65 @@
import { test, expect } from "@playwright/test";
-test("Basic app runs", async ({ page }) => {
- await page.goto("/admin/slide/list");
+test.describe("Basic app", () => {
+ test("App runs", async ({ page }) => {
+ await page.goto("/admin/slide/list");
- await page.route("**/slides*", async (route) => {
- const json = {
- "hydra:member": [
- {
- "@id": "/v2/slides/0086TQQC671WHA1S150MMF1Q3T",
- title: "Title on slide",
- description: "description",
- created: "1978-12-11T09:47:36.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/00MWCNKC4P0X5C0AT70E741E2V",
+ // Abort all routes that are not registered.
+ await page.route('**/*', async route => {
+ await route.abort();
+ });
+
+ await page.route("**/slides*", async (route) => {
+ const json = {
+ "hydra:member": [
+ {
+ "@id": "/v2/slides/0086TQQC671WHA1S150MMF1Q3T",
+ title: "Title on slide",
+ description: "description",
+ created: "1978-12-11T09:47:36.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/00MWCNKC4P0X5C0AT70E741E2V",
+ },
+ theme: "",
+ onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
+ duration: 70592,
+ published: {
+ from: null,
+ to: "1989-08-28T18:14:52.000Z",
+ },
},
- theme: "",
- onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
- duration: 70592,
- published: {
- from: null,
- to: "1989-08-28T18:14:52.000Z",
+ ],
+ };
+ await route.fulfill({ json });
+ });
+
+ await page.route("**/token", async (route) => {
+ const json = {
+ token: "1",
+ refresh_token: "2",
+ tenants: [
+ {
+ tenantKey: "ABC",
+ title: "ABC Tenant",
+ description: "Description",
+ roles: ["ROLE_ADMIN"],
},
+ ],
+ user: {
+ fullname: "John Doe",
+ email: "johndoe@example.com",
},
- ],
- };
- await route.fulfill({ json });
- });
+ };
+ await route.fulfill({ json });
+ });
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
+ await expect(page).toHaveTitle(/OS2Display Admin/);
+ await page.getByLabel("Email").fill("johndoe@example.com");
+ await page.getByLabel("Kodeord").fill("password");
+ await page.locator("#login").click();
+ await expect(page.getByText("Title on slide")).toBeVisible();
});
-
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.getByText("Title on slide")).toBeVisible();
});
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 563bbbcb..f545432b 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,41 +1,23 @@
import { test, expect } from "@playwright/test";
+import { emptySlidesJson, tokenJson } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/campaign/create");
+ // Abort all routes that are not registered.
+ await page.route('**/*', async route => {
+ await route.abort();
+ });
+
await page.route("**/slides*", async (route) => {
- const json = {
- "@id": "/v2/slides",
- "hydra:member": [],
- "hydra:totalItems": 100,
- "hydra:view": {
- "@id": "/v2/slides?itemsPerPage=0\u0026title=",
- "@type": "hydra:PartialCollectionView",
- },
- };
- await route.fulfill({ json });
+ await route.fulfill({ json: emptySlidesJson });
});
await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
+ await route.fulfill({ json: tokenJson });
});
+ await page.goto("/admin/campaign/create");
+
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
diff --git a/assets/tests/admin/admin-content-string.spec.js b/assets/tests/admin/admin-content-string.spec.js
index eaee3469..15c122db 100644
--- a/assets/tests/admin/admin-content-string.spec.js
+++ b/assets/tests/admin/admin-content-string.spec.js
@@ -16,6 +16,7 @@ test.describe("Content string", () => {
),
).toBe("test, hest or test");
});
+
test("It creates a string: 'test'", async ({ page }) => {
expect(contentString([{ name: "test" }], "or")).toBe("test");
});
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 5547f4d7..5af93790 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -1,216 +1,22 @@
import { test, expect } from "@playwright/test";
-
-const feedSourcesJson = {
- "@context": "/contexts/FeedSource",
- "@id": "/v2/feed-sources",
- "@type": "hydra:Collection",
- "hydra:totalItems": 5,
- "hydra:member": [
- {
- "@id": "/v2/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ",
- "@type": "FeedSource",
- title: "test 2",
- description: "test 2",
- outputType: "",
- feedType: "test 2",
- secrets: [],
- feeds: [],
- admin: [],
- supportedFeedOutputType: "test 2",
- modifiedBy: "admin@example.com",
- createdBy: "admin@example.com",
- id: "01JBBP48CS9CV80XRWRP8CAETJ",
- created: "2024-10-29T09:26:25.000Z",
- modified: "2024-10-29T09:26:25.000Z",
- },
- {
- "@id": "/v2/feed-sources/01JB9MSQEH75HC3GG75XCVP2WH",
- "@type": "FeedSource",
- title: "Ny datakilde test 3",
- description: "Ny datakilde test 3",
- outputType: "",
- feedType: "App\\Feed\\RssFeedType",
- secrets: [],
- feeds: [
- "/v2/feeds/01JB9R7EPN9NPW117C22NY31KH",
- "/v2/feeds/01JBBQMF72W2V36TWF6VXFA5Z7",
- ],
- admin: [
- {
- key: "rss-url",
- input: "input",
- name: "url",
- type: "url",
- label: "Kilde",
- helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
- },
- {
- key: "rss-number-of-entries",
- input: "input",
- name: "numberOfEntries",
- type: "number",
- label: "Antal indgange",
- helpText:
- "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
- },
- {
- key: "rss-entry-duration",
- input: "input",
- name: "entryDuration",
- type: "number",
- label: "Varighed pr. indgang (i sekunder)",
- helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
- ],
- supportedFeedOutputType: "rss",
- modifiedBy: "admin@example.com",
- createdBy: "admin@example.com",
- id: "01JB9MSQEH75HC3GG75XCVP2WH",
- created: "2024-10-28T14:24:43.000Z",
- modified: "2024-10-28T15:23:28.000Z",
- },
- {
- "@id": "/v2/feed-sources/01JB1DH8G4CXKGX5JRTYDHDPSP",
- "@type": "FeedSource",
- title: "Calendar datakilde test",
- description: "test",
- outputType: "",
- feedType: "App\\Feed\\CalendarApiFeedType",
- secrets: [],
- feeds: [],
- admin: [],
- supportedFeedOutputType: "calendar",
- modifiedBy: "",
- createdBy: "",
- id: "01JB1DH8G4CXKGX5JRTYDHDPSP",
- created: "2024-10-25T10:43:50.000Z",
- modified: "2024-10-25T10:43:50.000Z",
- },
- {
- "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
- "@type": "FeedSource",
- title: "feed_source_abc_notified",
- description:
- "Ut magnam veritatis velit ut doloribus id. Consequatur ut ipsum exercitationem aliquam laudantium voluptate voluptates perspiciatis. Id occaecati ea rerum facilis molestias et.",
- outputType: "",
- feedType: "App\\Feed\\RssFeedType",
- secrets: [],
- feeds: ["/v2/feeds/01GJD7S1KR10811MTA176C001R"],
- admin: [
- {
- key: "rss-url",
- input: "input",
- name: "url",
- type: "url",
- label: "Kilde",
- helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
- },
- {
- key: "rss-number-of-entries",
- input: "input",
- name: "numberOfEntries",
- type: "number",
- label: "Antal indgange",
- helpText:
- "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
- },
- {
- key: "rss-entry-duration",
- input: "input",
- name: "entryDuration",
- type: "number",
- label: "Varighed pr. indgang (i sekunder)",
- helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
- ],
- supportedFeedOutputType: "instagram",
- modifiedBy: "",
- createdBy: "",
- id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
- created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z",
- },
- {
- "@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
- "@type": "FeedSource",
- title: "feed_source_abc_1",
- description:
- "Totam eos molestias omnis aliquam quia qui voluptas. Non eum nihil ut sunt dolor.",
- outputType: "",
- feedType: "App\\Feed\\RssFeedType",
- secrets: [],
- feeds: ["/v2/feeds/01HD49075G0FNY1FNX12VE17K1"],
- admin: [
- {
- key: "rss-url",
- input: "input",
- name: "url",
- type: "url",
- label: "Kilde",
- helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
- },
- {
- key: "rss-number-of-entries",
- input: "input",
- name: "numberOfEntries",
- type: "number",
- label: "Antal indgange",
- helpText:
- "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
- },
- {
- key: "rss-entry-duration",
- input: "input",
- name: "entryDuration",
- type: "number",
- label: "Varighed pr. indgang (i sekunder)",
- helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
- ],
- supportedFeedOutputType: "rss",
- modifiedBy: "",
- createdBy: "",
- id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
- created: "2024-06-29T05:47:07.000Z",
- modified: "2024-10-21T18:01:25.000Z",
- },
- ],
-};
+import { errorJson, feedSourcesJson, tokenJson } from "./data-fixtures.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/feed-sources/list");
+ // Abort all routes that are not registered.
+ await page.route('**/*', async route => {
+ await route.abort();
+ });
+
await page.route("**/feed-sources*", async (route) => {
await route.fulfill({ json: feedSourcesJson });
});
await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
+ await route.fulfill({ json: tokenJson });
});
+
+ await page.goto("/admin/feed-sources/list");
+
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("admin@example.com");
await page.getByLabel("Kodeord").fill("password");
@@ -219,19 +25,14 @@ test.describe("feed sources", () => {
});
test("It loads create datakilde page", async ({ page }) => {
+ await page.goto("/admin/feed-sources/create");
page.getByText("Opret ny datakilde").click();
await expect(page.locator("#save")).toBeVisible();
});
test("It display error toast on save error", async ({ page }) => {
await page.route("**/feed-sources", async (route) => {
- const json = {
- "@context": "/contexts/Error",
- "@type": "hydra:Error",
- "hydra:title": "An error occurred",
- "hydra:description": "An error occurred",
- };
- await route.fulfill({ status: 500, json });
+ await route.fulfill({ status: 500, json: errorJson });
});
page.getByText("Opret ny datakilde").click();
@@ -252,44 +53,13 @@ test.describe("feed sources", () => {
).toBeVisible();
await expect(page).toHaveURL(/feed-sources\/create/);
});
+
test("Cancel create datakilde", async ({ page }) => {
page.getByText("Opret ny datakilde").click();
await expect(page.locator("#cancel")).toBeVisible();
await page.locator("#cancel").click();
await expect(page.locator("#cancel")).not.toBeVisible();
});
-});
-
-test.describe("datakilde list work", () => {
- test.beforeEach(async ({ page }) => {
- await page.goto("/admin/feed-sources/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/feed-sources*", async (route) => {
- await route.fulfill({ json: feedSourcesJson });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- });
test("It loads datakilde list", async ({ page }) => {
await expect(page.locator("table").locator("tbody")).not.toBeEmpty();
@@ -300,131 +70,11 @@ test.describe("datakilde list work", () => {
await expect(page.locator("#feed-sourceTitle")).not.toBeVisible();
await page.route("**/feed-sources*", async (route) => {
- const json = {
- "@context": "/contexts/FeedSource",
- "@id": "/v2/feed-sources",
- "@type": "hydra:Collection",
- "hydra:totalItems": 2,
- "hydra:member": [
- {
- "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
- "@type": "FeedSource",
- title: "feed_source_abc_notified",
- description:
- "Ut magnam veritatis velit ut doloribus id. Consequatur ut ipsum exercitationem aliquam laudantium voluptate voluptates perspiciatis. Id occaecati ea rerum facilis molestias et.",
- outputType: "",
- feedType: "App\\Feed\\RssFeedType",
- secrets: [],
- feeds: ["/v2/feeds/01GJD7S1KR10811MTA176C001R"],
- admin: [
- {
- key: "rss-url",
- input: "input",
- name: "url",
- type: "url",
- label: "Kilde",
- helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
- },
- {
- key: "rss-number-of-entries",
- input: "input",
- name: "numberOfEntries",
- type: "number",
- label: "Antal indgange",
- helpText:
- "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
- },
- {
- key: "rss-entry-duration",
- input: "input",
- name: "entryDuration",
- type: "number",
- label: "Varighed pr. indgang (i sekunder)",
- helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
- ],
- supportedFeedOutputType: "instagram",
- modifiedBy: "",
- createdBy: "",
- id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
- created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z",
- },
- {
- "@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
- "@type": "FeedSource",
- title: "feed_source_abc_1",
- description:
- "Totam eos molestias omnis aliquam quia qui voluptas. Non eum nihil ut sunt dolor.",
- outputType: "",
- feedType: "App\\Feed\\RssFeedType",
- secrets: [],
- feeds: ["/v2/feeds/01HD49075G0FNY1FNX12VE17K1"],
- admin: [
- {
- key: "rss-url",
- input: "input",
- name: "url",
- type: "url",
- label: "Kilde",
- helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
- },
- {
- key: "rss-number-of-entries",
- input: "input",
- name: "numberOfEntries",
- type: "number",
- label: "Antal indgange",
- helpText:
- "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
- },
- {
- key: "rss-entry-duration",
- input: "input",
- name: "entryDuration",
- type: "number",
- label: "Varighed pr. indgang (i sekunder)",
- helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
- ],
- supportedFeedOutputType: "rss",
- modifiedBy: "",
- createdBy: "",
- id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
- created: "2024-06-29T05:47:07.000Z",
- modified: "2024-10-21T18:01:25.000Z",
- },
- ],
- };
- await route.fulfill({ json });
+ await route.fulfill({ json: feedSourcesJson2 });
});
await page.route("**/feed-sources/*", async (route) => {
- const json = {
- "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
- "@type": "FeedSource",
- title: "feed_source_abc_notified",
- description:
- "Ut magnam veritatis velit ut doloribus id. Consequatur ut ipsum exercitationem aliquam laudantium voluptate voluptates perspiciatis. Id occaecati ea rerum facilis molestias et.",
- outputType: "",
- feedType: "App\\Feed\\RssFeedType",
- secrets: [],
- feeds: ["/v2/feeds/01GJD7S1KR10811MTA176C001R"],
- supportedFeedOutputType: "instagram",
- modifiedBy: "",
- createdBy: "",
- id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
- created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z",
- };
-
- await route.fulfill({ json });
+ await route.fulfill({ json: feedSourcesJson3 });
});
await page.locator("tbody").locator("tr td a").first().click();
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
new file mode 100644
index 00000000..75575fb9
--- /dev/null
+++ b/assets/tests/admin/data-fixtures.js
@@ -0,0 +1,343 @@
+const tokenJson = {
+ token: "1",
+ refresh_token: "2",
+ tenants: [
+ {
+ tenantKey: "ABC",
+ title: "ABC Tenant",
+ description: "Description",
+ roles: ["ROLE_ADMIN"],
+ },
+ ],
+ user: {
+ fullname: "John Doe",
+ email: "johndoe@example.com",
+ },
+};
+
+const feedSourcesJson = {
+ "@context": "/contexts/FeedSource",
+ "@id": "/v2/feed-sources",
+ "@type": "hydra:Collection",
+ "hydra:totalItems": 5,
+ "hydra:member": [
+ {
+ "@id": "/v2/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ",
+ "@type": "FeedSource",
+ title: "test 2",
+ description: "test 2",
+ outputType: "",
+ feedType: "test 2",
+ secrets: [],
+ feeds: [],
+ admin: [],
+ supportedFeedOutputType: "test 2",
+ modifiedBy: "admin@example.com",
+ createdBy: "admin@example.com",
+ id: "01JBBP48CS9CV80XRWRP8CAETJ",
+ created: "2024-10-29T09:26:25.000Z",
+ modified: "2024-10-29T09:26:25.000Z",
+ },
+ {
+ "@id": "/v2/feed-sources/01JB9MSQEH75HC3GG75XCVP2WH",
+ "@type": "FeedSource",
+ title: "Ny datakilde test 3",
+ description: "Ny datakilde test 3",
+ outputType: "",
+ feedType: "App\\Feed\\RssFeedType",
+ secrets: [],
+ feeds: [
+ "/v2/feeds/01JB9R7EPN9NPW117C22NY31KH",
+ "/v2/feeds/01JBBQMF72W2V36TWF6VXFA5Z7",
+ ],
+ admin: [
+ {
+ key: "rss-url",
+ input: "input",
+ name: "url",
+ type: "url",
+ label: "Kilde",
+ helpText: "Her kan du skrive rss kilden",
+ formGroupClasses: "col-md-6",
+ },
+ {
+ key: "rss-number-of-entries",
+ input: "input",
+ name: "numberOfEntries",
+ type: "number",
+ label: "Antal indgange",
+ helpText:
+ "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ {
+ key: "rss-entry-duration",
+ input: "input",
+ name: "entryDuration",
+ type: "number",
+ label: "Varighed pr. indgang (i sekunder)",
+ helpText: "Her skal du skrive varigheden pr. indgang.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ ],
+ supportedFeedOutputType: "rss",
+ modifiedBy: "admin@example.com",
+ createdBy: "admin@example.com",
+ id: "01JB9MSQEH75HC3GG75XCVP2WH",
+ created: "2024-10-28T14:24:43.000Z",
+ modified: "2024-10-28T15:23:28.000Z",
+ },
+ {
+ "@id": "/v2/feed-sources/01JB1DH8G4CXKGX5JRTYDHDPSP",
+ "@type": "FeedSource",
+ title: "Calendar datakilde test",
+ description: "test",
+ outputType: "",
+ feedType: "App\\Feed\\CalendarApiFeedType",
+ secrets: [],
+ feeds: [],
+ admin: [],
+ supportedFeedOutputType: "calendar",
+ modifiedBy: "",
+ createdBy: "",
+ id: "01JB1DH8G4CXKGX5JRTYDHDPSP",
+ created: "2024-10-25T10:43:50.000Z",
+ modified: "2024-10-25T10:43:50.000Z",
+ },
+ {
+ "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+ "@type": "FeedSource",
+ title: "feed_source_abc_notified",
+ description:
+ "Ut magnam veritatis velit ut doloribus id. Consequatur ut ipsum exercitationem aliquam laudantium voluptate voluptates perspiciatis. Id occaecati ea rerum facilis molestias et.",
+ outputType: "",
+ feedType: "App\\Feed\\RssFeedType",
+ secrets: [],
+ feeds: ["/v2/feeds/01GJD7S1KR10811MTA176C001R"],
+ admin: [
+ {
+ key: "rss-url",
+ input: "input",
+ name: "url",
+ type: "url",
+ label: "Kilde",
+ helpText: "Her kan du skrive rss kilden",
+ formGroupClasses: "col-md-6",
+ },
+ {
+ key: "rss-number-of-entries",
+ input: "input",
+ name: "numberOfEntries",
+ type: "number",
+ label: "Antal indgange",
+ helpText:
+ "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ {
+ key: "rss-entry-duration",
+ input: "input",
+ name: "entryDuration",
+ type: "number",
+ label: "Varighed pr. indgang (i sekunder)",
+ helpText: "Her skal du skrive varigheden pr. indgang.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ ],
+ supportedFeedOutputType: "instagram",
+ modifiedBy: "",
+ createdBy: "",
+ id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+ created: "2024-09-05T12:18:20.000Z",
+ modified: "2024-09-17T09:33:12.000Z",
+ },
+ {
+ "@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
+ "@type": "FeedSource",
+ title: "feed_source_abc_1",
+ description:
+ "Totam eos molestias omnis aliquam quia qui voluptas. Non eum nihil ut sunt dolor.",
+ outputType: "",
+ feedType: "App\\Feed\\RssFeedType",
+ secrets: [],
+ feeds: ["/v2/feeds/01HD49075G0FNY1FNX12VE17K1"],
+ admin: [
+ {
+ key: "rss-url",
+ input: "input",
+ name: "url",
+ type: "url",
+ label: "Kilde",
+ helpText: "Her kan du skrive rss kilden",
+ formGroupClasses: "col-md-6",
+ },
+ {
+ key: "rss-number-of-entries",
+ input: "input",
+ name: "numberOfEntries",
+ type: "number",
+ label: "Antal indgange",
+ helpText:
+ "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ {
+ key: "rss-entry-duration",
+ input: "input",
+ name: "entryDuration",
+ type: "number",
+ label: "Varighed pr. indgang (i sekunder)",
+ helpText: "Her skal du skrive varigheden pr. indgang.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ ],
+ supportedFeedOutputType: "rss",
+ modifiedBy: "",
+ createdBy: "",
+ id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
+ created: "2024-06-29T05:47:07.000Z",
+ modified: "2024-10-21T18:01:25.000Z",
+ },
+ ],
+};
+
+const feedSourcesJson2 = {
+ "@context": "/contexts/FeedSource",
+ "@id": "/v2/feed-sources",
+ "@type": "hydra:Collection",
+ "hydra:totalItems": 2,
+ "hydra:member": [
+ {
+ "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+ "@type": "FeedSource",
+ title: "feed_source_abc_notified",
+ description:
+ "Ut magnam veritatis velit ut doloribus id. Consequatur ut ipsum exercitationem aliquam laudantium voluptate voluptates perspiciatis. Id occaecati ea rerum facilis molestias et.",
+ outputType: "",
+ feedType: "App\\Feed\\RssFeedType",
+ secrets: [],
+ feeds: ["/v2/feeds/01GJD7S1KR10811MTA176C001R"],
+ admin: [
+ {
+ key: "rss-url",
+ input: "input",
+ name: "url",
+ type: "url",
+ label: "Kilde",
+ helpText: "Her kan du skrive rss kilden",
+ formGroupClasses: "col-md-6",
+ },
+ {
+ key: "rss-number-of-entries",
+ input: "input",
+ name: "numberOfEntries",
+ type: "number",
+ label: "Antal indgange",
+ helpText:
+ "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ {
+ key: "rss-entry-duration",
+ input: "input",
+ name: "entryDuration",
+ type: "number",
+ label: "Varighed pr. indgang (i sekunder)",
+ helpText: "Her skal du skrive varigheden pr. indgang.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ ],
+ supportedFeedOutputType: "instagram",
+ modifiedBy: "",
+ createdBy: "",
+ id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+ created: "2024-09-05T12:18:20.000Z",
+ modified: "2024-09-17T09:33:12.000Z",
+ },
+ {
+ "@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
+ "@type": "FeedSource",
+ title: "feed_source_abc_1",
+ description:
+ "Totam eos molestias omnis aliquam quia qui voluptas. Non eum nihil ut sunt dolor.",
+ outputType: "",
+ feedType: "App\\Feed\\RssFeedType",
+ secrets: [],
+ feeds: ["/v2/feeds/01HD49075G0FNY1FNX12VE17K1"],
+ admin: [
+ {
+ key: "rss-url",
+ input: "input",
+ name: "url",
+ type: "url",
+ label: "Kilde",
+ helpText: "Her kan du skrive rss kilden",
+ formGroupClasses: "col-md-6",
+ },
+ {
+ key: "rss-number-of-entries",
+ input: "input",
+ name: "numberOfEntries",
+ type: "number",
+ label: "Antal indgange",
+ helpText:
+ "Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ {
+ key: "rss-entry-duration",
+ input: "input",
+ name: "entryDuration",
+ type: "number",
+ label: "Varighed pr. indgang (i sekunder)",
+ helpText: "Her skal du skrive varigheden pr. indgang.",
+ formGroupClasses: "col-md-6 mb-3",
+ },
+ ],
+ supportedFeedOutputType: "rss",
+ modifiedBy: "",
+ createdBy: "",
+ id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
+ created: "2024-06-29T05:47:07.000Z",
+ modified: "2024-10-21T18:01:25.000Z",
+ },
+ ],
+};
+
+const feedSourcesJson3 = {
+ "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+ "@type": "FeedSource",
+ title: "feed_source_abc_notified",
+ description:
+ "Ut magnam veritatis velit ut doloribus id. Consequatur ut ipsum exercitationem aliquam laudantium voluptate voluptates perspiciatis. Id occaecati ea rerum facilis molestias et.",
+ outputType: "",
+ feedType: "App\\Feed\\RssFeedType",
+ secrets: [],
+ feeds: ["/v2/feeds/01GJD7S1KR10811MTA176C001R"],
+ supportedFeedOutputType: "instagram",
+ modifiedBy: "",
+ createdBy: "",
+ id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+ created: "2024-09-05T12:18:20.000Z",
+ modified: "2024-09-17T09:33:12.000Z",
+};
+
+const errorJson = {
+ "@context": "/contexts/Error",
+ "@type": "hydra:Error",
+ "hydra:title": "An error occurred",
+ "hydra:description": "An error occurred",
+};
+
+const emptySlidesJson = {
+ "@id": "/v2/slides",
+ "hydra:member": [],
+ "hydra:totalItems": 100,
+ "hydra:view": {
+ "@id": "/v2/slides?itemsPerPage=0\u0026title=",
+ "@type": "hydra:PartialCollectionView",
+ },
+};
+
+
+export { tokenJson, feedSourcesJson, feedSourcesJson2, feedSourcesJson3, errorJson, emptySlidesJson };
From 6e8c93faac65ba2894168804fd38d480f33064f6 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Sat, 5 Jul 2025 15:33:08 +0200
Subject: [PATCH 16/30] 4565: Fixed tests
---
assets/tests/admin/admin-campaign.spec.js | 4 ++--
assets/tests/admin/admin-feed-sources.spec.js | 7 +++----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index f545432b..748444a4 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -3,6 +3,8 @@ import { emptySlidesJson, tokenJson } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
test.beforeEach(async ({ page }) => {
+ await page.goto("/admin/campaign/create");
+
// Abort all routes that are not registered.
await page.route('**/*', async route => {
await route.abort();
@@ -16,8 +18,6 @@ test.describe("Campaign pages work", () => {
await route.fulfill({ json: tokenJson });
});
- await page.goto("/admin/campaign/create");
-
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 5af93790..6b476235 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -1,8 +1,10 @@
import { test, expect } from "@playwright/test";
-import { errorJson, feedSourcesJson, tokenJson } from "./data-fixtures.js";
+import { errorJson, feedSourcesJson, feedSourcesJson2, feedSourcesJson3, tokenJson } from "./data-fixtures.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
+ await page.goto("/admin/feed-sources/list");
+
// Abort all routes that are not registered.
await page.route('**/*', async route => {
await route.abort();
@@ -15,8 +17,6 @@ test.describe("feed sources", () => {
await route.fulfill({ json: tokenJson });
});
- await page.goto("/admin/feed-sources/list");
-
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("admin@example.com");
await page.getByLabel("Kodeord").fill("password");
@@ -25,7 +25,6 @@ test.describe("feed sources", () => {
});
test("It loads create datakilde page", async ({ page }) => {
- await page.goto("/admin/feed-sources/create");
page.getByText("Opret ny datakilde").click();
await expect(page.locator("#save")).toBeVisible();
});
From ae4e327937af46c302dcef94dc80b6de7e05e0b3 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Fri, 1 Aug 2025 11:24:25 +0200
Subject: [PATCH 17/30] Started work on refactor
---
assets/tests/admin/admin-app.spec.js | 65 +---
assets/tests/admin/admin-campaign.spec.js | 303 +-----------------
assets/tests/admin/admin-helper.js | 27 ++
assets/tests/admin/data-fixtures.js | 264 ++++++++++++++-
.../tests/template/template-calendar.spec.js | 2 +-
docker-compose.override.yml | 17 +-
vite.config.js | 29 +-
7 files changed, 339 insertions(+), 368 deletions(-)
create mode 100644 assets/tests/admin/admin-helper.js
diff --git a/assets/tests/admin/admin-app.spec.js b/assets/tests/admin/admin-app.spec.js
index d68ac70b..72a27239 100644
--- a/assets/tests/admin/admin-app.spec.js
+++ b/assets/tests/admin/admin-app.spec.js
@@ -1,65 +1,6 @@
-import { test, expect } from "@playwright/test";
+import { test } from "@playwright/test";
+import { loginTest } from "./admin-helper.js";
test.describe("Basic app", () => {
- test("App runs", async ({ page }) => {
- await page.goto("/admin/slide/list");
-
- // Abort all routes that are not registered.
- await page.route('**/*', async route => {
- await route.abort();
- });
-
- await page.route("**/slides*", async (route) => {
- const json = {
- "hydra:member": [
- {
- "@id": "/v2/slides/0086TQQC671WHA1S150MMF1Q3T",
- title: "Title on slide",
- description: "description",
- created: "1978-12-11T09:47:36.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/00MWCNKC4P0X5C0AT70E741E2V",
- },
- theme: "",
- onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
- duration: 70592,
- published: {
- from: null,
- to: "1989-08-28T18:14:52.000Z",
- },
- },
- ],
- };
- await route.fulfill({ json });
- });
-
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
-
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.getByText("Title on slide")).toBeVisible();
- });
+ test("App runs", loginTest);
});
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 748444a4..934ec13c 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,301 +1,30 @@
import { test, expect } from "@playwright/test";
-import { emptySlidesJson, tokenJson } from "./data-fixtures.js";
+import { loginTest } from "./admin-helper.js";
+import { emptySlidesJson, slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
- test.beforeEach(async ({ page }) => {
- await page.goto("/admin/campaign/create");
+ test.beforeEach( async ({ page }) => {
+ await loginTest({page});
- // Abort all routes that are not registered.
- await page.route('**/*', async route => {
- await route.abort();
- });
-
- await page.route("**/slides*", async (route) => {
+ await page.route("**/playlists*", async (route) => {
await route.fulfill({ json: emptySlidesJson });
});
- await page.route("**/token", async (route) => {
- await route.fulfill({ json: tokenJson });
- });
-
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(
- page.locator("h1").getByText("Opret ny kampagne"),
- ).toBeVisible();
+ await page.locator('.sidebar-nav .nav-link').getByText("Kampagner").click();
+ await expect(page.locator('h1').getByText("Kampagner")).toBeVisible();
+ await page.getByText("Opret ny kampagne").click();
});
- test("It loads create campaign page", async ({ page }) => {
- await expect(page.locator("#save_playlist")).toBeVisible();
+ test("It cancels create campaign", async ({ page }) => {
+ await expect(page.locator("#cancel_playlist")).toBeVisible();
+ await page.locator("#cancel_playlist").click();
+ await expect(page.locator("#cancel_playlist")).not.toBeVisible();
});
test("It removes slide", async ({ page }) => {
// Intercept slides in dropdown
await page.route("**/slides*", async (route) => {
- const json = {
- "@id": "/v2/slides",
- "hydra:member": [
- {
- "@type": "Slide",
- "@id": "/v2/slides/00015Y0ZVC18N407JD07SM0YCF",
- title: "Odio quidem ab dolores dolores.",
- description:
- "Accusamus odio atque numquam sunt asperiores ab. Consequatur similique amet velit sit qui doloremque dicta. Ducimus repellat facere odit quia deserunt id quos.",
- created: "1970-01-15T17:36:43.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0Y8",
- onPlaylists: [],
- duration: 107879,
- published: {
- from: null,
- to: null,
- },
- media: [
- "/v2/media/00042YZWK214MP01NA1GF517Q2",
- "/v2/media/00TET3FF6K1Q011N5S12621E4H",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK",
- ],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/000E7VDT9E0GEJ0W5X040T1CB1",
- title: "Sed ex quo minus doloremque possimus.",
- description:
- "Ipsum quo ipsam rerum ullam labore fugit ut. Repellendus a iusto dolore veritatis. Aut vero assumenda voluptates tempore doloremque expedita pariatur. Sint ducimus qui ducimus asperiores cum.",
- created: "1970-06-27T00:53:51.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 80335,
- published: {
- from: "2021-03-19T22:20:54.000Z",
- to: "2021-12-28T06:13:08.000Z",
- },
- media: [
- "/v2/media/009H64MSPN1HEH0DTV2DEV085B",
- "/v2/media/00SC0JP6PV2QYS06R70SS31K68",
- ],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/001M5VMMV81A6Q1KN10QY90HKE",
- title: "Maxime numquam ducimus quos non.",
- description:
- "Aut ex id earum unde aut itaque vero id. Sunt praesentium harum vel autem.",
- created: "1971-10-11T12:15:35.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 21254,
- published: {
- from: null,
- to: null,
- },
- media: ["/v2/media/00YMKGY3FM106Q0SRV077G0KEX"],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/001M9W40CC0DQE02DR0PS41J7X",
- title: "Est doloremque culpa et facere.",
- description:
- "Eos voluptatem sint fugiat magni omnis aut ut. Odit quod non rerum dolor. Quis deleniti occaecati perspiciatis et esse dolorum. Impedit sunt dolor dolores.",
- created: "1971-10-13T01:40:56.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 60870,
- published: {
- from: "2021-02-26T20:12:10.000Z",
- to: "2021-06-08T05:44:41.000Z",
- },
- media: ["/v2/media/00BBYAKF190NMJ0FH118V91VV7"],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/001W87XHKC0CX10P4215RV2K9B",
- title: "Occaecati temporibus dolore maxime tenetur.",
- description:
- "Qui rem inventore non labore quam nihil in. Sunt rerum consequatur possimus cupiditate iure quo sit ratione. Et quis mollitia et.",
- created: "1972-01-19T20:34:13.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 75535,
- published: {
- from: null,
- to: "1996-02-16T00:54:17.000Z",
- },
- media: ["/v2/media/0027FWF7Y014RG0KW9053S1AX6"],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/0021MQ8MWP0MXK1NXB1J5918PM",
- title: "Excepturi sed qui.",
- description:
- "Expedita numquam sunt autem nostrum. Sed eos molestiae earum natus. Rerum consectetur et eius illo qui sunt sapiente. Est dolore veritatis cupiditate occaecati.",
- created: "1972-03-26T20:11:47.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 92829,
- published: {
- from: "2021-12-29T03:25:23.000Z",
- to: null,
- },
- media: ["/v2/media/001AX5W2S909NW0K5A0NVE0NS6"],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/002T3E98DP1KK410PC0F2P037P",
- title: "Voluptate aliquid maxime.",
- description:
- "Veniam labore odit omnis sint. Perferendis amet soluta quo quaerat nihil ex eius error.",
- created: "1973-01-24T19:40:11.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YN",
- onPlaylists: [],
- duration: 41589,
- published: {
- from: null,
- to: "1989-10-31T03:15:44.000Z",
- },
- media: [
- "/v2/media/00CX9N9EJE10WT1PVM10G51N13",
- "/v2/media/016HWRGVWJ170F1AF2099T13JW",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK",
- ],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00367HAGPF0XZA1SDN1ECH1NZX",
- title: "Non ut nobis reprehenderit pariatur.",
- description:
- "Iste asperiores reprehenderit et mollitia et. Molestias iusto repudiandae a qui accusantium nam vel nesciunt.",
- created: "1973-06-24T12:58:37.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 106091,
- published: {
- from: "2022-01-11T14:56:13.000Z",
- to: "2022-02-05T09:10:20.000Z",
- },
- media: ["/v2/media/00F1M5J6BY1GS517RP1T1B1306"],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/0039BTMNG61RJ606WT1QYN1X2K",
- title: "Iusto aut et dicta neque.",
- description:
- "Nihil esse quisquam aut aliquid velit vitae. Dignissimos sit eos voluptatem corporis qui. Maxime qui eaque magni dolor et. Dolorem est velit qui ratione iure provident architecto.",
- created: "1973-08-02T11:45:30.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/016MHSNKCH1PQW1VY615JC19Y3",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
- onPlaylists: [],
- duration: 79809,
- published: {
- from: "2021-08-10T06:26:30.000Z",
- to: "2021-08-12T15:26:21.000Z",
- },
- media: ["/v2/media/011ZBTXPF8123R1BA31CQR18HA"],
- content: [],
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00446YF1RP0KZH0WQK1QJM1S4T",
- title: "Inventore non nisi odit voluptatem et.",
- description:
- "Et in eum fugit culpa mollitia sunt. Et cupiditate molestias quia sapiente sint maxime qui. Beatae ad quod sed provident quas expedita exercitationem enim. Pariatur illo nam consequatur.",
- created: "1974-07-02T03:19:57.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WXAX8JMJTQHBV2BYEDM",
- onPlaylists: [],
- duration: 37983,
- published: {
- from: "2022-01-24T16:30:24.000Z",
- to: "2022-02-05T09:19:31.000Z",
- },
- media: [
- "/v2/media/0010X8D6JJ03G50T1J1FCW1XH6",
- "/v2/media/00F1M5J6BY1GS517RP1T1B1306",
- "/v2/media/00KXYB7Z291JXC1SY30G161HQD",
- ],
- content: [],
- },
- ],
- "hydra:totalItems": 60,
- };
- await route.fulfill({ json });
+ await route.fulfill({ json: slidesJson1 });
});
// Pick slide
@@ -329,10 +58,4 @@ test.describe("Campaign pages work", () => {
page.locator("#slides-section").locator("tbody"),
).not.toBeVisible();
});
-
- test("It cancels create campaign", async ({ page }) => {
- await expect(page.locator("#cancel_playlist")).toBeVisible();
- await page.locator("#cancel_playlist").click();
- await expect(page.locator("#cancel_playlist")).not.toBeVisible();
- });
});
diff --git a/assets/tests/admin/admin-helper.js b/assets/tests/admin/admin-helper.js
new file mode 100644
index 00000000..70163132
--- /dev/null
+++ b/assets/tests/admin/admin-helper.js
@@ -0,0 +1,27 @@
+import { emptySlidesJson, feedSourcesJson, tokenJson } from "./data-fixtures.js";
+import { expect } from "@playwright/test";
+
+const loginTest = async ({page}) => {
+ await page.goto("/admin/slides/list");
+
+ // Abort all routes that are not registered.
+ await page.route('**/*', async route => {
+ await route.abort();
+ });
+
+ await page.route("**/token", async (route) => {
+ await route.fulfill({ json: tokenJson });
+ });
+
+ await page.route("**/slides*", async (route) => {
+ await route.fulfill({ json: emptySlidesJson });
+ });
+
+ await expect(page).toHaveTitle(/OS2Display Admin/);
+ await page.getByLabel("Email").fill("admin@example.com");
+ await page.getByLabel("Kodeord").fill("password");
+ await page.locator("#login").click();
+ await expect(page.locator("h1").getByText("Slides")).toBeVisible();
+}
+
+export { loginTest };
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index 75575fb9..2f2f30e6 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -339,5 +339,267 @@ const emptySlidesJson = {
},
};
+const slidesJson1 = {
+ "@id": "/v2/slides",
+ "hydra:member": [
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00015Y0ZVC18N407JD07SM0YCF",
+ title: "Odio quidem ab dolores dolores.",
+ description:
+ "Accusamus odio atque numquam sunt asperiores ab. Consequatur similique amet velit sit qui doloremque dicta. Ducimus repellat facere odit quia deserunt id quos.",
+ created: "1970-01-15T17:36:43.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0Y8",
+ onPlaylists: [],
+ duration: 107879,
+ published: {
+ from: null,
+ to: null,
+ },
+ media: [
+ "/v2/media/00042YZWK214MP01NA1GF517Q2",
+ "/v2/media/00TET3FF6K1Q011N5S12621E4H",
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK",
+ ],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/000E7VDT9E0GEJ0W5X040T1CB1",
+ title: "Sed ex quo minus doloremque possimus.",
+ description:
+ "Ipsum quo ipsam rerum ullam labore fugit ut. Repellendus a iusto dolore veritatis. Aut vero assumenda voluptates tempore doloremque expedita pariatur. Sint ducimus qui ducimus asperiores cum.",
+ created: "1970-06-27T00:53:51.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 80335,
+ published: {
+ from: "2021-03-19T22:20:54.000Z",
+ to: "2021-12-28T06:13:08.000Z",
+ },
+ media: [
+ "/v2/media/009H64MSPN1HEH0DTV2DEV085B",
+ "/v2/media/00SC0JP6PV2QYS06R70SS31K68",
+ ],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/001M5VMMV81A6Q1KN10QY90HKE",
+ title: "Maxime numquam ducimus quos non.",
+ description:
+ "Aut ex id earum unde aut itaque vero id. Sunt praesentium harum vel autem.",
+ created: "1971-10-11T12:15:35.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 21254,
+ published: {
+ from: null,
+ to: null,
+ },
+ media: ["/v2/media/00YMKGY3FM106Q0SRV077G0KEX"],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/001M9W40CC0DQE02DR0PS41J7X",
+ title: "Est doloremque culpa et facere.",
+ description:
+ "Eos voluptatem sint fugiat magni omnis aut ut. Odit quod non rerum dolor. Quis deleniti occaecati perspiciatis et esse dolorum. Impedit sunt dolor dolores.",
+ created: "1971-10-13T01:40:56.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 60870,
+ published: {
+ from: "2021-02-26T20:12:10.000Z",
+ to: "2021-06-08T05:44:41.000Z",
+ },
+ media: ["/v2/media/00BBYAKF190NMJ0FH118V91VV7"],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/001W87XHKC0CX10P4215RV2K9B",
+ title: "Occaecati temporibus dolore maxime tenetur.",
+ description:
+ "Qui rem inventore non labore quam nihil in. Sunt rerum consequatur possimus cupiditate iure quo sit ratione. Et quis mollitia et.",
+ created: "1972-01-19T20:34:13.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 75535,
+ published: {
+ from: null,
+ to: "1996-02-16T00:54:17.000Z",
+ },
+ media: ["/v2/media/0027FWF7Y014RG0KW9053S1AX6"],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/0021MQ8MWP0MXK1NXB1J5918PM",
+ title: "Excepturi sed qui.",
+ description:
+ "Expedita numquam sunt autem nostrum. Sed eos molestiae earum natus. Rerum consectetur et eius illo qui sunt sapiente. Est dolore veritatis cupiditate occaecati.",
+ created: "1972-03-26T20:11:47.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 92829,
+ published: {
+ from: "2021-12-29T03:25:23.000Z",
+ to: null,
+ },
+ media: ["/v2/media/001AX5W2S909NW0K5A0NVE0NS6"],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/002T3E98DP1KK410PC0F2P037P",
+ title: "Voluptate aliquid maxime.",
+ description:
+ "Veniam labore odit omnis sint. Perferendis amet soluta quo quaerat nihil ex eius error.",
+ created: "1973-01-24T19:40:11.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YN",
+ onPlaylists: [],
+ duration: 41589,
+ published: {
+ from: null,
+ to: "1989-10-31T03:15:44.000Z",
+ },
+ media: [
+ "/v2/media/00CX9N9EJE10WT1PVM10G51N13",
+ "/v2/media/016HWRGVWJ170F1AF2099T13JW",
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK",
+ ],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00367HAGPF0XZA1SDN1ECH1NZX",
+ title: "Non ut nobis reprehenderit pariatur.",
+ description:
+ "Iste asperiores reprehenderit et mollitia et. Molestias iusto repudiandae a qui accusantium nam vel nesciunt.",
+ created: "1973-06-24T12:58:37.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 106091,
+ published: {
+ from: "2022-01-11T14:56:13.000Z",
+ to: "2022-02-05T09:10:20.000Z",
+ },
+ media: ["/v2/media/00F1M5J6BY1GS517RP1T1B1306"],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/0039BTMNG61RJ606WT1QYN1X2K",
+ title: "Iusto aut et dicta neque.",
+ description:
+ "Nihil esse quisquam aut aliquid velit vitae. Dignissimos sit eos voluptatem corporis qui. Maxime qui eaque magni dolor et. Dolorem est velit qui ratione iure provident architecto.",
+ created: "1973-08-02T11:45:30.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/016MHSNKCH1PQW1VY615JC19Y3",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
+ onPlaylists: [],
+ duration: 79809,
+ published: {
+ from: "2021-08-10T06:26:30.000Z",
+ to: "2021-08-12T15:26:21.000Z",
+ },
+ media: ["/v2/media/011ZBTXPF8123R1BA31CQR18HA"],
+ content: [],
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00446YF1RP0KZH0WQK1QJM1S4T",
+ title: "Inventore non nisi odit voluptatem et.",
+ description:
+ "Et in eum fugit culpa mollitia sunt. Et cupiditate molestias quia sapiente sint maxime qui. Beatae ad quod sed provident quas expedita exercitationem enim. Pariatur illo nam consequatur.",
+ created: "1974-07-02T03:19:57.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WXAX8JMJTQHBV2BYEDM",
+ onPlaylists: [],
+ duration: 37983,
+ published: {
+ from: "2022-01-24T16:30:24.000Z",
+ to: "2022-02-05T09:19:31.000Z",
+ },
+ media: [
+ "/v2/media/0010X8D6JJ03G50T1J1FCW1XH6",
+ "/v2/media/00F1M5J6BY1GS517RP1T1B1306",
+ "/v2/media/00KXYB7Z291JXC1SY30G161HQD",
+ ],
+ content: [],
+ },
+ ],
+ "hydra:totalItems": 60,
+};
+
-export { tokenJson, feedSourcesJson, feedSourcesJson2, feedSourcesJson3, errorJson, emptySlidesJson };
+export { tokenJson, feedSourcesJson, feedSourcesJson2, feedSourcesJson3, errorJson, emptySlidesJson, slidesJson1 };
diff --git a/assets/tests/template/template-calendar.spec.js b/assets/tests/template/template-calendar.spec.js
index 09ba1dfa..c24eb9ad 100644
--- a/assets/tests/template/template-calendar.spec.js
+++ b/assets/tests/template/template-calendar.spec.js
@@ -32,7 +32,7 @@ test("Calendar 1", async ({ page }) => {
await expect(page.locator(".header-title")).toHaveText(
"Møder i dag på Bautavej",
);
- await expect(page.locator(".header-date")).toHaveText(new RegExp("06:00"));
+ await expect(page.locator(".header-date")).toHaveText(new RegExp("06:"));
await expect(page.locator(".content-item")).toHaveCount(3);
await expect(page.getByText("Hvad")).toBeVisible();
await expect(page.getByText("Hvornår")).toBeVisible();
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 323243a2..2aa3bb4a 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -1,4 +1,10 @@
services:
+ nginx:
+ labels:
+ # HTTPS config - uncomment to enable redirect from :80 to :443
+ - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=redirect-to-https"
+ - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
+
redis:
image: "redis:6"
networks:
@@ -9,16 +15,23 @@ services:
node:
image: node:24
command: npm run dev
- ports:
- - "5173:5173"
networks:
- app
- frontend
+ ports:
+ - "5173"
working_dir: /app
environment:
- NODE_ENV=development
volumes:
- .:/app:delegated
+ labels:
+ - "traefik.enable=true"
+ - "traefik.docker.network=frontend"
+ - "traefik.http.routers.${COMPOSE_PROJECT_NAME}node.rule=Host(`node-${COMPOSE_DOMAIN}`)"
+ # HTTPS config - uncomment to enable redirect from :80 to :443
+# - "traefik.http.routers.${COMPOSE_PROJECT_NAME}node.middlewares=redirect-to-https"
+# - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
playwright:
# https://playwright.dev/docs/docker
diff --git a/vite.config.js b/vite.config.js
index 4886cdc6..71e96119 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,29 +1,29 @@
-import {defineConfig} from "vite";
+import { defineConfig } from "vite";
import symfonyPlugin from "vite-plugin-symfony";
import react from "@vitejs/plugin-react-oxc";
import svgr from "vite-plugin-svgr";
-export default defineConfig(({command}) => {
+export default defineConfig(({ command }) => {
return {
base: "/build",
css: {
preprocessorOptions: {
scss: {
quietDeps: true
- },
+ }
}
},
experimental: {
- enableNativePlugin: true,
+ enableNativePlugin: true
},
plugins: [
react(),
symfonyPlugin(),
svgr({
// svgr options: https://react-svgr.com/docs/options/
- svgrOptions: {exportType: "default", ref: true, svgo: false, titleProp: true},
- include: "**/*.svg",
- }),
+ svgrOptions: { exportType: "default", ref: true, svgo: false, titleProp: true },
+ include: "**/*.svg"
+ })
],
build: {
outDir: "./public/build",
@@ -36,12 +36,17 @@ export default defineConfig(({command}) => {
admin: "./assets/admin/index.jsx",
client: "./assets/client/index.jsx",
template: "./assets/shared/template/index.jsx"
- },
- },
+ }
+ }
},
server: {
host: "0.0.0.0",
- cors: true,
- },
- }
+ hmr: {
+ host: "node-display.local.itkdev.dk",
+ protocol: "wss",
+ clientPort: 443
+ },
+ cors: true
+ }
+ };
});
From 0e65fb67feb8c36ae18178a798003ecadba1c95a Mon Sep 17 00:00:00 2001
From: Sine Jespersen
Date: Fri, 1 Aug 2025 13:15:11 +0200
Subject: [PATCH 18/30] 4565: bash script argument and error handling
---
scripts/test | 24 ++++++++++++++++++++++++
scripts/test.sh | 8 --------
2 files changed, 24 insertions(+), 8 deletions(-)
create mode 100755 scripts/test
delete mode 100755 scripts/test.sh
diff --git a/scripts/test b/scripts/test
new file mode 100755
index 00000000..ed98d4a3
--- /dev/null
+++ b/scripts/test
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+# -o errexit: Exit immediately if a command exits with a non-zero status.
+# -o errtrace: Ensures that the ERR trap is also triggered when the error occurs inside a function or a subshell. (https://stackoverflow.com/questions/25378845/what-does-set-o-errtrace-do-in-a-shell-script)
+# -o noclobber: Prevents accidentally overwriting files with output redirection.
+# -o nounset: This command will cause the shell to exit if a variable is accessed before it is set.
+# -o pipefail: Ensures that a pipeline return the exit status of the command that first fails.
+set -o errexit -o errtrace -o noclobber -o nounset -o pipefail
+
+TEST_PATH="${1:-}"
+
+# Stop node container to avoid build conflicts.
+docker compose stop node
+# Build assets.
+docker compose run --rm node npm run build
+
+# Run tests (with or without a test path)
+if [[ -n "$TEST_PATH" ]]; then
+ docker compose run --rm playwright npx playwright test "$TEST_PATH"
+else
+ docker compose run --rm playwright npx playwright test
+fi
+# Restart node container.
+docker compose start node
diff --git a/scripts/test.sh b/scripts/test.sh
deleted file mode 100755
index aa6cdc02..00000000
--- a/scripts/test.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-# Stop node container to avoid build conflicts.
-docker compose stop node
-# Build assets.
-docker compose run --rm node npm run build
-# Run tests.
-docker compose run --rm playwright npx playwright test ${TEMPLATE_FILTER}
-# Restart node container.
-docker compose start node
From 70aca235020c177366192b016551c1119970335b Mon Sep 17 00:00:00 2001
From: Sine Jespersen
Date: Fri, 1 Aug 2025 13:15:22 +0200
Subject: [PATCH 19/30] 4565: documentation of test script added
---
docs/test.md | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/docs/test.md b/docs/test.md
index 1fb947d9..d0ed9808 100644
--- a/docs/test.md
+++ b/docs/test.md
@@ -12,6 +12,18 @@ See the `docker-compose.override.yml` playwright entry and the version imported
### Dev mode
+This project includes a test script that handles building assets, running
+Playwright tests, and stops and starts the node container. This script tests the
+*built* files.
+
+```bash
+./scripts/test {TEST-PATH}
+```
+
+TEST-PATH is optional, and is the specific test file or directory to run like
+`admin`/`client`/`template` or a specific file, e.g. `admin-app.spec.js`. If
+TEST-PATH is omitted, all tests will run.
+
To run tests locally, there are a few options.
To run from the developer machine:
From 9bd0560cfcd325df6d503aa5a0c48896393127da Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 7 Aug 2025 08:16:16 +0200
Subject: [PATCH 20/30] 4565: Fixed campaign test
---
assets/tests/admin/admin-campaign.spec.js | 6 ++++--
docker-compose.override.yml | 4 ++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 934ec13c..84dad8d5 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -53,9 +53,11 @@ test.describe("Campaign pages work", () => {
).toHaveCount(6);
// Remove slide
- await page.locator(".remove-from-list").click({ force: true });
+ await page.locator(".remove-from-list").click({ force: false });
+
+ // See that slides section is removed.
await expect(
- page.locator("#slides-section").locator("tbody"),
+ page.getByText("Afspilningsrækkefølge"),
).not.toBeVisible();
});
});
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 2aa3bb4a..efb2d29e 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -30,8 +30,8 @@ services:
- "traefik.docker.network=frontend"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}node.rule=Host(`node-${COMPOSE_DOMAIN}`)"
# HTTPS config - uncomment to enable redirect from :80 to :443
-# - "traefik.http.routers.${COMPOSE_PROJECT_NAME}node.middlewares=redirect-to-https"
-# - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
+ - "traefik.http.routers.${COMPOSE_PROJECT_NAME}node.middlewares=redirect-to-https"
+ - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
playwright:
# https://playwright.dev/docs/docker
From 31beaa967b88e97bbfe6402e5bfac069a4a5cd7b Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 7 Aug 2025 08:35:51 +0200
Subject: [PATCH 21/30] 4565: Reverted to use swc instead of oxc
---
package-lock.json | 2587 +++++++++++++++++----------------------------
package.json | 4 +-
vite.config.js | 4 +-
3 files changed, 978 insertions(+), 1617 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5a6cc0d9..4e42d215 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -60,7 +60,7 @@
"@playwright/test": "1.53.2",
"@reduxjs/toolkit": "^1.6.1",
"@vitejs/plugin-react": "^4.6.0",
- "@vitejs/plugin-react-oxc": "^0.2.3",
+ "@vitejs/plugin-react-swc": "^3.11.0",
"sass": "^1.88.9",
"typescript": "^4.4.2",
"vite": "npm:rolldown-vite@^7.0.3",
@@ -118,30 +118,30 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.27.2",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz",
- "integrity": "sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
+ "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz",
- "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz",
+ "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.27.5",
+ "@babel/generator": "^7.28.0",
"@babel/helper-compilation-targets": "^7.27.2",
"@babel/helper-module-transforms": "^7.27.3",
"@babel/helpers": "^7.27.6",
- "@babel/parser": "^7.27.7",
+ "@babel/parser": "^7.28.0",
"@babel/template": "^7.27.2",
- "@babel/traverse": "^7.27.7",
- "@babel/types": "^7.27.7",
+ "@babel/traverse": "^7.28.0",
+ "@babel/types": "^7.28.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -157,15 +157,15 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.27.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
- "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz",
+ "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==",
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.27.5",
- "@babel/types": "^7.27.3",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
+ "@babel/parser": "^7.28.0",
+ "@babel/types": "^7.28.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
},
"engines": {
@@ -173,12 +173,12 @@
}
},
"node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz",
- "integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==",
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.1"
+ "@babel/types": "^7.27.3"
},
"engines": {
"node": ">=6.9.0"
@@ -200,6 +200,15 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-module-imports": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
@@ -267,25 +276,25 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.27.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
- "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz",
+ "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==",
"license": "MIT",
"dependencies": {
"@babel/template": "^7.27.2",
- "@babel/types": "^7.27.6"
+ "@babel/types": "^7.28.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz",
- "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
+ "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.7"
+ "@babel/types": "^7.28.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -342,9 +351,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
- "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
+ "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -365,27 +374,27 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.7.tgz",
- "integrity": "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz",
+ "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.27.5",
- "@babel/parser": "^7.27.7",
+ "@babel/generator": "^7.28.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.0",
"@babel/template": "^7.27.2",
- "@babel/types": "^7.27.7",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
+ "@babel/types": "^7.28.0",
+ "debug": "^4.3.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz",
- "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==",
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
+ "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
@@ -396,21 +405,21 @@
}
},
"node_modules/@emnapi/core": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz",
- "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==",
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz",
+ "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/wasi-threads": "1.0.2",
+ "@emnapi/wasi-threads": "1.0.4",
"tslib": "^2.4.0"
}
},
"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==",
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz",
+ "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -419,9 +428,9 @@
}
},
"node_modules/@emnapi/wasi-threads": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz",
- "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz",
+ "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -564,615 +573,165 @@
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
},
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz",
- "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
+ "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.10"
}
},
- "node_modules/@esbuild/android-arm": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz",
- "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz",
+ "integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@floating-ui/core": "^1.7.3",
+ "@floating-ui/utils": "^0.2.10"
}
},
- "node_modules/@esbuild/android-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz",
- "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
+ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
+ "license": "MIT"
+ },
+ "node_modules/@foliojs-fork/fontkit": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.2.tgz",
+ "integrity": "sha512-IfB5EiIb+GZk+77TRB86AHroVaqfq8JRFlUbz0WEwsInyCG0epX2tCPOy+UfaWPju30DeVoUAXfzWXmhn753KA==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@foliojs-fork/restructure": "^2.0.2",
+ "brotli": "^1.2.0",
+ "clone": "^1.0.4",
+ "deep-equal": "^1.0.0",
+ "dfa": "^1.2.0",
+ "tiny-inflate": "^1.0.2",
+ "unicode-properties": "^1.2.2",
+ "unicode-trie": "^2.0.0"
}
},
- "node_modules/@esbuild/android-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz",
- "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@foliojs-fork/linebreak": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/linebreak/-/linebreak-1.1.2.tgz",
+ "integrity": "sha512-ZPohpxxbuKNE0l/5iBJnOAfUaMACwvUIKCvqtWGKIMv1lPYoNjYXRfhi9FeeV9McBkBLxsMFWTVVhHJA8cyzvg==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "base64-js": "1.3.1",
+ "unicode-trie": "^2.0.0"
}
},
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz",
- "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@foliojs-fork/pdfkit": {
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/pdfkit/-/pdfkit-0.15.3.tgz",
+ "integrity": "sha512-Obc0Wmy3bm7BINFVvPhcl2rnSSK61DQrlHU8aXnAqDk9LCjWdUOPwhgD8Ywz5VtuFjRxmVOM/kQ/XLIBjDvltw==",
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@foliojs-fork/fontkit": "^1.9.2",
+ "@foliojs-fork/linebreak": "^1.1.1",
+ "crypto-js": "^4.2.0",
+ "jpeg-exif": "^1.1.4",
+ "png-js": "^1.0.0"
}
},
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz",
- "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@foliojs-fork/restructure": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
+ "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==",
+ "license": "MIT"
+ },
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "1.11.4",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
+ "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@formatjs/intl-localematcher": "0.2.25",
+ "tslib": "^2.1.0"
}
},
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz",
- "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz",
+ "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==",
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "tslib": "^2.1.0"
}
},
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz",
- "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz",
+ "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==",
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.11.4",
+ "@formatjs/icu-skeleton-parser": "1.3.6",
+ "tslib": "^2.1.0"
}
},
- "node_modules/@esbuild/linux-arm": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz",
- "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz",
+ "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.11.4",
+ "tslib": "^2.1.0"
}
},
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz",
- "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@formatjs/intl": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.2.1.tgz",
+ "integrity": "sha512-vgvyUOOrzqVaOFYzTf2d3+ToSkH2JpR7x/4U1RyoHQLmvEaTQvXJ7A2qm1Iy3brGNXC/+/7bUlc3lpH+h/LOJA==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.11.4",
+ "@formatjs/fast-memoize": "1.2.1",
+ "@formatjs/icu-messageformat-parser": "2.1.0",
+ "@formatjs/intl-displaynames": "5.4.3",
+ "@formatjs/intl-listformat": "6.5.3",
+ "intl-messageformat": "9.13.0",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "typescript": "^4.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz",
- "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
+ "node_modules/@formatjs/intl-displaynames": {
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-5.4.3.tgz",
+ "integrity": "sha512-4r12A3mS5dp5hnSaQCWBuBNfi9Amgx2dzhU4lTFfhSxgb5DOAiAbMpg6+7gpWZgl4ahsj3l2r/iHIjdmdXOE2Q==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.11.4",
+ "@formatjs/intl-localematcher": "0.2.25",
+ "tslib": "^2.1.0"
}
},
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz",
- "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
+ "node_modules/@formatjs/intl-listformat": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.3.tgz",
+ "integrity": "sha512-ozpz515F/+3CU+HnLi5DYPsLa6JoCfBggBSSg/8nOB5LYSFW9+ZgNQJxJ8tdhKYeODT+4qVHX27EeJLoxLGLNg==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.11.4",
+ "@formatjs/intl-localematcher": "0.2.25",
+ "tslib": "^2.1.0"
}
},
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz",
- "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz",
- "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz",
- "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz",
- "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz",
- "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz",
- "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz",
- "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz",
- "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz",
- "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz",
- "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz",
- "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz",
- "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz",
- "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@floating-ui/core": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.0.tgz",
- "integrity": "sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/utils": "^0.2.9"
- }
- },
- "node_modules/@floating-ui/dom": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.0.tgz",
- "integrity": "sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/core": "^1.7.0",
- "@floating-ui/utils": "^0.2.9"
- }
- },
- "node_modules/@floating-ui/utils": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
- "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
- "license": "MIT"
- },
- "node_modules/@foliojs-fork/fontkit": {
- "version": "1.9.2",
- "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.2.tgz",
- "integrity": "sha512-IfB5EiIb+GZk+77TRB86AHroVaqfq8JRFlUbz0WEwsInyCG0epX2tCPOy+UfaWPju30DeVoUAXfzWXmhn753KA==",
- "license": "MIT",
- "dependencies": {
- "@foliojs-fork/restructure": "^2.0.2",
- "brotli": "^1.2.0",
- "clone": "^1.0.4",
- "deep-equal": "^1.0.0",
- "dfa": "^1.2.0",
- "tiny-inflate": "^1.0.2",
- "unicode-properties": "^1.2.2",
- "unicode-trie": "^2.0.0"
- }
- },
- "node_modules/@foliojs-fork/linebreak": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@foliojs-fork/linebreak/-/linebreak-1.1.2.tgz",
- "integrity": "sha512-ZPohpxxbuKNE0l/5iBJnOAfUaMACwvUIKCvqtWGKIMv1lPYoNjYXRfhi9FeeV9McBkBLxsMFWTVVhHJA8cyzvg==",
- "license": "MIT",
- "dependencies": {
- "base64-js": "1.3.1",
- "unicode-trie": "^2.0.0"
- }
- },
- "node_modules/@foliojs-fork/pdfkit": {
- "version": "0.15.3",
- "resolved": "https://registry.npmjs.org/@foliojs-fork/pdfkit/-/pdfkit-0.15.3.tgz",
- "integrity": "sha512-Obc0Wmy3bm7BINFVvPhcl2rnSSK61DQrlHU8aXnAqDk9LCjWdUOPwhgD8Ywz5VtuFjRxmVOM/kQ/XLIBjDvltw==",
- "license": "MIT",
- "dependencies": {
- "@foliojs-fork/fontkit": "^1.9.2",
- "@foliojs-fork/linebreak": "^1.1.1",
- "crypto-js": "^4.2.0",
- "jpeg-exif": "^1.1.4",
- "png-js": "^1.0.0"
- }
- },
- "node_modules/@foliojs-fork/restructure": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
- "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==",
- "license": "MIT"
- },
- "node_modules/@formatjs/ecma402-abstract": {
- "version": "1.11.4",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
- "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/intl-localematcher": "0.2.25",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/@formatjs/fast-memoize": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz",
- "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.1.0"
- }
- },
- "node_modules/@formatjs/icu-messageformat-parser": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz",
- "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "1.11.4",
- "@formatjs/icu-skeleton-parser": "1.3.6",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/@formatjs/icu-skeleton-parser": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz",
- "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "1.11.4",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/@formatjs/intl": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.2.1.tgz",
- "integrity": "sha512-vgvyUOOrzqVaOFYzTf2d3+ToSkH2JpR7x/4U1RyoHQLmvEaTQvXJ7A2qm1Iy3brGNXC/+/7bUlc3lpH+h/LOJA==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "1.11.4",
- "@formatjs/fast-memoize": "1.2.1",
- "@formatjs/icu-messageformat-parser": "2.1.0",
- "@formatjs/intl-displaynames": "5.4.3",
- "@formatjs/intl-listformat": "6.5.3",
- "intl-messageformat": "9.13.0",
- "tslib": "^2.1.0"
- },
- "peerDependencies": {
- "typescript": "^4.5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@formatjs/intl-displaynames": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-5.4.3.tgz",
- "integrity": "sha512-4r12A3mS5dp5hnSaQCWBuBNfi9Amgx2dzhU4lTFfhSxgb5DOAiAbMpg6+7gpWZgl4ahsj3l2r/iHIjdmdXOE2Q==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "1.11.4",
- "@formatjs/intl-localematcher": "0.2.25",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/@formatjs/intl-listformat": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.3.tgz",
- "integrity": "sha512-ozpz515F/+3CU+HnLi5DYPsLa6JoCfBggBSSg/8nOB5LYSFW9+ZgNQJxJ8tdhKYeODT+4qVHX27EeJLoxLGLNg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "1.11.4",
- "@formatjs/intl-localematcher": "0.2.25",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/@formatjs/intl-localematcher": {
- "version": "0.2.25",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
- "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
+ "node_modules/@formatjs/intl-localematcher": {
+ "version": "0.2.25",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
+ "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
"license": "MIT",
"dependencies": {
"tslib": "^2.1.0"
@@ -1215,16 +774,16 @@
}
},
"node_modules/@fortawesome/react-fontawesome": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz",
- "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==",
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.3.tgz",
+ "integrity": "sha512-HlJco8RDY8NrzFVjy23b/7mNS4g9NegcrBG3n7jinwpc2x/AmSVk53IhWniLYM4szYLxRAFTAGwGn0EIlclDeQ==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
- "@fortawesome/fontawesome-svg-core": "~1 || ~6",
- "react": ">=16.3"
+ "@fortawesome/fontawesome-svg-core": "~1 || ~6 || ~7",
+ "react": "^16.3 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@hello-pangea/dnd": {
@@ -1292,17 +851,13 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
- "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "version": "0.3.12",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
+ "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
"license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
@@ -1314,25 +869,16 @@
"node": ">=6.0.0"
}
},
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
+ "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "version": "0.3.29",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
+ "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -1340,16 +886,16 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.11",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz",
- "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.1.tgz",
+ "integrity": "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@tybys/wasm-util": "^0.9.0"
+ "@emnapi/core": "^1.4.5",
+ "@emnapi/runtime": "^1.4.5",
+ "@tybys/wasm-util": "^0.10.0"
}
},
"node_modules/@nodelib/fs.scandir": {
@@ -1391,9 +937,9 @@
}
},
"node_modules/@oxc-project/runtime": {
- "version": "0.75.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.75.0.tgz",
- "integrity": "sha512-gzRmVI/vorsPmbDXt7GD4Uh2lD3rCOku/1xWPB4Yx48k0EP4TZmzQudWapjN4+7Vv+rgXr0RqCHQadeaMvdBuw==",
+ "version": "0.78.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.78.0.tgz",
+ "integrity": "sha512-jOU7sDFMyq5ShGJC21UobalVzqcdtWGfySVp8ELvKoVLzMpLHb4kv1bs9VKxaP8XC7Z9hlAXwEKVhCTN+j21aQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1401,9 +947,9 @@
}
},
"node_modules/@oxc-project/types": {
- "version": "0.75.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.75.0.tgz",
- "integrity": "sha512-QMW+06WOXs7+F301Y3X0VpmWhwuQVc/X/RP2zF9OIwvSMmsif3xURS2wxbakFIABYsytgBcHpUcFepVS0Qnd3A==",
+ "version": "0.78.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.78.0.tgz",
+ "integrity": "sha512-8FvExh0WRWN1FoSTjah1xa9RlavZcJQ8/yxRbZ7ElmSa2Ij5f5Em7MvRbSthE6FbwC6Wh8iAw0Gpna7QdoqLGg==",
"dev": true,
"license": "MIT",
"funding": {
@@ -1411,159 +957,54 @@
}
},
"node_modules/@parcel/watcher": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
- "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "detect-libc": "^1.0.3",
- "is-glob": "^4.0.3",
- "micromatch": "^4.0.5",
- "node-addon-api": "^7.0.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.1",
- "@parcel/watcher-darwin-arm64": "2.5.1",
- "@parcel/watcher-darwin-x64": "2.5.1",
- "@parcel/watcher-freebsd-x64": "2.5.1",
- "@parcel/watcher-linux-arm-glibc": "2.5.1",
- "@parcel/watcher-linux-arm-musl": "2.5.1",
- "@parcel/watcher-linux-arm64-glibc": "2.5.1",
- "@parcel/watcher-linux-arm64-musl": "2.5.1",
- "@parcel/watcher-linux-x64-glibc": "2.5.1",
- "@parcel/watcher-linux-x64-musl": "2.5.1",
- "@parcel/watcher-win32-arm64": "2.5.1",
- "@parcel/watcher-win32-ia32": "2.5.1",
- "@parcel/watcher-win32-x64": "2.5.1"
- }
- },
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
- "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
- "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
- "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
- "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
- "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
- "cpu": [
- "arm"
- ],
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
+ "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
"dev": true,
+ "hasInstallScript": true,
"license": "MIT",
"optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.5",
+ "node-addon-api": "^7.0.0"
+ },
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.1",
+ "@parcel/watcher-darwin-arm64": "2.5.1",
+ "@parcel/watcher-darwin-x64": "2.5.1",
+ "@parcel/watcher-freebsd-x64": "2.5.1",
+ "@parcel/watcher-linux-arm-glibc": "2.5.1",
+ "@parcel/watcher-linux-arm-musl": "2.5.1",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.1",
+ "@parcel/watcher-linux-arm64-musl": "2.5.1",
+ "@parcel/watcher-linux-x64-glibc": "2.5.1",
+ "@parcel/watcher-linux-x64-musl": "2.5.1",
+ "@parcel/watcher-win32-arm64": "2.5.1",
+ "@parcel/watcher-win32-ia32": "2.5.1",
+ "@parcel/watcher-win32-x64": "2.5.1"
}
},
- "node_modules/@parcel/watcher-linux-arm-musl": {
+ "node_modules/@parcel/watcher-android-arm64": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
- "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
+ "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
"cpu": [
- "arm"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "linux"
+ "android"
],
"engines": {
"node": ">= 10.0.0"
@@ -1573,10 +1014,10 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "node_modules/@parcel/watcher-darwin-arm64": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
- "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
+ "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
"cpu": [
"arm64"
],
@@ -1584,7 +1025,7 @@
"license": "MIT",
"optional": true,
"os": [
- "linux"
+ "darwin"
],
"engines": {
"node": ">= 10.0.0"
@@ -1594,18 +1035,18 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "node_modules/@parcel/watcher-darwin-x64": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
- "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
+ "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
"cpu": [
- "arm64"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "linux"
+ "darwin"
],
"engines": {
"node": ">= 10.0.0"
@@ -1615,10 +1056,10 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "node_modules/@parcel/watcher-freebsd-x64": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
- "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
+ "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
"cpu": [
"x64"
],
@@ -1626,7 +1067,7 @@
"license": "MIT",
"optional": true,
"os": [
- "linux"
+ "freebsd"
],
"engines": {
"node": ">= 10.0.0"
@@ -1636,12 +1077,12 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-linux-x64-musl": {
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
- "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
+ "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
"cpu": [
- "x64"
+ "arm"
],
"dev": true,
"license": "MIT",
@@ -1657,18 +1098,18 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-win32-arm64": {
+ "node_modules/@parcel/watcher-linux-arm-musl": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
- "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
+ "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
"cpu": [
- "arm64"
+ "arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "linux"
],
"engines": {
"node": ">= 10.0.0"
@@ -1678,18 +1119,18 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-win32-ia32": {
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
- "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
+ "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
"cpu": [
- "ia32"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "linux"
],
"engines": {
"node": ">= 10.0.0"
@@ -1699,18 +1140,18 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@parcel/watcher-win32-x64": {
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
"version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
- "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
+ "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
"cpu": [
- "x64"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "win32"
+ "linux"
],
"engines": {
"node": ">= 10.0.0"
@@ -1720,182 +1161,10 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/@playwright/test": {
- "version": "1.53.2",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz",
- "integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "playwright": "1.53.2"
- },
- "bin": {
- "playwright": "cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@polka/url": {
- "version": "1.0.0-next.29",
- "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
- "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@popperjs/core": {
- "version": "2.11.8",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
- "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/popperjs"
- }
- },
- "node_modules/@reduxjs/toolkit": {
- "version": "1.9.7",
- "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz",
- "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "immer": "^9.0.21",
- "redux": "^4.2.1",
- "redux-thunk": "^2.4.2",
- "reselect": "^4.1.8"
- },
- "peerDependencies": {
- "react": "^16.9.0 || ^17.0.0 || ^18",
- "react-redux": "^7.2.1 || ^8.0.2"
- },
- "peerDependenciesMeta": {
- "react": {
- "optional": true
- },
- "react-redux": {
- "optional": true
- }
- }
- },
- "node_modules/@remix-run/router": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
- "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@restart/context": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
- "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==",
- "license": "MIT",
- "peerDependencies": {
- "react": ">=16.3.2"
- }
- },
- "node_modules/@restart/hooks": {
- "version": "0.4.16",
- "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
- "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
- "license": "MIT",
- "dependencies": {
- "dequal": "^2.0.3"
- },
- "peerDependencies": {
- "react": ">=16.8.0"
- }
- },
- "node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.21.tgz",
- "integrity": "sha512-FFkhqqq4kz7UCa4mGkexdsPK5++31zBTnhUTYhDUX+hdCwcYOlh2r2WsjHY+fQCMbIJ2UqOdAIocVGirs6/f7w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.21.tgz",
- "integrity": "sha512-To/Ma+/5rxSoCVO/EInVCpQBB5YA4PDme0yYsbC5b76d+1OzuENaY4iq8vmCcEDZVnTU+xnfwfiMR9X+gB8W/w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.21.tgz",
- "integrity": "sha512-Z1lct0slFVDp08xzmRX6dPI7/uh6JG8dAswVdM4h5jjeXksC2AQpzBj4YgeX6t0OI428PC7FKP1k6T8HZS7Frg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.21.tgz",
- "integrity": "sha512-XKfjZLMODXpgHW1gZUkP/3giahuZD+35ft92nJX6qzEAjcwsZRNsAW2mlWPH68Kp97TBw09+zkNuL8vP66L9uw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.21.tgz",
- "integrity": "sha512-Q+5C4gUakWccecCmsr3ts6ypQzGPHUp+ooUQhQAf7L6bTv6037gsRYGDdkxla77S5+VfLXBwNXKZFsndDOuZoQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.21.tgz",
- "integrity": "sha512-xf30hS7YvyZlkqR3NZAWm+so0m9Rrp24TRq1F4UmNWpDL5Cwbmgak/Cn4IYUEY6PE960+ZejuAhbCDPt5Bxaeg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.21.tgz",
- "integrity": "sha512-/X3MvmRcIQSxmHF/TxO2SI0snHjGlY2uO3BKwgPA100hSmvVDuz6cFB80tcGNCUVSJAtRHt/FniNTmbMHfdHLQ==",
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
+ "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
"cpu": [
"x64"
],
@@ -1904,12 +1173,19 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.21.tgz",
- "integrity": "sha512-z5rjicKLgYiffiHOQgM3kROyEUILRZx3GeLtRnrf9yjgMDdpguRl3ggB67ej5ytgRXn5K5F13lsIv5R0i9KRFQ==",
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
+ "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
"cpu": [
"x64"
],
@@ -1918,29 +1194,19 @@
"optional": true,
"os": [
"linux"
- ]
- },
- "node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.21.tgz",
- "integrity": "sha512-v5eFQYJcD4a2FBb/KDzS+bhVW2tf5aolJCbAiqlVnJwD3dbYMQtwJRwej2kISDerGplx6yQIHp5R5Y7GRoEGhw==",
- "cpu": [
- "wasm32"
],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@napi-rs/wasm-runtime": "^0.2.10"
- },
"engines": {
- "node": ">=14.21.3"
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.21.tgz",
- "integrity": "sha512-1QZIJXSlbIlHJT6xY1YCuyF54sSOoOlsUaX3pWlJvuZs4fbgl894gN4wZATYd0V7KT62qfRdB40wg0yfrTkfFQ==",
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
+ "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
"cpu": [
"arm64"
],
@@ -1949,12 +1215,19 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/@rolldown/binding-win32-ia32-msvc": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.21.tgz",
- "integrity": "sha512-JXTN7gKNmQoFtqYrCK0If4HuZagvBQ7ThY6fl2rAMbUXpq3mtVd+Z2k0TzzeWB7Nxwo6FusLYYlbmPYS5QCl1w==",
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
+ "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
"cpu": [
"ia32"
],
@@ -1963,12 +1236,19 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.21.tgz",
- "integrity": "sha512-wp7kF6IpuVVqQVzkaDxrxJqBByMSEJ8uAa9LTW1fK2x8TulNRjlxPRpjeDNji2uiEGa+QbdQDfRm/WS8ROnutg==",
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
+ "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
"cpu": [
"x64"
],
@@ -1977,77 +1257,107 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.19",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz",
- "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==",
+ "node_modules/@playwright/test": {
+ "version": "1.53.2",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz",
+ "integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright": "1.53.2"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
"dev": true,
"license": "MIT"
},
- "node_modules/@rollup/pluginutils": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
- "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@reduxjs/toolkit": {
+ "version": "1.9.7",
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz",
+ "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/estree": "^1.0.0",
- "estree-walker": "^2.0.2",
- "picomatch": "^4.0.2"
- },
- "engines": {
- "node": ">=14.0.0"
+ "immer": "^9.0.21",
+ "redux": "^4.2.1",
+ "redux-thunk": "^2.4.2",
+ "reselect": "^4.1.8"
},
"peerDependencies": {
- "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ "react": "^16.9.0 || ^17.0.0 || ^18",
+ "react-redux": "^7.2.1 || ^8.0.2"
},
"peerDependenciesMeta": {
- "rollup": {
+ "react": {
+ "optional": true
+ },
+ "react-redux": {
"optional": true
}
}
},
- "node_modules/@rollup/pluginutils/node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rollup/pluginutils/node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
- "dev": true,
+ "node_modules/@remix-run/router": {
+ "version": "1.23.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
+ "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
"license": "MIT",
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "node": ">=14.0.0"
}
},
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz",
- "integrity": "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
+ "node_modules/@restart/context": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
+ "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true
+ "peerDependencies": {
+ "react": ">=16.3.2"
+ }
+ },
+ "node_modules/@restart/hooks": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
+ "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
},
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz",
- "integrity": "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==",
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.30.tgz",
+ "integrity": "sha512-4j7QBitb/WMT1fzdJo7BsFvVNaFR5WCQPdf/RPDHEsgQIYwBaHaL47KTZxncGFQDD1UAKN3XScJ0k7LAsZfsvg==",
"cpu": [
"arm64"
],
@@ -2056,13 +1366,12 @@
"optional": true,
"os": [
"android"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz",
- "integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==",
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.30.tgz",
+ "integrity": "sha512-4vWFTe1o5LXeitI2lW8qMGRxxwrH/LhKd2HDLa/QPhdxohvdnfKyDZWN96XUhDyje2bHFCFyhMs3ak2lg2mJFA==",
"cpu": [
"arm64"
],
@@ -2071,13 +1380,12 @@
"optional": true,
"os": [
"darwin"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz",
- "integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==",
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.30.tgz",
+ "integrity": "sha512-MxrfodqImbsDFFFU/8LxyFPZjt7s4ht8g2Zb76EmIQ+xlmit46L9IzvWiuMpEaSJ5WbnjO7fCDWwakMGyJJ+Dw==",
"cpu": [
"x64"
],
@@ -2086,28 +1394,12 @@
"optional": true,
"os": [
"darwin"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz",
- "integrity": "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz",
- "integrity": "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==",
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.30.tgz",
+ "integrity": "sha512-c/TQXcATKoO8qE1bCjCOkymZTu7yVUAxBSNLp42Q97XHCb0Cu9v6MjZpB6c7Hq9NQ9NzW44uglak9D/r77JeDw==",
"cpu": [
"x64"
],
@@ -2116,28 +1408,12 @@
"optional": true,
"os": [
"freebsd"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz",
- "integrity": "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz",
- "integrity": "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==",
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.30.tgz",
+ "integrity": "sha512-Vxci4xylM11zVqvrmezAaRjGBDyOlMRtlt7TDgxaBmSYLuiokXbZpD8aoSuOyjUAeN0/tmWItkxNGQza8UWGNQ==",
"cpu": [
"arm"
],
@@ -2146,13 +1422,12 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz",
- "integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==",
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.30.tgz",
+ "integrity": "sha512-iEBEdSs25Ol0lXyVNs763f7YPAIP0t1EAjoXME81oJ94DesJslaLTj71Rn1shoMDVA+dfkYA286w5uYnOs9ZNA==",
"cpu": [
"arm64"
],
@@ -2161,13 +1436,12 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz",
- "integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==",
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.30.tgz",
+ "integrity": "sha512-Ny684Sn1X8c+gGLuDlxkOuwiEE3C7eEOqp1/YVBzQB4HO7U/b4n7alvHvShboOEY5DP1fFUjq6Z+sBLYlCIZbQ==",
"cpu": [
"arm64"
],
@@ -2176,88 +1450,40 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz",
- "integrity": "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz",
- "integrity": "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz",
- "integrity": "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz",
- "integrity": "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==",
+ "node_modules/@rolldown/binding-linux-arm64-ohos": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-ohos/-/binding-linux-arm64-ohos-1.0.0-beta.30.tgz",
+ "integrity": "sha512-6moyULHDPKwt5RDEV72EqYw5n+s46AerTwtEBau5wCsZd1wuHS1L9z6wqhKISXAFTK9sneN0TEjvYKo+sgbbiA==",
"cpu": [
- "riscv64"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "linux"
- ],
- "peer": true
+ "openharmony"
+ ]
},
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz",
- "integrity": "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==",
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.30.tgz",
+ "integrity": "sha512-p0yoPdoGg5Ow2YZKKB5Ypbn58i7u4XFk3PvMkriFnEcgtVk40c5u7miaX7jH0JdzahyXVBJ/KT5yEpJrzQn8yg==",
"cpu": [
- "s390x"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz",
- "integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==",
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.30.tgz",
+ "integrity": "sha512-sM/KhCrsT0YdHX10mFSr0cvbfk1+btG6ftepAfqhbcDfhi0s65J4dTOxGmklJnJL9i1LXZ8WA3N4wmnqsfoK8Q==",
"cpu": [
"x64"
],
@@ -2266,28 +1492,29 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz",
- "integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==",
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.30.tgz",
+ "integrity": "sha512-i3kD5OWs8PQP0V+JW3TFyCLuyjuNzrB45em0g84Jc+gvnDsGVlzVjMNPo7txE/yT8CfE90HC/lDs3ry9FvaUyw==",
"cpu": [
- "x64"
+ "wasm32"
],
"dev": true,
"license": "MIT",
"optional": true,
- "os": [
- "linux"
- ],
- "peer": true
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
},
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz",
- "integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==",
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.30.tgz",
+ "integrity": "sha512-q7mrYln30V35VrCqnBVQQvNPQm8Om9HC59I3kMYiOWogvJobzSPyO+HA1MP363+Qgwe39I2I1nqBKPOtWZ33AQ==",
"cpu": [
"arm64"
],
@@ -2296,13 +1523,12 @@
"optional": true,
"os": [
"win32"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz",
- "integrity": "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==",
+ "node_modules/@rolldown/binding-win32-ia32-msvc": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.30.tgz",
+ "integrity": "sha512-nUqGBt39XTpbBEREEnyKofdP3uz+SN/x2884BH+N3B2NjSUrP6NXwzltM35C0wKK42hX/nthRrwSgj715m99Jw==",
"cpu": [
"ia32"
],
@@ -2311,13 +1537,12 @@
"optional": true,
"os": [
"win32"
- ],
- "peer": true
+ ]
},
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz",
- "integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==",
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.30.tgz",
+ "integrity": "sha512-lbnvUwAXIVWSXAeZrCa4b1KvV/DW0rBnMHuX0T7I6ey1IsXZ90J37dEgt3j48Ex1Cw1E+5H7VDNP2gyOX8iu3w==",
"cpu": [
"x64"
],
@@ -2326,8 +1551,50 @@
"optional": true,
"os": [
"win32"
- ],
- "peer": true
+ ]
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz",
+ "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
@@ -2513,13 +1780,6 @@
"url": "https://github.com/sponsors/gregberge"
}
},
- "node_modules/@svgr/core/node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
- "license": "Python-2.0"
- },
"node_modules/@svgr/core/node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
@@ -2547,19 +1807,6 @@
}
}
},
- "node_modules/@svgr/core/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
"node_modules/@svgr/hast-util-to-babel-ast": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
@@ -2578,46 +1825,272 @@
"url": "https://github.com/sponsors/gregberge"
}
},
- "node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/@svgr/plugin-jsx": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
+ "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "@svgr/hast-util-to-babel-ast": "8.0.0",
+ "svg-parser": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
+ }
+ },
+ "node_modules/@swc/core": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.3.tgz",
+ "integrity": "sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.23"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.13.3",
+ "@swc/core-darwin-x64": "1.13.3",
+ "@swc/core-linux-arm-gnueabihf": "1.13.3",
+ "@swc/core-linux-arm64-gnu": "1.13.3",
+ "@swc/core-linux-arm64-musl": "1.13.3",
+ "@swc/core-linux-x64-gnu": "1.13.3",
+ "@swc/core-linux-x64-musl": "1.13.3",
+ "@swc/core-win32-arm64-msvc": "1.13.3",
+ "@swc/core-win32-ia32-msvc": "1.13.3",
+ "@swc/core-win32-x64-msvc": "1.13.3"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.17"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.3.tgz",
+ "integrity": "sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.3.tgz",
+ "integrity": "sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.3.tgz",
+ "integrity": "sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.3.tgz",
+ "integrity": "sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.3.tgz",
+ "integrity": "sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.3.tgz",
+ "integrity": "sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.3.tgz",
+ "integrity": "sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.3.tgz",
+ "integrity": "sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.3.tgz",
+ "integrity": "sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.3.tgz",
+ "integrity": "sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
+ "node": ">=10"
}
},
- "node_modules/@svgr/plugin-jsx": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
- "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
"dev": true,
- "license": "MIT",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.24",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.24.tgz",
+ "integrity": "sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@babel/core": "^7.21.3",
- "@svgr/babel-preset": "8.1.0",
- "@svgr/hast-util-to-babel-ast": "8.0.0",
- "svg-parser": "^2.0.4"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/gregberge"
- },
- "peerDependencies": {
- "@svgr/core": "*"
+ "@swc/counter": "^0.1.3"
}
},
"node_modules/@tybys/wasm-util": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
- "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==",
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz",
+ "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -2661,30 +2134,32 @@
}
},
"node_modules/@types/babel__traverse": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
- "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.20.7"
+ "@babel/types": "^7.28.2"
}
},
"node_modules/@types/estree": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
- "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/hoist-non-react-statics": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
- "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz",
+ "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==",
"license": "MIT",
"dependencies": {
- "@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*"
}
},
"node_modules/@types/invariant": {
@@ -2693,18 +2168,6 @@
"integrity": "sha512-IwpIMieE55oGWiXkQPSBY1nw1nFs6bsKXTFskNY8sdS17K24vyEBRQZEwlRS7ZmXCWnJcQtbxWzly+cODWGs2A==",
"license": "MIT"
},
- "node_modules/@types/node": {
- "version": "20.19.2",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.2.tgz",
- "integrity": "sha512-9pLGGwdzOUBDYi0GNjM97FIA+f92fqSke6joWeBjWXllfNxZBs7qeMF7tvtOIsbY45xkWkxrdwUfUf3MnQa9gA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "undici-types": "~6.21.0"
- }
- },
"node_modules/@types/parse-json": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
@@ -2712,9 +2175,9 @@
"license": "MIT"
},
"node_modules/@types/prop-types": {
- "version": "15.7.14",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
- "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
"license": "MIT"
},
"node_modules/@types/quill": {
@@ -2727,9 +2190,9 @@
}
},
"node_modules/@types/react": {
- "version": "18.3.22",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.22.tgz",
- "integrity": "sha512-vUhG0YmQZ7kL/tmKLrD3g5zXbXXreZXB3pmROW8bg3CnLnpjkRVwUlLne7Ufa2r9yJ8+/6B73RzhAek5TBKh2Q==",
+ "version": "18.3.23",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
+ "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
@@ -2798,9 +2261,9 @@
}
},
"node_modules/@vimeo/player": {
- "version": "2.27.1",
- "resolved": "https://registry.npmjs.org/@vimeo/player/-/player-2.27.1.tgz",
- "integrity": "sha512-G3lk+BI0qPvJYxh+OguN5uE5aKfJBcGOQODl++NlXNLP9OMe21jZql0iI6AFGGd1KBLXZXuNmpvBKb4PG+fiVw==",
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/@vimeo/player/-/player-2.29.3.tgz",
+ "integrity": "sha512-pS2LsZbcbuQmV9BatpxdjcsFsjuas1jslCzY48o1qsXJ/sQuPiWIuk5B/dSaLbY3AcnS4M1IPphPgA7PRSMdxA==",
"license": "MIT",
"dependencies": {
"native-promise-only": "0.8.1",
@@ -2808,16 +2271,16 @@
}
},
"node_modules/@vitejs/plugin-react": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz",
- "integrity": "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==",
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.27.4",
+ "@babel/core": "^7.28.0",
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-beta.19",
+ "@rolldown/pluginutils": "1.0.0-beta.27",
"@types/babel__core": "^7.20.5",
"react-refresh": "^0.17.0"
},
@@ -2825,32 +2288,23 @@
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0"
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
- "node_modules/@vitejs/plugin-react-oxc": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-oxc/-/plugin-react-oxc-0.2.3.tgz",
- "integrity": "sha512-ONriHoEGQv+ITmeJQsHIpx7u1ms8Z68oIo3AdKCoaBTvZtF+AfDVviQ3tKgCTnIbz9NW8V2Rd/Q+5zjzpsht1g==",
+ "node_modules/@vitejs/plugin-react-swc": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz",
+ "integrity": "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@rolldown/pluginutils": "1.0.0-beta.11"
- },
- "engines": {
- "node": ">=20.0.0"
+ "@rolldown/pluginutils": "1.0.0-beta.27",
+ "@swc/core": "^1.12.11"
},
"peerDependencies": {
- "vite": "^6.3.0 || ^7.0.0-beta.0"
+ "vite": "^4 || ^5 || ^6 || ^7"
}
},
- "node_modules/@vitejs/plugin-react-oxc/node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.11",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz",
- "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -2885,6 +2339,13 @@
"node": ">=14"
}
},
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
"node_modules/atomic-sleep": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
@@ -2982,9 +2443,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.24.5",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz",
- "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==",
+ "version": "4.25.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
+ "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
"funding": [
{
"type": "opencollective",
@@ -3001,8 +2462,8 @@
],
"license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001716",
- "electron-to-chromium": "^1.5.149",
+ "caniuse-lite": "^1.0.30001726",
+ "electron-to-chromium": "^1.5.173",
"node-releases": "^2.0.19",
"update-browserslist-db": "^1.1.3"
},
@@ -3092,9 +2553,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001718",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz",
- "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==",
+ "version": "1.0.30001731",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz",
+ "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==",
"funding": [
{
"type": "opencollective",
@@ -3144,40 +2605,6 @@
"wrap-ansi": "^6.2.0"
}
},
- "node_modules/cliui/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/cliui/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cliui/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
@@ -3230,9 +2657,9 @@
"license": "MIT"
},
"node_modules/core-js": {
- "version": "3.42.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.42.0.tgz",
- "integrity": "sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==",
+ "version": "3.45.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.0.tgz",
+ "integrity": "sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
@@ -3689,11 +3116,17 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.157",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.157.tgz",
- "integrity": "sha512-/0ybgsQd1muo8QlnuTpKwtl0oX5YMlUGbm8xyqgDU00motRkKFFbUJySAQBWcY79rVqNLWIWa87BGVGClwAB2w==",
+ "version": "1.5.198",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.198.tgz",
+ "integrity": "sha512-G5COfnp3w+ydVu80yprgWSfmfQaYRh9DOxfhAxstLyetKaLyl55QrNjx8C38Pc/C+RaDmb1M0Lk8wPEMQ+bGgQ==",
"license": "ISC"
},
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
"node_modules/entities": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
@@ -3745,49 +3178,6 @@
"node": ">= 0.4"
}
},
- "node_modules/esbuild": {
- "version": "0.25.4",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz",
- "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.25.4",
- "@esbuild/android-arm": "0.25.4",
- "@esbuild/android-arm64": "0.25.4",
- "@esbuild/android-x64": "0.25.4",
- "@esbuild/darwin-arm64": "0.25.4",
- "@esbuild/darwin-x64": "0.25.4",
- "@esbuild/freebsd-arm64": "0.25.4",
- "@esbuild/freebsd-x64": "0.25.4",
- "@esbuild/linux-arm": "0.25.4",
- "@esbuild/linux-arm64": "0.25.4",
- "@esbuild/linux-ia32": "0.25.4",
- "@esbuild/linux-loong64": "0.25.4",
- "@esbuild/linux-mips64el": "0.25.4",
- "@esbuild/linux-ppc64": "0.25.4",
- "@esbuild/linux-riscv64": "0.25.4",
- "@esbuild/linux-s390x": "0.25.4",
- "@esbuild/linux-x64": "0.25.4",
- "@esbuild/netbsd-arm64": "0.25.4",
- "@esbuild/netbsd-x64": "0.25.4",
- "@esbuild/openbsd-arm64": "0.25.4",
- "@esbuild/openbsd-x64": "0.25.4",
- "@esbuild/sunos-x64": "0.25.4",
- "@esbuild/win32-arm64": "0.25.4",
- "@esbuild/win32-ia32": "0.25.4",
- "@esbuild/win32-x64": "0.25.4"
- }
- },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -3809,6 +3199,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
@@ -3821,6 +3218,12 @@
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"license": "MIT"
},
+ "node_modules/fast-diff": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
+ "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+ "license": "Apache-2.0"
+ },
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -3911,9 +3314,9 @@
}
},
"node_modules/focus-trap": {
- "version": "7.6.4",
- "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.4.tgz",
- "integrity": "sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==",
+ "version": "7.6.5",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.5.tgz",
+ "integrity": "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==",
"license": "MIT",
"dependencies": {
"tabbable": "^6.2.0"
@@ -4035,15 +3438,6 @@
"node": ">= 6"
}
},
- "node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -4056,6 +3450,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
@@ -4236,9 +3639,9 @@
}
},
"node_modules/immutable": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.2.tgz",
- "integrity": "sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==",
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz",
+ "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==",
"dev": true,
"license": "MIT"
},
@@ -4425,6 +3828,19 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
},
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -5363,12 +4779,6 @@
"node": ">=0.10"
}
},
- "node_modules/quill-delta/node_modules/fast-diff": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
- "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
- "license": "Apache-2.0"
- },
"node_modules/quill/node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
@@ -5540,9 +4950,9 @@
}
},
"node_modules/react-is": {
- "version": "19.1.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz",
- "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==",
+ "version": "19.1.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz",
+ "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==",
"license": "MIT",
"peer": true
},
@@ -5715,9 +5125,9 @@
"license": "MIT"
},
"node_modules/react-select": {
- "version": "5.10.1",
- "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.10.1.tgz",
- "integrity": "sha512-roPEZUL4aRZDx6DcsD+ZNreVl+fM8VsKn0Wtex1v4IazH60ILp5xhdlp464IsEAlJdXeD+BhDAFsBVMfvLQueA==",
+ "version": "5.10.2",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.10.2.tgz",
+ "integrity": "sha512-Z33nHdEFWq9tfnfVXaiM12rbJmk+QjFEztWLtmXqQhz6Al4UZZ9xc0wiatmGtUOCCnHN0WizL3tCMYRENX4rVQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.0",
@@ -5762,9 +5172,9 @@
}
},
"node_modules/react-tooltip": {
- "version": "5.28.1",
- "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.28.1.tgz",
- "integrity": "sha512-ZA4oHwoIIK09TS7PvSLFcRlje1wGZaxw6xHvfrzn6T82UcMEfEmHVCad16Gnr4NDNDh93HyN037VK4HDi5odfQ==",
+ "version": "5.29.1",
+ "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.29.1.tgz",
+ "integrity": "sha512-rmJmEb/p99xWhwmVT7F7riLG08wwKykjHiMGbDPloNJk3tdI73oHsVOwzZ4SRjqMdd5/xwb/4nmz0RcoMfY7Bw==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.1",
@@ -5937,84 +5347,44 @@
}
},
"node_modules/rolldown": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.21.tgz",
- "integrity": "sha512-pjU+yNElXbreaNNz2EDOPrf5Yj6aoT8cTfd4pViBSdO7Nr0MOqHV0vDR9w3V8venZmjzF4LAfs03Cbl46YsdVw==",
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.30.tgz",
+ "integrity": "sha512-H/LmDTUPlm65hWOTjXvd1k0qrGinNi8LrG3JsHVm6Oit7STg0upBmgoG5PZUHbAnGTHr0MLoLyzjmH261lIqSg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/runtime": "=0.75.0",
- "@oxc-project/types": "=0.75.0",
- "@rolldown/pluginutils": "1.0.0-beta.21",
+ "@oxc-project/runtime": "=0.78.0",
+ "@oxc-project/types": "=0.78.0",
+ "@rolldown/pluginutils": "1.0.0-beta.30",
"ansis": "^4.0.0"
},
"bin": {
"rolldown": "bin/cli.mjs"
},
"optionalDependencies": {
- "@rolldown/binding-darwin-arm64": "1.0.0-beta.21",
- "@rolldown/binding-darwin-x64": "1.0.0-beta.21",
- "@rolldown/binding-freebsd-x64": "1.0.0-beta.21",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.21",
- "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.21",
- "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.21",
- "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.21",
- "@rolldown/binding-linux-x64-musl": "1.0.0-beta.21",
- "@rolldown/binding-wasm32-wasi": "1.0.0-beta.21",
- "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.21",
- "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.21",
- "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.21"
+ "@rolldown/binding-android-arm64": "1.0.0-beta.30",
+ "@rolldown/binding-darwin-arm64": "1.0.0-beta.30",
+ "@rolldown/binding-darwin-x64": "1.0.0-beta.30",
+ "@rolldown/binding-freebsd-x64": "1.0.0-beta.30",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.30",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.30",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.30",
+ "@rolldown/binding-linux-arm64-ohos": "1.0.0-beta.30",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.30",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-beta.30",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-beta.30",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.30",
+ "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.30",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.30"
}
},
"node_modules/rolldown/node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.21",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.21.tgz",
- "integrity": "sha512-OTjWr7XYqRZaSzi6dTe0fP25EEsYEQ2H04xIedXG3D0Hrs+Bpe3V5L48R6y+R5ohTygp1ijC09mbrd7vlslpzA==",
+ "version": "1.0.0-beta.30",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.30.tgz",
+ "integrity": "sha512-whXaSoNUFiyDAjkUF8OBpOm77Szdbk5lGNqFe6CbVbJFrhCCPinCbRA3NjawwlNHla1No7xvXXh+CpSxnPfUEw==",
"dev": true,
"license": "MIT"
},
- "node_modules/rollup": {
- "version": "4.41.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz",
- "integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "@types/estree": "1.0.7"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.41.1",
- "@rollup/rollup-android-arm64": "4.41.1",
- "@rollup/rollup-darwin-arm64": "4.41.1",
- "@rollup/rollup-darwin-x64": "4.41.1",
- "@rollup/rollup-freebsd-arm64": "4.41.1",
- "@rollup/rollup-freebsd-x64": "4.41.1",
- "@rollup/rollup-linux-arm-gnueabihf": "4.41.1",
- "@rollup/rollup-linux-arm-musleabihf": "4.41.1",
- "@rollup/rollup-linux-arm64-gnu": "4.41.1",
- "@rollup/rollup-linux-arm64-musl": "4.41.1",
- "@rollup/rollup-linux-loongarch64-gnu": "4.41.1",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.41.1",
- "@rollup/rollup-linux-riscv64-gnu": "4.41.1",
- "@rollup/rollup-linux-riscv64-musl": "4.41.1",
- "@rollup/rollup-linux-s390x-gnu": "4.41.1",
- "@rollup/rollup-linux-x64-gnu": "4.41.1",
- "@rollup/rollup-linux-x64-musl": "4.41.1",
- "@rollup/rollup-win32-arm64-msvc": "4.41.1",
- "@rollup/rollup-win32-ia32-msvc": "4.41.1",
- "@rollup/rollup-win32-x64-msvc": "4.41.1",
- "fsevents": "~2.3.2"
- }
- },
"node_modules/rrule": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/rrule/-/rrule-2.8.1.tgz",
@@ -6064,9 +5434,9 @@
"license": "MIT"
},
"node_modules/sass": {
- "version": "1.89.0",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz",
- "integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==",
+ "version": "1.90.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz",
+ "integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6242,6 +5612,20 @@
"node": ">=4"
}
},
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -6308,16 +5692,18 @@
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
"license": "MIT"
},
- "node_modules/styled-components/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
+ "node_modules/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
+ "license": "MIT"
+ },
+ "node_modules/suncalc": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz",
+ "integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A=="
},
- "node_modules/styled-components/node_modules/supports-color": {
+ "node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
@@ -6329,17 +5715,6 @@
"node": ">=4"
}
},
- "node_modules/stylis": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
- "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
- "license": "MIT"
- },
- "node_modules/suncalc": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz",
- "integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A=="
- },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -6425,9 +5800,9 @@
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6510,15 +5885,6 @@
"react": ">=15.0.0"
}
},
- "node_modules/undici-types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/unicode-properties": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz",
@@ -6609,18 +5975,17 @@
},
"node_modules/vite": {
"name": "rolldown-vite",
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/rolldown-vite/-/rolldown-vite-7.0.3.tgz",
- "integrity": "sha512-Bg5i1Du+reIljLk5sB/+iOXkhW541NcbS1Ntqd+0EpzdXnl+uxiZDEOUGmVFT8Z94FTpEld2BvoXN80+o2LKAA==",
+ "version": "7.0.12",
+ "resolved": "https://registry.npmjs.org/rolldown-vite/-/rolldown-vite-7.0.12.tgz",
+ "integrity": "sha512-Gr40FRnE98FwPJcMwcJgBwP6U7Qxw/VEtDsFdFjvGUTdgI/tTmF7z7dbVo/ajItM54G+Zo9w5BIrUmat6MbuWQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/runtime": "0.75.0",
"fdir": "^6.4.6",
"lightningcss": "^1.30.1",
- "picomatch": "^4.0.2",
+ "picomatch": "^4.0.3",
"postcss": "^8.5.6",
- "rolldown": "1.0.0-beta.21",
+ "rolldown": "1.0.0-beta.30",
"tinyglobby": "^0.2.14"
},
"bin": {
@@ -6746,9 +6111,9 @@
}
},
"node_modules/vite/node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6791,10 +6156,24 @@
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"license": "ISC"
},
+ "node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/xmldoc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-2.0.1.tgz",
- "integrity": "sha512-sOOqgsjl3PU6iBw+fBUGAkTCE+JFK+sBaOL3pnZgzqk2/yvOD7RlFmZtDRJAEBzdpOYxSXyOQH4mjubdfs3MSg==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-2.0.2.tgz",
+ "integrity": "sha512-UiRwoSStEXS3R+YE8OqYv3jebza8cBBAI2y8g3B15XFkn3SbEOyyLnmPHjLBPZANrPJKEzxxB7A3XwcLikQVlQ==",
"license": "MIT",
"dependencies": {
"sax": "^1.2.4"
@@ -6816,9 +6195,9 @@
"license": "ISC"
},
"node_modules/yaml": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
- "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
+ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"dev": true,
"license": "ISC",
"optional": true,
@@ -6873,26 +6252,6 @@
"engines": {
"node": ">=6"
}
- },
- "node_modules/yargs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/yargs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
}
}
}
diff --git a/package.json b/package.json
index 0573d5d2..eaec7d23 100644
--- a/package.json
+++ b/package.json
@@ -9,9 +9,9 @@
},
"devDependencies": {
"@playwright/test": "1.53.2",
- "@vitejs/plugin-react": "^4.6.0",
- "@vitejs/plugin-react-oxc": "^0.2.3",
"@reduxjs/toolkit": "^1.6.1",
+ "@vitejs/plugin-react": "^4.6.0",
+ "@vitejs/plugin-react-swc": "^3.11.0",
"sass": "^1.88.9",
"typescript": "^4.4.2",
"vite": "npm:rolldown-vite@^7.0.3",
diff --git a/vite.config.js b/vite.config.js
index 71e96119..9904a797 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,8 +1,10 @@
import { defineConfig } from "vite";
import symfonyPlugin from "vite-plugin-symfony";
-import react from "@vitejs/plugin-react-oxc";
+import react from "@vitejs/plugin-react-swc";
import svgr from "vite-plugin-svgr";
+// TODO: When possible change to @vitejs/plugin-react-oxc.
+
export default defineConfig(({ command }) => {
return {
base: "/build",
From 4d55a07c3fab7c54b2b3a154066b3def9b603b56 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 7 Aug 2025 08:42:48 +0200
Subject: [PATCH 22/30] 4565: Added esbuild
---
assets/tests/admin/admin-campaign.spec.js | 12 +-
assets/tests/admin/admin-feed-sources.spec.js | 10 +-
assets/tests/admin/admin-helper.js | 12 +-
assets/tests/admin/data-fixtures.js | 11 +-
package-lock.json | 790 +++++++++++-------
package.json | 3 +-
vite.config.js | 4 +-
7 files changed, 513 insertions(+), 329 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 84dad8d5..9cae76bd 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -3,15 +3,15 @@ import { loginTest } from "./admin-helper.js";
import { emptySlidesJson, slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
- test.beforeEach( async ({ page }) => {
- await loginTest({page});
+ test.beforeEach(async ({ page }) => {
+ await loginTest({ page });
await page.route("**/playlists*", async (route) => {
await route.fulfill({ json: emptySlidesJson });
});
- await page.locator('.sidebar-nav .nav-link').getByText("Kampagner").click();
- await expect(page.locator('h1').getByText("Kampagner")).toBeVisible();
+ await page.locator(".sidebar-nav .nav-link").getByText("Kampagner").click();
+ await expect(page.locator("h1").getByText("Kampagner")).toBeVisible();
await page.getByText("Opret ny kampagne").click();
});
@@ -56,8 +56,6 @@ test.describe("Campaign pages work", () => {
await page.locator(".remove-from-list").click({ force: false });
// See that slides section is removed.
- await expect(
- page.getByText("Afspilningsrækkefølge"),
- ).not.toBeVisible();
+ await expect(page.getByText("Afspilningsrækkefølge")).not.toBeVisible();
});
});
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 6b476235..2907a3f1 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -1,12 +1,18 @@
import { test, expect } from "@playwright/test";
-import { errorJson, feedSourcesJson, feedSourcesJson2, feedSourcesJson3, tokenJson } from "./data-fixtures.js";
+import {
+ errorJson,
+ feedSourcesJson,
+ feedSourcesJson2,
+ feedSourcesJson3,
+ tokenJson,
+} from "./data-fixtures.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/admin/feed-sources/list");
// Abort all routes that are not registered.
- await page.route('**/*', async route => {
+ await page.route("**/*", async (route) => {
await route.abort();
});
diff --git a/assets/tests/admin/admin-helper.js b/assets/tests/admin/admin-helper.js
index 70163132..1b9e6de0 100644
--- a/assets/tests/admin/admin-helper.js
+++ b/assets/tests/admin/admin-helper.js
@@ -1,11 +1,15 @@
-import { emptySlidesJson, feedSourcesJson, tokenJson } from "./data-fixtures.js";
+import {
+ emptySlidesJson,
+ feedSourcesJson,
+ tokenJson,
+} from "./data-fixtures.js";
import { expect } from "@playwright/test";
-const loginTest = async ({page}) => {
+const loginTest = async ({ page }) => {
await page.goto("/admin/slides/list");
// Abort all routes that are not registered.
- await page.route('**/*', async route => {
+ await page.route("**/*", async (route) => {
await route.abort();
});
@@ -22,6 +26,6 @@ const loginTest = async ({page}) => {
await page.getByLabel("Kodeord").fill("password");
await page.locator("#login").click();
await expect(page.locator("h1").getByText("Slides")).toBeVisible();
-}
+};
export { loginTest };
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index 2f2f30e6..11e7f8cb 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -601,5 +601,12 @@ const slidesJson1 = {
"hydra:totalItems": 60,
};
-
-export { tokenJson, feedSourcesJson, feedSourcesJson2, feedSourcesJson3, errorJson, emptySlidesJson, slidesJson1 };
+export {
+ tokenJson,
+ feedSourcesJson,
+ feedSourcesJson2,
+ feedSourcesJson3,
+ errorJson,
+ emptySlidesJson,
+ slidesJson1,
+};
diff --git a/package-lock.json b/package-lock.json
index 4e42d215..c6b41214 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"@hello-pangea/dnd": "^16.0.0",
"@popperjs/core": "^2.11.8",
"@u-wave/react-vimeo": "^0.9.11",
+ "@vitejs/plugin-react-oxc": "^0.3.0",
"bootstrap": "^5.3.7",
"crypto-js": "^4.0.0",
"dayjs": "^1.10.5",
@@ -60,7 +61,7 @@
"@playwright/test": "1.53.2",
"@reduxjs/toolkit": "^1.6.1",
"@vitejs/plugin-react": "^4.6.0",
- "@vitejs/plugin-react-swc": "^3.11.0",
+ "esbuild": "^0.25.8",
"sass": "^1.88.9",
"typescript": "^4.4.2",
"vite": "npm:rolldown-vite@^7.0.3",
@@ -408,7 +409,6 @@
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz",
"integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==",
- "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -420,7 +420,6 @@
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz",
"integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==",
- "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -431,7 +430,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz",
"integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==",
- "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -573,6 +571,422 @@
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz",
+ "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz",
+ "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz",
+ "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz",
+ "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz",
+ "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz",
+ "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz",
+ "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz",
+ "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz",
+ "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz",
+ "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz",
+ "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz",
+ "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz",
+ "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz",
+ "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz",
+ "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz",
+ "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz",
+ "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz",
+ "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz",
+ "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz",
+ "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz",
+ "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
@@ -889,7 +1303,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.1.tgz",
"integrity": "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==",
- "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -940,7 +1353,6 @@
"version": "0.78.0",
"resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.78.0.tgz",
"integrity": "sha512-jOU7sDFMyq5ShGJC21UobalVzqcdtWGfySVp8ELvKoVLzMpLHb4kv1bs9VKxaP8XC7Z9hlAXwEKVhCTN+j21aQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -950,7 +1362,6 @@
"version": "0.78.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.78.0.tgz",
"integrity": "sha512-8FvExh0WRWN1FoSTjah1xa9RlavZcJQ8/yxRbZ7ElmSa2Ij5f5Em7MvRbSthE6FbwC6Wh8iAw0Gpna7QdoqLGg==",
- "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/Boshen"
@@ -960,7 +1371,6 @@
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
"integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -1000,7 +1410,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1021,7 +1430,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1042,7 +1450,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1063,7 +1470,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1084,7 +1490,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1105,7 +1510,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1126,7 +1530,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1147,7 +1550,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1168,7 +1570,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1189,7 +1590,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1210,7 +1610,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1231,7 +1630,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1252,7 +1650,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1361,7 +1758,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1375,7 +1771,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1389,7 +1784,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1403,7 +1797,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1417,7 +1810,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1431,7 +1823,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1445,7 +1836,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1459,7 +1849,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1473,7 +1862,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1487,7 +1875,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1501,7 +1888,6 @@
"cpu": [
"wasm32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -1518,7 +1904,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1532,7 +1917,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1546,7 +1930,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -1557,7 +1940,6 @@
"version": "1.0.0-beta.27",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
"integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
- "dev": true,
"license": "MIT"
},
"node_modules/@rollup/pluginutils": {
@@ -1861,237 +2243,10 @@
"@svgr/core": "*"
}
},
- "node_modules/@swc/core": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.3.tgz",
- "integrity": "sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==",
- "dev": true,
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@swc/counter": "^0.1.3",
- "@swc/types": "^0.1.23"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/swc"
- },
- "optionalDependencies": {
- "@swc/core-darwin-arm64": "1.13.3",
- "@swc/core-darwin-x64": "1.13.3",
- "@swc/core-linux-arm-gnueabihf": "1.13.3",
- "@swc/core-linux-arm64-gnu": "1.13.3",
- "@swc/core-linux-arm64-musl": "1.13.3",
- "@swc/core-linux-x64-gnu": "1.13.3",
- "@swc/core-linux-x64-musl": "1.13.3",
- "@swc/core-win32-arm64-msvc": "1.13.3",
- "@swc/core-win32-ia32-msvc": "1.13.3",
- "@swc/core-win32-x64-msvc": "1.13.3"
- },
- "peerDependencies": {
- "@swc/helpers": ">=0.5.17"
- },
- "peerDependenciesMeta": {
- "@swc/helpers": {
- "optional": true
- }
- }
- },
- "node_modules/@swc/core-darwin-arm64": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.3.tgz",
- "integrity": "sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-darwin-x64": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.3.tgz",
- "integrity": "sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.3.tgz",
- "integrity": "sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.3.tgz",
- "integrity": "sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.3.tgz",
- "integrity": "sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.3.tgz",
- "integrity": "sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-x64-musl": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.3.tgz",
- "integrity": "sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.3.tgz",
- "integrity": "sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.3.tgz",
- "integrity": "sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.13.3",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.3.tgz",
- "integrity": "sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/counter": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
- "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/@swc/types": {
- "version": "0.1.24",
- "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.24.tgz",
- "integrity": "sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@swc/counter": "^0.1.3"
- }
- },
"node_modules/@tybys/wasm-util": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz",
"integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==",
- "dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
@@ -2291,18 +2446,19 @@
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
- "node_modules/@vitejs/plugin-react-swc": {
- "version": "3.11.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz",
- "integrity": "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==",
- "dev": true,
+ "node_modules/@vitejs/plugin-react-oxc": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-oxc/-/plugin-react-oxc-0.3.0.tgz",
+ "integrity": "sha512-OaqaDIc74NNuqH1xKGbGoErpKP8L1XlxBQsfWvIUfpQaDCe5El9Ac5mPrvn/Dg0pv3xKB/PNm4Wirxr6hnKu/A==",
"license": "MIT",
"dependencies": {
- "@rolldown/pluginutils": "1.0.0-beta.27",
- "@swc/core": "^1.12.11"
+ "@rolldown/pluginutils": "1.0.0-beta.27"
+ },
+ "engines": {
+ "node": ">=20.0.0"
},
"peerDependencies": {
- "vite": "^4 || ^5 || ^6 || ^7"
+ "vite": "^6.3.0 || ^7.0.0"
}
},
"node_modules/ansi-regex": {
@@ -2333,7 +2489,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz",
"integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
@@ -2424,7 +2579,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
@@ -2576,7 +2731,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
@@ -2985,7 +3140,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "dev": true,
"license": "Apache-2.0",
"optional": true,
"bin": {
@@ -3178,6 +3332,48 @@
"node": ">= 0.4"
}
},
+ "node_modules/esbuild": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz",
+ "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.8",
+ "@esbuild/android-arm": "0.25.8",
+ "@esbuild/android-arm64": "0.25.8",
+ "@esbuild/android-x64": "0.25.8",
+ "@esbuild/darwin-arm64": "0.25.8",
+ "@esbuild/darwin-x64": "0.25.8",
+ "@esbuild/freebsd-arm64": "0.25.8",
+ "@esbuild/freebsd-x64": "0.25.8",
+ "@esbuild/linux-arm": "0.25.8",
+ "@esbuild/linux-arm64": "0.25.8",
+ "@esbuild/linux-ia32": "0.25.8",
+ "@esbuild/linux-loong64": "0.25.8",
+ "@esbuild/linux-mips64el": "0.25.8",
+ "@esbuild/linux-ppc64": "0.25.8",
+ "@esbuild/linux-riscv64": "0.25.8",
+ "@esbuild/linux-s390x": "0.25.8",
+ "@esbuild/linux-x64": "0.25.8",
+ "@esbuild/netbsd-arm64": "0.25.8",
+ "@esbuild/netbsd-x64": "0.25.8",
+ "@esbuild/openbsd-arm64": "0.25.8",
+ "@esbuild/openbsd-x64": "0.25.8",
+ "@esbuild/openharmony-arm64": "0.25.8",
+ "@esbuild/sunos-x64": "0.25.8",
+ "@esbuild/win32-arm64": "0.25.8",
+ "@esbuild/win32-ia32": "0.25.8",
+ "@esbuild/win32-x64": "0.25.8"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -3276,7 +3472,7 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -3642,7 +3838,7 @@
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz",
"integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/import-fresh": {
@@ -3754,7 +3950,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -3773,7 +3969,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -3786,7 +3982,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@@ -3881,7 +4077,6 @@
"version": "1.30.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
"integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
- "dev": true,
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^2.0.3"
@@ -3913,7 +4108,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -3934,7 +4128,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -3955,7 +4148,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -3976,7 +4168,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -3997,7 +4188,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -4018,7 +4208,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -4039,7 +4228,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -4060,7 +4248,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -4081,7 +4268,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -4102,7 +4288,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -4120,7 +4305,6 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
"integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@@ -4241,7 +4425,7 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@@ -4271,7 +4455,6 @@
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -4307,7 +4490,6 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "dev": true,
"license": "MIT",
"optional": true
},
@@ -4606,7 +4788,6 @@
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -5205,7 +5386,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
@@ -5350,7 +5531,6 @@
"version": "1.0.0-beta.30",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.30.tgz",
"integrity": "sha512-H/LmDTUPlm65hWOTjXvd1k0qrGinNi8LrG3JsHVm6Oit7STg0upBmgoG5PZUHbAnGTHr0MLoLyzjmH261lIqSg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@oxc-project/runtime": "=0.78.0",
@@ -5382,7 +5562,6 @@
"version": "1.0.0-beta.30",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.30.tgz",
"integrity": "sha512-whXaSoNUFiyDAjkUF8OBpOm77Szdbk5lGNqFe6CbVbJFrhCCPinCbRA3NjawwlNHla1No7xvXXh+CpSxnPfUEw==",
- "dev": true,
"license": "MIT"
},
"node_modules/rrule": {
@@ -5437,7 +5616,7 @@
"version": "1.90.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz",
"integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
@@ -5570,7 +5749,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -5771,7 +5949,6 @@
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.4.4",
@@ -5788,7 +5965,6 @@
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
- "dev": true,
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
@@ -5803,7 +5979,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -5822,7 +5997,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@@ -5978,7 +6153,6 @@
"version": "7.0.12",
"resolved": "https://registry.npmjs.org/rolldown-vite/-/rolldown-vite-7.0.12.tgz",
"integrity": "sha512-Gr40FRnE98FwPJcMwcJgBwP6U7Qxw/VEtDsFdFjvGUTdgI/tTmF7z7dbVo/ajItM54G+Zo9w5BIrUmat6MbuWQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.4.6",
@@ -6084,7 +6258,6 @@
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
- "dev": true,
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
@@ -6099,7 +6272,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -6114,7 +6286,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -6198,7 +6369,6 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
- "dev": true,
"license": "ISC",
"optional": true,
"peer": true,
diff --git a/package.json b/package.json
index eaec7d23..39bcd49f 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"@playwright/test": "1.53.2",
"@reduxjs/toolkit": "^1.6.1",
"@vitejs/plugin-react": "^4.6.0",
- "@vitejs/plugin-react-swc": "^3.11.0",
+ "esbuild": "^0.25.8",
"sass": "^1.88.9",
"typescript": "^4.4.2",
"vite": "npm:rolldown-vite@^7.0.3",
@@ -26,6 +26,7 @@
"@hello-pangea/dnd": "^16.0.0",
"@popperjs/core": "^2.11.8",
"@u-wave/react-vimeo": "^0.9.11",
+ "@vitejs/plugin-react-oxc": "^0.3.0",
"bootstrap": "^5.3.7",
"crypto-js": "^4.0.0",
"dayjs": "^1.10.5",
diff --git a/vite.config.js b/vite.config.js
index 9904a797..71e96119 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,10 +1,8 @@
import { defineConfig } from "vite";
import symfonyPlugin from "vite-plugin-symfony";
-import react from "@vitejs/plugin-react-swc";
+import react from "@vitejs/plugin-react-oxc";
import svgr from "vite-plugin-svgr";
-// TODO: When possible change to @vitejs/plugin-react-oxc.
-
export default defineConfig(({ command }) => {
return {
base: "/build",
From 6907751f636079cc968abe5ad2aa6fe2c320e879 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 7 Aug 2025 10:26:56 +0200
Subject: [PATCH 23/30] 4565: Test adjustments
---
assets/tests/admin/admin-app.spec.js | 6 --
assets/tests/admin/admin-campaign.spec.js | 4 +-
assets/tests/admin/admin-feed-sources.spec.js | 17 +---
assets/tests/admin/admin-helper.js | 11 ++-
assets/tests/admin/admin-login.spec.js | 55 ++++++-----
assets/tests/admin/admin-top-bar.spec.js | 94 ++++++++++---------
assets/tests/admin/data-fixtures.js | 28 +++++-
7 files changed, 121 insertions(+), 94 deletions(-)
delete mode 100644 assets/tests/admin/admin-app.spec.js
diff --git a/assets/tests/admin/admin-app.spec.js b/assets/tests/admin/admin-app.spec.js
deleted file mode 100644
index 72a27239..00000000
--- a/assets/tests/admin/admin-app.spec.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { test } from "@playwright/test";
-import { loginTest } from "./admin-helper.js";
-
-test.describe("Basic app", () => {
- test("App runs", loginTest);
-});
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 9cae76bd..f709cb14 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,13 +1,13 @@
import { test, expect } from "@playwright/test";
import { loginTest } from "./admin-helper.js";
-import { emptySlidesJson, slidesJson1 } from "./data-fixtures.js";
+import { emptyJson, slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
test.beforeEach(async ({ page }) => {
await loginTest({ page });
await page.route("**/playlists*", async (route) => {
- await route.fulfill({ json: emptySlidesJson });
+ await route.fulfill({ json: emptyJson });
});
await page.locator(".sidebar-nav .nav-link").getByText("Kampagner").click();
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 2907a3f1..bd315fe4 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -4,29 +4,18 @@ import {
feedSourcesJson,
feedSourcesJson2,
feedSourcesJson3,
- tokenJson,
} from "./data-fixtures.js";
+import { loginTest } from "./admin-helper.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/feed-sources/list");
-
- // Abort all routes that are not registered.
- await page.route("**/*", async (route) => {
- await route.abort();
- });
+ await loginTest({ page });
await page.route("**/feed-sources*", async (route) => {
await route.fulfill({ json: feedSourcesJson });
});
- await page.route("**/token", async (route) => {
- await route.fulfill({ json: tokenJson });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("admin@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
+ await page.locator(".sidebar-nav .nav-link").getByText("Datakilder").click();
await expect(page.locator("h1").getByText("Datakilder")).toBeVisible();
});
diff --git a/assets/tests/admin/admin-helper.js b/assets/tests/admin/admin-helper.js
index 1b9e6de0..196c4c9e 100644
--- a/assets/tests/admin/admin-helper.js
+++ b/assets/tests/admin/admin-helper.js
@@ -1,7 +1,8 @@
import {
- emptySlidesJson,
+ accessConfigJson,
+ emptyJson,
feedSourcesJson,
- tokenJson,
+ tokenJson
} from "./data-fixtures.js";
import { expect } from "@playwright/test";
@@ -17,8 +18,12 @@ const loginTest = async ({ page }) => {
await route.fulfill({ json: tokenJson });
});
+ await page.route('**/access-config.json*', async (route) => {
+ await route.fulfill({ json: accessConfigJson});
+ })
+
await page.route("**/slides*", async (route) => {
- await route.fulfill({ json: emptySlidesJson });
+ await route.fulfill({ json: emptyJson });
});
await expect(page).toHaveTitle(/OS2Display Admin/);
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index 7a398b12..aa51d8d1 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -1,7 +1,18 @@
import { test, expect } from "@playwright/test";
+import { accessConfigJson, emptyJson } from "./data-fixtures.js";
test.describe("Login works", () => {
+ test.beforeEach(async ({ page }) => {
+ await page.route("**/access-config.json", async (route) => {
+ await route.fulfill({ json: accessConfigJson });
+ });
+ });
+
test("Login one tenant works", async ({ page }) => {
+ await page.route("**/playlists*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
await page.route("**/token", async (route) => {
const json = {
token: "1",
@@ -11,13 +22,13 @@ test.describe("Login works", () => {
tenantKey: "ABC",
title: "ABC Tenant",
description: "Description",
- roles: ["ROLE_ADMIN"],
- },
+ roles: ["ROLE_ADMIN"]
+ }
],
user: {
fullname: "John Doe",
- email: "johndoe@example.com",
- },
+ email: "johndoe@example.com"
+ }
};
await route.fulfill({ json });
});
@@ -37,25 +48,25 @@ test.describe("Login works", () => {
tenantKey: "ABC",
title: "ABC Tenant",
description: "Nulla quam ipsam voluptatem cupiditate.",
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
{
tenantKey: "DEF",
title: "DEF Tenant",
description: "Inventore sed libero et.",
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
{
tenantKey: "XYZ",
title: "XYC Tenant",
description: "Itaque quibusdam tempora velit porro ut velit.",
- roles: ["ROLE_ADMIN"],
- },
+ roles: ["ROLE_ADMIN"]
+ }
],
user: {
fullname: "John Doe",
- email: "johndoe@example.com",
- },
+ email: "johndoe@example.com"
+ }
};
await route.fulfill({ json });
});
@@ -76,13 +87,13 @@ test.describe("Login works", () => {
tenantKey: "ABC",
title: "ABC Tenant",
description: "Description",
- roles: ["ROLE_EDITOR"],
- },
+ roles: ["ROLE_EDITOR"]
+ }
],
user: {
fullname: "John Doe",
- email: "johndoe@example.com",
- },
+ email: "johndoe@example.com"
+ }
};
await route.fulfill({ json });
});
@@ -91,13 +102,13 @@ test.describe("Login works", () => {
await page.locator("#login").click();
await expect(page.locator(".name")).toHaveText("John Doe");
await expect(page.locator(".sidebar-nav").locator(".nav-item")).toHaveCount(
- 4,
+ 4
);
});
test("Role editor should not be able to visit restricted route", async ({
- page,
- }) => {
+ page
+ }) => {
await page.goto("/admin/playlist/list");
await page.route("**/token", async (route) => {
const json = {
@@ -108,20 +119,20 @@ test.describe("Login works", () => {
tenantKey: "ABC",
title: "ABC Tenant",
description: "Description",
- roles: ["ROLE_EDITOR"],
- },
+ roles: ["ROLE_EDITOR"]
+ }
],
user: {
fullname: "John Doe",
- email: "johndoe@example.com",
- },
+ email: "johndoe@example.com"
+ }
};
await route.fulfill({ json });
});
await page.goto("/admin/shared/list");
await page.locator("#login").click();
await expect(page.locator("main").locator("div")).toHaveText(
- "Du har ikke adgang til denne side",
+ "Du har ikke adgang til denne side"
);
});
});
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index 2111aa95..939712c0 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -1,39 +1,10 @@
import { test, expect } from "@playwright/test";
+import { loginTest } from "./admin-helper.js";
+import { emptyJson } from "./data-fixtures.js";
test.describe("Nav items loads", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/screen/create");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/layouts*", async (route) => {
- const json = {
- "@id": "/v2/layouts",
- "hydra:member": [],
- };
- await route.fulfill({ json });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.locator("h1").getByText("Opret ny skærm")).toBeVisible();
+ await loginTest({ page });
});
test("It loads", async ({ page }) => {
@@ -41,51 +12,86 @@ test.describe("Nav items loads", () => {
});
test("It navigates to slides list", async ({ page }) => {
+ await page.route("**/media*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
+ // Go to media page first, since Slide is the starting page, to allow for link click.
+ await page.getByRole("link", { name: "Medier" }).click();
+
await page.getByRole("link", { name: "Slides" }).click();
await expect(page.locator("h1")).toHaveText("Slides");
});
test("It navigates to media list", async ({ page }) => {
+ await page.route("**/media*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
await page.getByRole("link", { name: "Medier" }).click();
await expect(page.locator("h1")).toHaveText("Medier");
});
test("It navigates to screens list", async ({ page }) => {
+ await page.route("**/screens*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
await page.getByRole("link", { name: "Skærme" }).click();
await expect(page.locator("h1")).toHaveText("Skærme");
});
test("It navigates to groups list", async ({ page }) => {
+ await page.route("**/screen-groups*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
await page.getByRole("link", { name: "Grupper" }).click();
await expect(page.locator("h1")).toHaveText("Grupper");
});
test("It navigates to playlists list", async ({ page }) => {
+ await page.route("**/playlists*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
await page.getByRole("link", { name: "Spillelister", exact: true }).click();
await expect(page.locator("h1")).toHaveText("Spillelister");
});
test("It navigates to themes list", async ({ page }) => {
+ await page.route("**/themes*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
await page.getByRole("link", { name: "Temaer" }).click();
await expect(page.locator("h1")).toHaveText("Temaer");
});
- test.skip("It navigates to create slide", async ({ page }) => {
- await page.goto("/admin/screen/create");
- await page.getByRole("button", { name: "Tilføj" }).click();
- await page.getByRole("link", { name: "Nyt slide", exact: true }).click();
- await expect(page.locator("h1")).toHaveText("Opret nyt slide");
+ test("It navigates to create slide", async ({ page }) => {
+ await page.route("**/playlists*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+ await page.route("**/themes*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+ await page.route("**/templates*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
+ await page.getByLabel("Tilføj nyt slide").first().click();
+ await expect(page.locator("h1")).toHaveText("Opret nyt slide:");
});
- test.skip("It navigates to create playlist", async ({ page }) => {
- await page.getByRole("button", { name: "Tilføj" }).click();
- await page.getByRole("link", { name: "Ny spilleliste" }).click();
- await expect(page.locator("h1")).toHaveText("Opret nyt spilleliste");
+ test("It navigates to create playlist", async ({ page }) => {
+ await page.route("**/tenants*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+ await page.getByLabel("Tilføj ny spilleliste").first().click();
+ await expect(page.locator("h1")).toHaveText("Opret ny spilleliste:");
});
- test.skip("It navigates to create screen", async ({ page }) => {
- await page.getByRole("button", { name: "Tilføj" }).click();
- await page.getByRole("link", { name: "Ny skærm" }).click();
+ test("It navigates to create screen", async ({ page }) => {
+ await page.getByLabel("Tilføj ny skærm").first().click();
await expect(page.locator("h1")).toHaveText("Opret ny skærm");
});
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index 11e7f8cb..0cb21a3b 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -329,16 +329,37 @@ const errorJson = {
"hydra:description": "An error occurred",
};
-const emptySlidesJson = {
+const emptyJson = {
"@id": "/v2/slides",
"hydra:member": [],
- "hydra:totalItems": 100,
+ "hydra:totalItems": 0,
"hydra:view": {
"@id": "/v2/slides?itemsPerPage=0\u0026title=",
"@type": "hydra:PartialCollectionView",
},
};
+const accessConfigJson = {
+ campaign: {
+ roles: ["ROLE_ADMIN"],
+ },
+ screen: {
+ roles: ["ROLE_ADMIN"],
+ },
+ settings: {
+ roles: ["ROLE_ADMIN"],
+ },
+ groups: {
+ roles: ["ROLE_ADMIN"],
+ },
+ shared: {
+ roles: ["ROLE_ADMIN"],
+ },
+ users: {
+ roles: ["ROLE_ADMIN", "ROLE_EXTERNAL_USER_ADMIN"],
+ },
+};
+
const slidesJson1 = {
"@id": "/v2/slides",
"hydra:member": [
@@ -607,6 +628,7 @@ export {
feedSourcesJson2,
feedSourcesJson3,
errorJson,
- emptySlidesJson,
+ emptyJson,
slidesJson1,
+ accessConfigJson,
};
From 72795520de5ea3d06e9d29a2e2d9ec29b5181609 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 7 Aug 2025 13:13:13 +0200
Subject: [PATCH 24/30] 4565: Reverted how config is loaded in client and admin
---
assets/admin/admin-config-loader.js | 59 ++++++
assets/admin/app.jsx | 6 +-
.../admin/components/screen/screen-list.jsx | 7 +-
.../admin/components/screen/screen-status.jsx | 7 +-
assets/admin/components/user/login.jsx | 11 +-
assets/client/app.jsx | 19 +-
assets/client/client-config-loader.js | 85 ++++++++
assets/client/components/screen.jsx | 58 +++---
assets/client/service/content-service.js | 23 ++-
assets/client/service/release-service.js | 14 +-
assets/client/service/schedule-service.js | 31 +--
assets/client/service/tenant-service.js | 1 -
assets/client/service/token-service.js | 16 +-
assets/client/util/release-loader.js | 2 +-
assets/shared/config-loader.js | 9 -
assets/tests/admin/admin-helper.js | 6 +-
assets/tests/admin/admin-login.spec.js | 9 +-
assets/tests/admin/data-fixtures.js | 193 ++++++++++--------
config/routes.yaml | 10 +
config/services.yaml | 4 +-
.../Admin/AdminConfigController.php | 33 +++
src/Controller/Admin/AdminController.php | 15 +-
.../Client/ClientConfigController.php | 39 ++++
src/Controller/Client/ClientController.php | 21 +-
templates/admin/admin.html.twig | 4 -
templates/client/client.html.twig | 4 -
26 files changed, 453 insertions(+), 233 deletions(-)
create mode 100644 assets/admin/admin-config-loader.js
create mode 100644 assets/client/client-config-loader.js
delete mode 100644 assets/shared/config-loader.js
create mode 100644 src/Controller/Admin/AdminConfigController.php
create mode 100644 src/Controller/Client/ClientConfigController.php
diff --git a/assets/admin/admin-config-loader.js b/assets/admin/admin-config-loader.js
new file mode 100644
index 00000000..c0158194
--- /dev/null
+++ b/assets/admin/admin-config-loader.js
@@ -0,0 +1,59 @@
+let configData = null;
+let activePromise = null;
+
+const AdminConfigLoader = {
+ async loadConfig() {
+ if (activePromise) {
+ return activePromise;
+ }
+
+ activePromise = new Promise((resolve) => {
+ if (configData !== null) {
+ resolve(configData);
+ } else {
+ fetch("/config/admin")
+ .then((response) => response.json())
+ .then((data) => {
+ configData = data;
+ resolve(configData);
+ })
+ .catch(() => {
+ if (configData !== null) {
+ resolve(configData);
+ } else {
+ // eslint-disable-next-line no-console
+ console.error(
+ "Could not load config. Will use default config."
+ );
+
+ // Default config.
+ resolve({
+ rejseplanenApiKey: null,
+ touchButtonRegions: false,
+ showScreenStatus: false,
+ enhancedPreview: false,
+ loginMethods: [
+ {
+ type: "username-password",
+ enabled: true,
+ provider: "username-password",
+ label: null,
+ icon: null,
+ },
+ ],
+ });
+ }
+ })
+ .finally(() => {
+ activePromise = null;
+ });
+ }
+ });
+
+ return activePromise;
+ },
+};
+
+Object.freeze(AdminConfigLoader);
+
+export default AdminConfigLoader;
diff --git a/assets/admin/app.jsx b/assets/admin/app.jsx
index 315bf4a4..5b839224 100644
--- a/assets/admin/app.jsx
+++ b/assets/admin/app.jsx
@@ -39,7 +39,7 @@ import UsersList from "./components/users/users-list";
import ActivationCodeList from "./components/activation-code/activation-code-list";
import ActivationCodeCreate from "./components/activation-code/activation-code-create";
import ActivationCodeActivate from "./components/activation-code/activation-code-activate";
-import ConfigLoader from "../shared/config-loader.js";
+import AdminConfigLoader from "./admin-config-loader.js";
import "react-toastify/dist/ReactToastify.css";
import "./app.scss";
import FeedSourcesList from "./components/feed-sources/feed-sources-list";
@@ -90,7 +90,9 @@ function App() {
};
useEffect(() => {
- setConfig(ConfigLoader.getConfig());
+ AdminConfigLoader.loadConfig().then((loadedConfig) => {
+ setConfig(loadedConfig);
+ })
}, []);
const handleReauthenticate = () => {
diff --git a/assets/admin/components/screen/screen-list.jsx b/assets/admin/components/screen/screen-list.jsx
index 9308be6c..eaaace95 100644
--- a/assets/admin/components/screen/screen-list.jsx
+++ b/assets/admin/components/screen/screen-list.jsx
@@ -18,7 +18,7 @@ import {
displayError,
} from "../util/list/toast-component/display-toast";
import "./screen-list.scss";
-import ConfigLoader from "../../../shared/config-loader.js";
+import AdminConfigLoader from "../../admin-config-loader.js";
/**
* The screen list component.
@@ -68,8 +68,9 @@ function ScreenList() {
});
useEffect(() => {
- const config = ConfigLoader.getConfig();
- setShowScreenStatus(config.showScreenStatus);
+ AdminConfigLoader.loadConfig().then((loadedConfig) => {
+ setShowScreenStatus(loadedConfig.showScreenStatus);
+ });
}, []);
useEffect(() => {
diff --git a/assets/admin/components/screen/screen-status.jsx b/assets/admin/components/screen/screen-status.jsx
index 6399e0b3..1c10835b 100644
--- a/assets/admin/components/screen/screen-status.jsx
+++ b/assets/admin/components/screen/screen-status.jsx
@@ -18,7 +18,7 @@ import idFromUrl from "../util/helpers/id-from-url";
import { api } from "../../redux/api/api.generated.ts";
import { displayError } from "../util/list/toast-component/display-toast";
import FormInput from "../util/forms/form-input";
-import ConfigLoader from "../../../shared/config-loader.js";
+import AdminConfigLoader from "../../admin-config-loader.js";
/**
* Displays screen status.
@@ -102,8 +102,9 @@ function ScreenStatus({ screen, handleInput = () => {}, mode = "default" }) {
}, [status]);
useEffect(() => {
- const config = ConfigLoader.getConfig();
- setShowScreenStatus(config.showScreenStatus);
+ AdminConfigLoader.loadConfig().then((loadedConfig) => {
+ setShowScreenStatus(loadedConfig.showScreenStatus);
+ });
}, []);
if (mode === "minimal") {
diff --git a/assets/admin/components/user/login.jsx b/assets/admin/components/user/login.jsx
index 6c7c6383..bcfb922e 100644
--- a/assets/admin/components/user/login.jsx
+++ b/assets/admin/components/user/login.jsx
@@ -9,7 +9,7 @@ import {MultiSelect} from "react-multi-select-component";
import UserContext from "../../context/user-context";
import FormInput from "../util/forms/form-input";
import {api} from "../../redux/api/api.generated.ts";
-import ConfigLoader from "../../../shared/config-loader.js";
+import AdminConfigLoader from "../../admin-config-loader.js";
import {displayError} from "../util/list/toast-component/display-toast";
import localStorageKeys from "../util/local-storage-keys";
import LoginSidebar from "../navigation/login-sidebar/login-sidebar";
@@ -193,7 +193,6 @@ function Login() {
};
useEffect(() => {
- const config = ConfigLoader.getConfig();
const loginMethodDefaults = [
{
type: "oidc",
@@ -217,9 +216,11 @@ function Login() {
},
];
- setLoginMethods(
- config.loginMethods ?? loginMethodDefaults
- );
+ AdminConfigLoader.loadConfig().then((loadedConfig) => {
+ setLoginMethods(
+ loadedConfig.loginMethods ?? loginMethodDefaults
+ );
+ });
}, []);
useEffect(() => {
diff --git a/assets/client/app.jsx b/assets/client/app.jsx
index 81e91e52..477055dd 100644
--- a/assets/client/app.jsx
+++ b/assets/client/app.jsx
@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import Screen from "./components/screen.jsx";
import ContentService from "./service/content-service";
-import ConfigLoader from "../shared/config-loader";
+import ClientConfigLoader from "./client-config-loader.js";
import logger from "./logger/logger";
import "./app.scss";
import fallback from "./assets/fallback.png";
@@ -97,12 +97,12 @@ function App({ preview, previewId }) {
clearTimeout(checkLoginTimeoutRef.current);
}
- const config = ConfigLoader.getConfig();
-
- checkLoginTimeoutRef.current = setTimeout(
- checkLogin,
- config.loginCheckTimeout ?? defaults.loginCheckTimeoutDefault
- );
+ ClientConfigLoader.loadConfig().then((config) => {
+ checkLoginTimeoutRef.current = setTimeout(
+ checkLogin,
+ config.loginCheckTimeout ?? defaults.loginCheckTimeoutDefault
+ );
+ });
};
/* eslint-enable no-use-before-define */
@@ -220,8 +220,9 @@ function App({ preview, previewId }) {
tokenService.checkToken();
- const config = ConfigLoader.getConfig();
- setDebug(config.debug ?? false);
+ ClientConfigLoader.loadConfig().then((config) => {
+ setDebug(config.debug ?? false);
+ });
releaseService.checkForNewRelease().finally(() => {
releaseService.setPreviousBootInUrl();
diff --git a/assets/client/client-config-loader.js b/assets/client/client-config-loader.js
new file mode 100644
index 00000000..a791dafe
--- /dev/null
+++ b/assets/client/client-config-loader.js
@@ -0,0 +1,85 @@
+// Only fetch new config if more than 15 minutes have passed.
+import appStorage from './util/app-storage';
+
+const configFetchIntervalDefault = 15 * 60 * 1000;
+
+// Defaults.
+let configData = null;
+
+// Last time the config was fetched.
+let latestFetchTimestamp = 0;
+
+let activePromise = null;
+
+const ClientConfigLoader = {
+ async loadConfig() {
+ if (activePromise) {
+ return activePromise;
+ }
+
+ activePromise = new Promise((resolve) => {
+ const nowTimestamp = new Date().getTime();
+
+ if (
+ latestFetchTimestamp +
+ (configData?.configFetchInterval ?? configFetchIntervalDefault) >=
+ nowTimestamp
+ ) {
+ resolve(configData);
+ } else {
+ fetch(`/config/client`)
+ .then((response) => response.json())
+ .then((data) => {
+ latestFetchTimestamp = nowTimestamp;
+ configData = data;
+
+ // Make api endpoint available through localstorage.
+ appStorage.setApiUrl(configData.apiEndpoint);
+
+ resolve(configData);
+ })
+ .catch(() => {
+ if (configData !== null) {
+ resolve(configData);
+ } else {
+ // eslint-disable-next-line no-console
+ console.error(
+ 'Could not load config. Will use default config.'
+ );
+
+ // Default config.
+ resolve({
+ apiEndpoint: '/api',
+ dataStrategy: {
+ type: 'pull',
+ config: {
+ interval: 30000,
+ },
+ },
+ loginCheckTimeout: 20000,
+ configFetchInterval: 900000,
+ refreshTokenTimeout: 15000,
+ releaseTimestampIntervalTimeout: 600000,
+ colorScheme: {
+ type: 'library',
+ lat: 56.0,
+ lng: 10.0,
+ },
+ schedulingInterval: 60000,
+ debug: false,
+ });
+ }
+ })
+ .finally(() => {
+ activePromise = null;
+ });
+ }
+ });
+
+ return activePromise;
+ },
+};
+
+Object.freeze(ClientConfigLoader);
+
+export default ClientConfigLoader;
diff --git a/assets/client/components/screen.jsx b/assets/client/components/screen.jsx
index d04bfce2..73d9d378 100644
--- a/assets/client/components/screen.jsx
+++ b/assets/client/components/screen.jsx
@@ -6,7 +6,7 @@ import Region from "./region.jsx";
import "./screen.scss";
import logger from "../logger/logger";
import TouchRegion from "./touch-region.jsx";
-import ConfigLoader from "../../shared/config-loader";
+import ClientConfigLoader from "../client-config-loader.js";
/**
* Screen component.
@@ -32,41 +32,41 @@ function Screen({ screen }) {
};
const refreshColorScheme = () => {
- const config = ConfigLoader.getConfig();
-
logger.info("Refreshing color scheme.");
- const now = new Date();
- let colorScheme = "";
+ ClientConfigLoader.loadConfig().then((config) => {
+ const now = new Date();
+ let colorScheme;
- if (config.colorScheme?.type === "library") {
- // Default to somewhere in Denmark.
- const times = SunCalc.getTimes(
- now,
- config.colorScheme?.lat ?? 56.0,
- config.colorScheme?.lng ?? 10.0
- );
+ if (config.colorScheme?.type === "library") {
+ // Default to somewhere in Denmark.
+ const times = SunCalc.getTimes(
+ now,
+ config.colorScheme?.lat ?? 56.0,
+ config.colorScheme?.lng ?? 10.0
+ );
- if (now > times.sunrise && now < times.sunset) {
- logger.info("Light color scheme activated.");
- colorScheme = "color-scheme-light";
+ if (now > times.sunrise && now < times.sunset) {
+ logger.info("Light color scheme activated.");
+ colorScheme = "color-scheme-light";
+ } else {
+ logger.info("Dark color scheme activated.");
+ colorScheme = "color-scheme-dark";
+ }
} else {
- logger.info("Dark color scheme activated.");
- colorScheme = "color-scheme-dark";
+ // Browser based.
+ colorScheme = window?.matchMedia("(prefers-color-scheme: dark)").matches
+ ? "color-scheme-dark"
+ : "color-scheme-light";
}
- } else {
- // Browser based.
- colorScheme = window?.matchMedia("(prefers-color-scheme: dark)").matches
- ? "color-scheme-dark"
- : "color-scheme-light";
- }
- // Set class name on html root.
- document.documentElement.classList.remove(
- "color-scheme-light",
- "color-scheme-dark"
- );
- document.documentElement.classList.add(colorScheme);
+ // Set class name on html root.
+ document.documentElement.classList.remove(
+ "color-scheme-light",
+ "color-scheme-dark"
+ );
+ document.documentElement.classList.add(colorScheme);
+ });
};
useEffect(() => {
diff --git a/assets/client/service/content-service.js b/assets/client/service/content-service.js
index 34713c0d..c1ae1665 100644
--- a/assets/client/service/content-service.js
+++ b/assets/client/service/content-service.js
@@ -8,7 +8,7 @@ import {
import logger from "../logger/logger";
import DataSync from "../data-sync/data-sync";
import ScheduleService from "./schedule-service";
-import ConfigLoader from "../../shared/config-loader";
+import ClientConfigLoader from "../client-config-loader.js";
/**
* ContentService.
@@ -48,18 +48,19 @@ class ContentService {
startSyncing(screenPath) {
logger.info("Starting data synchronization");
- const config = ConfigLoader.getConfig();
- const dataStrategyConfig = {
- interval: config.pullStrategyInterval,
- endpoint: "",
- };
+ ClientConfigLoader.loadConfig().then((config) => {
+ const dataStrategyConfig = {
+ interval: config.pullStrategyInterval,
+ endpoint: "",
+ };
- if (screenPath) {
- dataStrategyConfig.entryPoint = screenPath;
- }
+ if (screenPath) {
+ dataStrategyConfig.entryPoint = screenPath;
+ }
- this.dataSync = new DataSync(dataStrategyConfig);
- this.dataSync.start();
+ this.dataSync = new DataSync(dataStrategyConfig);
+ this.dataSync.start();
+ });
}
/**
diff --git a/assets/client/service/release-service.js b/assets/client/service/release-service.js
index 1e7389e6..c14c488f 100644
--- a/assets/client/service/release-service.js
+++ b/assets/client/service/release-service.js
@@ -1,5 +1,5 @@
import ReleaseLoader from "../util/release-loader";
-import ConfigLoader from "../../shared/config-loader";
+import ClientConfigLoader from "../client-config-loader.js";
import defaults from "../util/defaults";
import idFromPath from "../util/id-from-path";
import appStorage from "../util/app-storage";
@@ -70,13 +70,13 @@ class ReleaseService {
};
startReleaseCheck = () => {
- const config = ConfigLoader.getConfig();
-
- this.releaseCheckInterval = setInterval(
- this.checkForNewRelease,
- config.releaseTimestampIntervalTimeout ??
+ ClientConfigLoader.loadConfig().then((config) => {
+ this.releaseCheckInterval = setInterval(
+ this.checkForNewRelease,
+ config.releaseTimestampIntervalTimeout ??
defaults.releaseTimestampIntervalTimeoutDefault,
- );
+ );
+ });
};
stopReleaseCheck = () => {
diff --git a/assets/client/service/schedule-service.js b/assets/client/service/schedule-service.js
index dbb95bfd..fddbcff2 100644
--- a/assets/client/service/schedule-service.js
+++ b/assets/client/service/schedule-service.js
@@ -4,7 +4,7 @@ import Md5 from "crypto-js/md5";
import Base64 from "crypto-js/enc-base64";
import isPublished from "../util/isPublished";
import logger from "../logger/logger";
-import ConfigLoader from "../../shared/config-loader";
+import ClientConfigLoader from "../client-config-loader.js";
import ScheduleUtils from "../util/schedule";
/**
@@ -94,20 +94,21 @@ class ScheduleService {
const { intervals } = this;
if (!Object.prototype.hasOwnProperty.call(intervals, regionId)) {
- const config = ConfigLoader.getConfig();
- const schedulingInterval = config?.schedulingInterval ?? 60000;
-
- // Extra check because of async.
- if (!Object.prototype.hasOwnProperty.call(intervals, regionId)) {
- logger.info(
- `registering scheduling interval for region: ${regionId}, with an update rate of ${schedulingInterval}`,
- );
-
- this.intervals[regionId] = setInterval(
- () => this.checkScheduling(regionId),
- schedulingInterval,
- );
- }
+ ClientConfigLoader.loadConfig().then((config) => {
+ const schedulingInterval = config?.schedulingInterval ?? 60000;
+
+ // Extra check because of async.
+ if (!Object.prototype.hasOwnProperty.call(intervals, regionId)) {
+ logger.info(
+ `registering scheduling interval for region: ${regionId}, with an update rate of ${schedulingInterval}`,
+ );
+
+ this.intervals[regionId] = setInterval(
+ () => this.checkScheduling(regionId),
+ schedulingInterval,
+ );
+ }
+ });
}
if (newContent) {
diff --git a/assets/client/service/tenant-service.js b/assets/client/service/tenant-service.js
index ba7e8af3..66512e76 100644
--- a/assets/client/service/tenant-service.js
+++ b/assets/client/service/tenant-service.js
@@ -1,4 +1,3 @@
-import ConfigLoader from "../../shared/config-loader";
import appStorage from "../util/app-storage";
class TenantService {
diff --git a/assets/client/service/token-service.js b/assets/client/service/token-service.js
index 011708e8..5d80706f 100644
--- a/assets/client/service/token-service.js
+++ b/assets/client/service/token-service.js
@@ -1,6 +1,6 @@
import logger from "../logger/logger";
import appStorage from "../util/app-storage";
-import ConfigLoader from "../../shared/config-loader";
+import ClientConfigLoader from "../client-config-loader.js";
import defaults from "../util/defaults";
import statusService from "./status-service";
import constants from "../util/constants";
@@ -219,13 +219,13 @@ class TokenService {
};
startRefreshing = () => {
- const config = ConfigLoader.getConfig();
-
- // Start refresh token interval.
- this.refreshInterval = setInterval(
- this.ensureFreshToken,
- config.refreshTokenTimeout ?? defaults.refreshTokenTimeoutDefault,
- );
+ ClientConfigLoader.loadConfig().then((config) => {
+ // Start refresh token interval.
+ this.refreshInterval = setInterval(
+ this.ensureFreshToken,
+ config.refreshTokenTimeout ?? defaults.refreshTokenTimeoutDefault,
+ );
+ });
};
stopRefreshing = () => {
diff --git a/assets/client/util/release-loader.js b/assets/client/util/release-loader.js
index 1b3f6bd1..e6ec48bb 100644
--- a/assets/client/util/release-loader.js
+++ b/assets/client/util/release-loader.js
@@ -8,7 +8,7 @@ export default class ReleaseLoader {
.then((response) => response.json())
.catch((err) => {
/* eslint-disable-next-line no-console */
- console.error("Could not find release.json. Returning defaults.", err);
+ console.warn("Could not find release.json. Returning defaults.", err);
return {
releaseTimestamp: null,
diff --git a/assets/shared/config-loader.js b/assets/shared/config-loader.js
deleted file mode 100644
index e1aac43a..00000000
--- a/assets/shared/config-loader.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const ConfigLoader = {
- getConfig() {
- return DISPLAY_CONFIG;
- },
-};
-
-Object.freeze(ConfigLoader);
-
-export default ConfigLoader;
diff --git a/assets/tests/admin/admin-helper.js b/assets/tests/admin/admin-helper.js
index 196c4c9e..400a4a50 100644
--- a/assets/tests/admin/admin-helper.js
+++ b/assets/tests/admin/admin-helper.js
@@ -1,5 +1,5 @@
import {
- accessConfigJson,
+ accessConfigJson, adminConfigJson,
emptyJson,
feedSourcesJson,
tokenJson
@@ -22,6 +22,10 @@ const loginTest = async ({ page }) => {
await route.fulfill({ json: accessConfigJson});
})
+ await page.route('**/config/admin', async (route) => {
+ await route.fulfill({ json: adminConfigJson });
+ })
+
await page.route("**/slides*", async (route) => {
await route.fulfill({ json: emptyJson });
});
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index aa51d8d1..23b72634 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -1,14 +1,20 @@
import { test, expect } from "@playwright/test";
-import { accessConfigJson, emptyJson } from "./data-fixtures.js";
+import { accessConfigJson, adminConfigJson, emptyJson } from "./data-fixtures.js";
test.describe("Login works", () => {
test.beforeEach(async ({ page }) => {
await page.route("**/access-config.json", async (route) => {
await route.fulfill({ json: accessConfigJson });
});
+
+ await page.route('**/config/admin', async (route) => {
+ await route.fulfill({ json: adminConfigJson });
+ })
});
test("Login one tenant works", async ({ page }) => {
+ await page.goto("/admin/playlists/list");
+
await page.route("**/playlists*", async (route) => {
await route.fulfill({ json: emptyJson });
});
@@ -33,7 +39,6 @@ test.describe("Login works", () => {
await route.fulfill({ json });
});
- await page.goto("/admin/playlist/list");
await page.locator("#login").click();
await expect(page.locator(".name")).toHaveText("John Doe");
});
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index 0cb21a3b..56f3d735 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -6,13 +6,13 @@ const tokenJson = {
tenantKey: "ABC",
title: "ABC Tenant",
description: "Description",
- roles: ["ROLE_ADMIN"],
- },
+ roles: ["ROLE_ADMIN"]
+ }
],
user: {
fullname: "John Doe",
- email: "johndoe@example.com",
- },
+ email: "johndoe@example.com"
+ }
};
const feedSourcesJson = {
@@ -36,7 +36,7 @@ const feedSourcesJson = {
createdBy: "admin@example.com",
id: "01JBBP48CS9CV80XRWRP8CAETJ",
created: "2024-10-29T09:26:25.000Z",
- modified: "2024-10-29T09:26:25.000Z",
+ modified: "2024-10-29T09:26:25.000Z"
},
{
"@id": "/v2/feed-sources/01JB9MSQEH75HC3GG75XCVP2WH",
@@ -48,7 +48,7 @@ const feedSourcesJson = {
secrets: [],
feeds: [
"/v2/feeds/01JB9R7EPN9NPW117C22NY31KH",
- "/v2/feeds/01JBBQMF72W2V36TWF6VXFA5Z7",
+ "/v2/feeds/01JBBQMF72W2V36TWF6VXFA5Z7"
],
admin: [
{
@@ -58,7 +58,7 @@ const feedSourcesJson = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
+ formGroupClasses: "col-md-6"
},
{
key: "rss-number-of-entries",
@@ -68,7 +68,7 @@ const feedSourcesJson = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
+ formGroupClasses: "col-md-6 mb-3"
},
{
key: "rss-entry-duration",
@@ -77,15 +77,15 @@ const feedSourcesJson = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
+ formGroupClasses: "col-md-6 mb-3"
+ }
],
supportedFeedOutputType: "rss",
modifiedBy: "admin@example.com",
createdBy: "admin@example.com",
id: "01JB9MSQEH75HC3GG75XCVP2WH",
created: "2024-10-28T14:24:43.000Z",
- modified: "2024-10-28T15:23:28.000Z",
+ modified: "2024-10-28T15:23:28.000Z"
},
{
"@id": "/v2/feed-sources/01JB1DH8G4CXKGX5JRTYDHDPSP",
@@ -102,7 +102,7 @@ const feedSourcesJson = {
createdBy: "",
id: "01JB1DH8G4CXKGX5JRTYDHDPSP",
created: "2024-10-25T10:43:50.000Z",
- modified: "2024-10-25T10:43:50.000Z",
+ modified: "2024-10-25T10:43:50.000Z"
},
{
"@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
@@ -122,7 +122,7 @@ const feedSourcesJson = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
+ formGroupClasses: "col-md-6"
},
{
key: "rss-number-of-entries",
@@ -132,7 +132,7 @@ const feedSourcesJson = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
+ formGroupClasses: "col-md-6 mb-3"
},
{
key: "rss-entry-duration",
@@ -141,15 +141,15 @@ const feedSourcesJson = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
+ formGroupClasses: "col-md-6 mb-3"
+ }
],
supportedFeedOutputType: "instagram",
modifiedBy: "",
createdBy: "",
id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z",
+ modified: "2024-09-17T09:33:12.000Z"
},
{
"@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
@@ -169,7 +169,7 @@ const feedSourcesJson = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
+ formGroupClasses: "col-md-6"
},
{
key: "rss-number-of-entries",
@@ -179,7 +179,7 @@ const feedSourcesJson = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
+ formGroupClasses: "col-md-6 mb-3"
},
{
key: "rss-entry-duration",
@@ -188,17 +188,17 @@ const feedSourcesJson = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
+ formGroupClasses: "col-md-6 mb-3"
+ }
],
supportedFeedOutputType: "rss",
modifiedBy: "",
createdBy: "",
id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
created: "2024-06-29T05:47:07.000Z",
- modified: "2024-10-21T18:01:25.000Z",
- },
- ],
+ modified: "2024-10-21T18:01:25.000Z"
+ }
+ ]
};
const feedSourcesJson2 = {
@@ -225,7 +225,7 @@ const feedSourcesJson2 = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
+ formGroupClasses: "col-md-6"
},
{
key: "rss-number-of-entries",
@@ -235,7 +235,7 @@ const feedSourcesJson2 = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
+ formGroupClasses: "col-md-6 mb-3"
},
{
key: "rss-entry-duration",
@@ -244,15 +244,15 @@ const feedSourcesJson2 = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
+ formGroupClasses: "col-md-6 mb-3"
+ }
],
supportedFeedOutputType: "instagram",
modifiedBy: "",
createdBy: "",
id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z",
+ modified: "2024-09-17T09:33:12.000Z"
},
{
"@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
@@ -272,7 +272,7 @@ const feedSourcesJson2 = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6",
+ formGroupClasses: "col-md-6"
},
{
key: "rss-number-of-entries",
@@ -282,7 +282,7 @@ const feedSourcesJson2 = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3",
+ formGroupClasses: "col-md-6 mb-3"
},
{
key: "rss-entry-duration",
@@ -291,17 +291,17 @@ const feedSourcesJson2 = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3",
- },
+ formGroupClasses: "col-md-6 mb-3"
+ }
],
supportedFeedOutputType: "rss",
modifiedBy: "",
createdBy: "",
id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
created: "2024-06-29T05:47:07.000Z",
- modified: "2024-10-21T18:01:25.000Z",
- },
- ],
+ modified: "2024-10-21T18:01:25.000Z"
+ }
+ ]
};
const feedSourcesJson3 = {
@@ -319,14 +319,14 @@ const feedSourcesJson3 = {
createdBy: "",
id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z",
+ modified: "2024-09-17T09:33:12.000Z"
};
const errorJson = {
"@context": "/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
- "hydra:description": "An error occurred",
+ "hydra:description": "An error occurred"
};
const emptyJson = {
@@ -335,29 +335,54 @@ const emptyJson = {
"hydra:totalItems": 0,
"hydra:view": {
"@id": "/v2/slides?itemsPerPage=0\u0026title=",
- "@type": "hydra:PartialCollectionView",
- },
+ "@type": "hydra:PartialCollectionView"
+ }
+};
+
+const adminConfigJson = {
+ rejseplanenApiKey: null,
+ touchButtonRegions: false,
+ showScreenStatus: true,
+ loginMethods: [
+ {
+ type: "username-password",
+ enabled: true,
+ provider: "username-password",
+ label: ""
+ },
+ ],
+ enhancedPreview: true,
+};
+
+const clientConfigJson = {
+ loginCheckTimeout: 1000 * 60 * 60,
+ refreshTokenTimeout: 1000 * 60 * 60,
+ releaseTimestampIntervalTimeout: 1000 * 60 * 60,
+ pullStrategyInterval: 1000 * 60 * 60,
+ schedulingInterval: 1000 * 60 * 60,
+ debug: false,
+ logging: false
};
const accessConfigJson = {
campaign: {
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
screen: {
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
settings: {
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
groups: {
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
shared: {
- roles: ["ROLE_ADMIN"],
+ roles: ["ROLE_ADMIN"]
},
users: {
- roles: ["ROLE_ADMIN", "ROLE_EXTERNAL_USER_ADMIN"],
- },
+ roles: ["ROLE_ADMIN", "ROLE_EXTERNAL_USER_ADMIN"]
+ }
};
const slidesJson1 = {
@@ -375,21 +400,21 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: [],
+ options: []
},
theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0Y8",
onPlaylists: [],
duration: 107879,
published: {
from: null,
- to: null,
+ to: null
},
media: [
"/v2/media/00042YZWK214MP01NA1GF517Q2",
"/v2/media/00TET3FF6K1Q011N5S12621E4H",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK",
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK"
],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -403,20 +428,20 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: [],
+ options: []
},
theme: "",
onPlaylists: [],
duration: 80335,
published: {
from: "2021-03-19T22:20:54.000Z",
- to: "2021-12-28T06:13:08.000Z",
+ to: "2021-12-28T06:13:08.000Z"
},
media: [
"/v2/media/009H64MSPN1HEH0DTV2DEV085B",
- "/v2/media/00SC0JP6PV2QYS06R70SS31K68",
+ "/v2/media/00SC0JP6PV2QYS06R70SS31K68"
],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -430,17 +455,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
- options: [],
+ options: []
},
theme: "",
onPlaylists: [],
duration: 21254,
published: {
from: null,
- to: null,
+ to: null
},
media: ["/v2/media/00YMKGY3FM106Q0SRV077G0KEX"],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -454,17 +479,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
- options: [],
+ options: []
},
theme: "",
onPlaylists: [],
duration: 60870,
published: {
from: "2021-02-26T20:12:10.000Z",
- to: "2021-06-08T05:44:41.000Z",
+ to: "2021-06-08T05:44:41.000Z"
},
media: ["/v2/media/00BBYAKF190NMJ0FH118V91VV7"],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -478,17 +503,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: [],
+ options: []
},
theme: "",
onPlaylists: [],
duration: 75535,
published: {
from: null,
- to: "1996-02-16T00:54:17.000Z",
+ to: "1996-02-16T00:54:17.000Z"
},
media: ["/v2/media/0027FWF7Y014RG0KW9053S1AX6"],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -502,17 +527,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: [],
+ options: []
},
theme: "",
onPlaylists: [],
duration: 92829,
published: {
from: "2021-12-29T03:25:23.000Z",
- to: null,
+ to: null
},
media: ["/v2/media/001AX5W2S909NW0K5A0NVE0NS6"],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -526,21 +551,21 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: [],
+ options: []
},
theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YN",
onPlaylists: [],
duration: 41589,
published: {
from: null,
- to: "1989-10-31T03:15:44.000Z",
+ to: "1989-10-31T03:15:44.000Z"
},
media: [
"/v2/media/00CX9N9EJE10WT1PVM10G51N13",
"/v2/media/016HWRGVWJ170F1AF2099T13JW",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK",
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK"
],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -554,17 +579,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: [],
+ options: []
},
theme: "",
onPlaylists: [],
duration: 106091,
published: {
from: "2022-01-11T14:56:13.000Z",
- to: "2022-02-05T09:10:20.000Z",
+ to: "2022-02-05T09:10:20.000Z"
},
media: ["/v2/media/00F1M5J6BY1GS517RP1T1B1306"],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -578,17 +603,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/016MHSNKCH1PQW1VY615JC19Y3",
- options: [],
+ options: []
},
theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
onPlaylists: [],
duration: 79809,
published: {
from: "2021-08-10T06:26:30.000Z",
- to: "2021-08-12T15:26:21.000Z",
+ to: "2021-08-12T15:26:21.000Z"
},
media: ["/v2/media/011ZBTXPF8123R1BA31CQR18HA"],
- content: [],
+ content: []
},
{
"@type": "Slide",
@@ -602,24 +627,24 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: [],
+ options: []
},
theme: "/v2/themes/01FPFH3WXAX8JMJTQHBV2BYEDM",
onPlaylists: [],
duration: 37983,
published: {
from: "2022-01-24T16:30:24.000Z",
- to: "2022-02-05T09:19:31.000Z",
+ to: "2022-02-05T09:19:31.000Z"
},
media: [
"/v2/media/0010X8D6JJ03G50T1J1FCW1XH6",
"/v2/media/00F1M5J6BY1GS517RP1T1B1306",
- "/v2/media/00KXYB7Z291JXC1SY30G161HQD",
+ "/v2/media/00KXYB7Z291JXC1SY30G161HQD"
],
- content: [],
- },
+ content: []
+ }
],
- "hydra:totalItems": 60,
+ "hydra:totalItems": 60
};
export {
@@ -631,4 +656,6 @@ export {
emptyJson,
slidesJson1,
accessConfigJson,
+ clientConfigJson,
+ adminConfigJson,
};
diff --git a/config/routes.yaml b/config/routes.yaml
index f1185ed4..82b9feaa 100644
--- a/config/routes.yaml
+++ b/config/routes.yaml
@@ -36,6 +36,16 @@ client:
methods: ['GET']
controller: App\Controller\Client\ClientController
+admin_config:
+ path: /config/admin
+ methods: ['GET']
+ controller: App\Controller\Admin\AdminConfigController
+
+client_config:
+ path: /config/client
+ methods: ['GET']
+ controller: App\Controller\Client\ClientConfigController
+
when@dev:
templates:
path: /template{subroutes}
diff --git a/config/services.yaml b/config/services.yaml
index 429b8939..1e6406c7 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -53,7 +53,7 @@ services:
Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface: '@Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationFailureHandler'
Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface: '@Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler'
- App\Controller\Admin\AdminController:
+ App\Controller\Admin\AdminConfigController:
arguments:
$rejseplanenApiKey: '%env(ADMIN_REJSEPLANEN_APIKEY)%'
$touchButtonRegions: '%env(bool:ADMIN_TOUCH_BUTTON_REGIONS)%'
@@ -61,7 +61,7 @@ services:
$loginMethods: '%env(json:ADMIN_LOGIN_METHODS)%'
$enhancedPreview: '%env(bool:ADMIN_ENHANCED_PREVIEW)%'
- App\Controller\Client\ClientController:
+ App\Controller\Client\ClientConfigController:
arguments:
$loginCheckTimeout: '%env(int:CLIENT_LOGIN_CHECK_TIMEOUT)%'
$refreshTokenTimeout: '%env(int:CLIENT_REFRESH_TOKEN_TIMEOUT)%'
diff --git a/src/Controller/Admin/AdminConfigController.php b/src/Controller/Admin/AdminConfigController.php
new file mode 100644
index 00000000..6d61d2af
--- /dev/null
+++ b/src/Controller/Admin/AdminConfigController.php
@@ -0,0 +1,33 @@
+ $this->rejseplanenApiKey,
+ 'touchButtonRegions' => $this->touchButtonRegions,
+ 'showScreenStatus' => $this->showScreenStatus,
+ 'loginMethods' => $this->loginMethods,
+ 'enhancedPreview' => $this->enhancedPreview,
+ ]);
+ }
+}
diff --git a/src/Controller/Admin/AdminController.php b/src/Controller/Admin/AdminController.php
index 757ddb76..98493248 100644
--- a/src/Controller/Admin/AdminController.php
+++ b/src/Controller/Admin/AdminController.php
@@ -13,11 +13,6 @@
class AdminController extends AbstractController
{
public function __construct(
- private readonly string $rejseplanenApiKey,
- private readonly bool $touchButtonRegions,
- private readonly bool $showScreenStatus,
- private readonly array $loginMethods,
- private readonly bool $enhancedPreview,
private readonly ?Profiler $profiler = null,
) {}
@@ -25,14 +20,6 @@ public function __invoke(): Response
{
$this->profiler?->disable();
- return $this->render('admin/admin.html.twig', [
- 'config' => json_encode([
- 'rejseplanenApiKey' => $this->rejseplanenApiKey,
- 'touchButtonRegions' => $this->touchButtonRegions,
- 'showScreenStatus' => $this->showScreenStatus,
- 'loginMethods' => $this->loginMethods,
- 'enhancedPreview' => $this->enhancedPreview,
- ]),
- ]);
+ return $this->render('admin/admin.html.twig');
}
}
diff --git a/src/Controller/Client/ClientConfigController.php b/src/Controller/Client/ClientConfigController.php
new file mode 100644
index 00000000..aa0ffb88
--- /dev/null
+++ b/src/Controller/Client/ClientConfigController.php
@@ -0,0 +1,39 @@
+ $this->loginCheckTimeout,
+ 'refreshTokenTimeout' => $this->refreshTokenTimeout,
+ 'releaseTimestampIntervalTimeout' => $this->releaseTimestampIntervalTimeout,
+ 'pullStrategyInterval' => $this->pullStrategyInterval,
+ 'schedulingInterval' => $this->schedulingInterval,
+ 'colorScheme' => $this->colorScheme,
+ 'debug' => $this->debug,
+ 'logging' => $this->logging,
+ ]);
+ }
+}
diff --git a/src/Controller/Client/ClientController.php b/src/Controller/Client/ClientController.php
index f10d4df6..b834187a 100644
--- a/src/Controller/Client/ClientController.php
+++ b/src/Controller/Client/ClientController.php
@@ -13,14 +13,6 @@
class ClientController extends AbstractController
{
public function __construct(
- private readonly int $loginCheckTimeout,
- private readonly int $refreshTokenTimeout,
- private readonly int $releaseTimestampIntervalTimeout,
- private readonly int $schedulingInterval,
- private readonly int $pullStrategyInterval,
- private readonly array $colorScheme,
- private readonly bool $debug,
- private readonly array $logging,
private readonly ?Profiler $profiler = null,
) {}
@@ -28,17 +20,6 @@ public function __invoke(): Response
{
$this->profiler?->disable();
- return $this->render('client/client.html.twig', [
- 'config' => json_encode([
- 'loginCheckTimeout' => $this->loginCheckTimeout,
- 'refreshTokenTimeout' => $this->refreshTokenTimeout,
- 'releaseTimestampIntervalTimeout' => $this->releaseTimestampIntervalTimeout,
- 'pullStrategyInterval' => $this->pullStrategyInterval,
- 'schedulingInterval' => $this->schedulingInterval,
- 'colorScheme' => $this->colorScheme,
- 'debug' => $this->debug,
- 'logging' => $this->logging,
- ]),
- ]);
+ return $this->render('client/client.html.twig');
}
}
diff --git a/templates/admin/admin.html.twig b/templates/admin/admin.html.twig
index 680f9ab5..05d7f34f 100644
--- a/templates/admin/admin.html.twig
+++ b/templates/admin/admin.html.twig
@@ -11,10 +11,6 @@
{% block javascripts %}
{{ vite_entry_script_tags('admin', {dependency: 'react'}) }}
{% endblock %}
-
-
diff --git a/templates/client/client.html.twig b/templates/client/client.html.twig
index 204f105d..cf2bfd3f 100644
--- a/templates/client/client.html.twig
+++ b/templates/client/client.html.twig
@@ -11,10 +11,6 @@
{% block javascripts %}
{{ vite_entry_script_tags('client', {dependency: 'react'}) }}
{% endblock %}
-
-
From ad852cd005f299c5b8299ef8f5b36c7f90b9c0a4 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Thu, 7 Aug 2025 14:19:40 +0200
Subject: [PATCH 25/30] 4565: Fixed tests
---
assets/tests/admin/admin-campaign.spec.js | 14 ++++-
.../tests/admin/admin-content-string.spec.js | 5 ++
assets/tests/admin/admin-feed-sources.spec.js | 6 +-
assets/tests/admin/admin-helper.js | 12 ++--
assets/tests/admin/admin-login.spec.js | 62 ++++++++++---------
assets/tests/admin/admin-media.spec.js | 5 ++
assets/tests/admin/admin-playlist.spec.js | 5 ++
.../tests/admin/admin-screen-groups.spec.js | 5 ++
assets/tests/admin/admin-screens.spec.js | 13 ++++
assets/tests/admin/admin-shared-list.spec.js | 5 ++
assets/tests/admin/admin-slides.spec.js | 5 ++
assets/tests/admin/admin-theme.spec.js | 5 ++
assets/tests/admin/admin-top-bar.spec.js | 6 +-
13 files changed, 110 insertions(+), 38 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index f709cb14..854b0ed0 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,14 +1,24 @@
import { test, expect } from "@playwright/test";
-import { loginTest } from "./admin-helper.js";
+import { abortUnhandledRoutes, loginTest } from "./admin-helper.js";
import { emptyJson, slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await loginTest({ page });
await page.route("**/playlists*", async (route) => {
await route.fulfill({ json: emptyJson });
});
+ await page.route("**/screens*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+ await page.route("**/screen-groups*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
await page.locator(".sidebar-nav .nav-link").getByText("Kampagner").click();
await expect(page.locator("h1").getByText("Kampagner")).toBeVisible();
@@ -53,7 +63,7 @@ test.describe("Campaign pages work", () => {
).toHaveCount(6);
// Remove slide
- await page.locator(".remove-from-list").click({ force: false });
+ await page.locator(".remove-from-list").click();
// See that slides section is removed.
await expect(page.getByText("Afspilningsrækkefølge")).not.toBeVisible();
diff --git a/assets/tests/admin/admin-content-string.spec.js b/assets/tests/admin/admin-content-string.spec.js
index 15c122db..785b0a2a 100644
--- a/assets/tests/admin/admin-content-string.spec.js
+++ b/assets/tests/admin/admin-content-string.spec.js
@@ -1,7 +1,12 @@
import { test, expect } from "@playwright/test";
import contentString from "../../admin/components/util/helpers/content-string.jsx";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Content string", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test("It creates a string: 'test and test'", async ({ page }) => {
expect(contentString([{ name: "test" }, { name: "test" }], "and")).toBe(
"test and test",
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index bd315fe4..ef41a671 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -5,9 +5,13 @@ import {
feedSourcesJson2,
feedSourcesJson3,
} from "./data-fixtures.js";
-import { loginTest } from "./admin-helper.js";
+import { abortUnhandledRoutes, loginTest } from "./admin-helper.js";
test.describe("feed sources", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await loginTest({ page });
diff --git a/assets/tests/admin/admin-helper.js b/assets/tests/admin/admin-helper.js
index 400a4a50..04526597 100644
--- a/assets/tests/admin/admin-helper.js
+++ b/assets/tests/admin/admin-helper.js
@@ -6,13 +6,15 @@ import {
} from "./data-fixtures.js";
import { expect } from "@playwright/test";
-const loginTest = async ({ page }) => {
- await page.goto("/admin/slides/list");
-
+const abortUnhandledRoutes = async(page) => {
// Abort all routes that are not registered.
- await page.route("**/*", async (route) => {
+ await page.route("*", async (route) => {
await route.abort();
});
+};
+
+const loginTest = async ({ page }) => {
+ await page.goto("/admin/slides/list");
await page.route("**/token", async (route) => {
await route.fulfill({ json: tokenJson });
@@ -37,4 +39,4 @@ const loginTest = async ({ page }) => {
await expect(page.locator("h1").getByText("Slides")).toBeVisible();
};
-export { loginTest };
+export { loginTest, abortUnhandledRoutes };
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index 23b72634..750c3997 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -1,15 +1,20 @@
import { test, expect } from "@playwright/test";
import { accessConfigJson, adminConfigJson, emptyJson } from "./data-fixtures.js";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Login works", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.route("**/access-config.json", async (route) => {
await route.fulfill({ json: accessConfigJson });
});
- await page.route('**/config/admin', async (route) => {
+ await page.route("**/config/admin", async (route) => {
await route.fulfill({ json: adminConfigJson });
- })
+ });
});
test("Login one tenant works", async ({ page }) => {
@@ -111,33 +116,32 @@ test.describe("Login works", () => {
);
});
- test("Role editor should not be able to visit restricted route", async ({
- page
- }) => {
- await page.goto("/admin/playlist/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_EDITOR"]
+ test("Role editor should not be able to visit restricted route",
+ async ({ page }) => {
+ await page.goto("/admin/playlist/list");
+ await page.route("**/token", async (route) => {
+ const json = {
+ token: "1",
+ refresh_token: "2",
+ tenants: [
+ {
+ tenantKey: "ABC",
+ title: "ABC Tenant",
+ description: "Description",
+ roles: ["ROLE_EDITOR"]
+ }
+ ],
+ user: {
+ fullname: "John Doe",
+ email: "johndoe@example.com"
}
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com"
- }
- };
- await route.fulfill({ json });
+ };
+ await route.fulfill({ json });
+ });
+ await page.goto("/admin/shared/list");
+ await page.locator("#login").click();
+ await expect(page.locator("main").locator("div")).toHaveText(
+ "Du har ikke adgang til denne side"
+ );
});
- await page.goto("/admin/shared/list");
- await page.locator("#login").click();
- await expect(page.locator("main").locator("div")).toHaveText(
- "Du har ikke adgang til denne side"
- );
- });
});
diff --git a/assets/tests/admin/admin-media.spec.js b/assets/tests/admin/admin-media.spec.js
index 312a18b7..530d7bc0 100644
--- a/assets/tests/admin/admin-media.spec.js
+++ b/assets/tests/admin/admin-media.spec.js
@@ -1,6 +1,11 @@
import { test, expect } from "@playwright/test";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("media list tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.goto("/admin/media/list");
await page.route("**/media*", async (route) => {
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index add7f5c1..02b4668f 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -1,6 +1,11 @@
import { test, expect } from "@playwright/test";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Playlist create tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.goto("/admin/playlist/create");
await page.route("**/token", async (route) => {
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index fc5c047c..25403270 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -1,6 +1,11 @@
import { test, expect } from "@playwright/test";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Create group page works", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.goto("/admin/group/create");
await page.route("**/token", async (route) => {
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index e7821d98..c684705c 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -1,6 +1,12 @@
import { test, expect } from "@playwright/test";
+import { adminConfigJson } from "./data-fixtures.js";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Screen list tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test("Test list", async ({ page }) => {
await page.goto("/admin/screen/list");
await page.route("**/token", async (route) => {
@@ -22,6 +28,7 @@ test.describe("Screen list tests", () => {
};
await route.fulfill({ json });
});
+
await page.route("**/screens*", async (route) => {
const json = {
"@id": "/v2/screens",
@@ -73,6 +80,7 @@ test.describe("Screen list tests", () => {
};
await route.fulfill({ json });
});
+
await page.route("**/campaigns*", async (route) => {
await route.fulfill({
json: {
@@ -81,6 +89,7 @@ test.describe("Screen list tests", () => {
},
});
});
+
await page.route("**/screen-groups*", async (route) => {
await route.fulfill({
json: {
@@ -90,6 +99,10 @@ test.describe("Screen list tests", () => {
});
});
+ await page.route('**/config/admin', async (route) => {
+ await route.fulfill({ json: adminConfigJson });
+ })
+
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("johndoe@example.com");
await page.getByLabel("Kodeord").fill("password");
diff --git a/assets/tests/admin/admin-shared-list.spec.js b/assets/tests/admin/admin-shared-list.spec.js
index 94adf5bf..24e6ee18 100644
--- a/assets/tests/admin/admin-shared-list.spec.js
+++ b/assets/tests/admin/admin-shared-list.spec.js
@@ -1,6 +1,11 @@
import { test, expect } from "@playwright/test";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Shared list tests", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.goto("/admin/shared/list");
await page.route("**/token", async (route) => {
diff --git a/assets/tests/admin/admin-slides.spec.js b/assets/tests/admin/admin-slides.spec.js
index c44060e2..ce8ffef7 100644
--- a/assets/tests/admin/admin-slides.spec.js
+++ b/assets/tests/admin/admin-slides.spec.js
@@ -1,6 +1,11 @@
import { test, expect } from "@playwright/test";
+import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Create slide page works", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.goto("/admin/slide/create");
await page.route("**/token", async (route) => {
diff --git a/assets/tests/admin/admin-theme.spec.js b/assets/tests/admin/admin-theme.spec.js
index 640d5fc2..4ccadfbe 100644
--- a/assets/tests/admin/admin-theme.spec.js
+++ b/assets/tests/admin/admin-theme.spec.js
@@ -1,4 +1,5 @@
import { test, expect } from "@playwright/test";
+import { abortUnhandledRoutes } from "./admin-helper.js";
const themesJson = {
"@context": "/contexts/Theme",
@@ -274,6 +275,10 @@ const themesJson = {
};
test.describe("Theme pages work", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await page.goto("/admin/themes/list");
await page.route("**/themes*", async (route) => {
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index 939712c0..44828750 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -1,8 +1,12 @@
import { test, expect } from "@playwright/test";
-import { loginTest } from "./admin-helper.js";
+import { abortUnhandledRoutes, loginTest } from "./admin-helper.js";
import { emptyJson } from "./data-fixtures.js";
test.describe("Nav items loads", () => {
+ test.beforeEach(async ({ page }) => {
+ await abortUnhandledRoutes(page);
+ });
+
test.beforeEach(async ({ page }) => {
await loginTest({ page });
});
From 9cf6d76d6fce19f25d7663de0bd1c7b05a09404f Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Fri, 8 Aug 2025 08:41:25 +0200
Subject: [PATCH 26/30] 4565: Worked on test refactor
---
assets/admin/admin-config-loader.js | 4 +-
assets/client/client-config-loader.js | 14 +-
assets/client/service/release-service.js | 2 +-
assets/tests/admin/admin-campaign.spec.js | 20 +-
.../tests/admin/admin-content-string.spec.js | 5 -
assets/tests/admin/admin-feed-sources.spec.js | 39 ++-
assets/tests/admin/admin-helper.js | 42 ----
assets/tests/admin/admin-login.spec.js | 137 +++--------
assets/tests/admin/admin-media.spec.js | 8 +-
assets/tests/admin/admin-playlist.spec.js | 4 +-
.../tests/admin/admin-screen-groups.spec.js | 4 +-
assets/tests/admin/admin-screens.spec.js | 8 +-
assets/tests/admin/admin-shared-list.spec.js | 4 +-
assets/tests/admin/admin-slides.spec.js | 4 +-
assets/tests/admin/admin-theme.spec.js | 4 +-
assets/tests/admin/admin-top-bar.spec.js | 4 +-
assets/tests/admin/data-fixtures.js | 228 +++++++++++-------
assets/tests/admin/test-helper.js | 65 +++++
18 files changed, 283 insertions(+), 313 deletions(-)
delete mode 100644 assets/tests/admin/admin-helper.js
create mode 100644 assets/tests/admin/test-helper.js
diff --git a/assets/admin/admin-config-loader.js b/assets/admin/admin-config-loader.js
index c0158194..0624ff13 100644
--- a/assets/admin/admin-config-loader.js
+++ b/assets/admin/admin-config-loader.js
@@ -22,9 +22,7 @@ const AdminConfigLoader = {
resolve(configData);
} else {
// eslint-disable-next-line no-console
- console.error(
- "Could not load config. Will use default config."
- );
+ console.error("Could not load config. Will use default config.");
// Default config.
resolve({
diff --git a/assets/client/client-config-loader.js b/assets/client/client-config-loader.js
index a791dafe..b02c0e18 100644
--- a/assets/client/client-config-loader.js
+++ b/assets/client/client-config-loader.js
@@ -1,5 +1,5 @@
// Only fetch new config if more than 15 minutes have passed.
-import appStorage from './util/app-storage';
+import appStorage from "./util/app-storage";
const configFetchIntervalDefault = 15 * 60 * 1000;
@@ -22,7 +22,7 @@ const ClientConfigLoader = {
if (
latestFetchTimestamp +
- (configData?.configFetchInterval ?? configFetchIntervalDefault) >=
+ (configData?.configFetchInterval ?? configFetchIntervalDefault) >=
nowTimestamp
) {
resolve(configData);
@@ -43,15 +43,13 @@ const ClientConfigLoader = {
resolve(configData);
} else {
// eslint-disable-next-line no-console
- console.error(
- 'Could not load config. Will use default config.'
- );
+ console.error("Could not load config. Will use default config.");
// Default config.
resolve({
- apiEndpoint: '/api',
+ apiEndpoint: "/api",
dataStrategy: {
- type: 'pull',
+ type: "pull",
config: {
interval: 30000,
},
@@ -61,7 +59,7 @@ const ClientConfigLoader = {
refreshTokenTimeout: 15000,
releaseTimestampIntervalTimeout: 600000,
colorScheme: {
- type: 'library',
+ type: "library",
lat: 56.0,
lng: 10.0,
},
diff --git a/assets/client/service/release-service.js b/assets/client/service/release-service.js
index c14c488f..731a7d14 100644
--- a/assets/client/service/release-service.js
+++ b/assets/client/service/release-service.js
@@ -74,7 +74,7 @@ class ReleaseService {
this.releaseCheckInterval = setInterval(
this.checkForNewRelease,
config.releaseTimestampIntervalTimeout ??
- defaults.releaseTimestampIntervalTimeoutDefault,
+ defaults.releaseTimestampIntervalTimeoutDefault,
);
});
};
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 854b0ed0..7fc6bb75 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,24 +1,16 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes, loginTest } from "./admin-helper.js";
-import { emptyJson, slidesJson1 } from "./data-fixtures.js";
+import { awaitDataRoute, awaitEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
+import { slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
await loginTest({ page });
- await page.route("**/playlists*", async (route) => {
- await route.fulfill({ json: emptyJson });
- });
- await page.route("**/screens*", async (route) => {
- await route.fulfill({ json: emptyJson });
- });
- await page.route("**/screen-groups*", async (route) => {
- await route.fulfill({ json: emptyJson });
- });
+ await awaitEmptyRoutes(page, ["**/playlists*", "**/screens*", "**/screen-groups*"]);
await page.locator(".sidebar-nav .nav-link").getByText("Kampagner").click();
await expect(page.locator("h1").getByText("Kampagner")).toBeVisible();
@@ -33,9 +25,7 @@ test.describe("Campaign pages work", () => {
test("It removes slide", async ({ page }) => {
// Intercept slides in dropdown
- await page.route("**/slides*", async (route) => {
- await route.fulfill({ json: slidesJson1 });
- });
+ await awaitDataRoute(page, "**/slides*", slidesJson1);
// Pick slide
await page
diff --git a/assets/tests/admin/admin-content-string.spec.js b/assets/tests/admin/admin-content-string.spec.js
index 785b0a2a..15c122db 100644
--- a/assets/tests/admin/admin-content-string.spec.js
+++ b/assets/tests/admin/admin-content-string.spec.js
@@ -1,12 +1,7 @@
import { test, expect } from "@playwright/test";
import contentString from "../../admin/components/util/helpers/content-string.jsx";
-import { abortUnhandledRoutes } from "./admin-helper.js";
test.describe("Content string", () => {
- test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
- });
-
test("It creates a string: 'test and test'", async ({ page }) => {
expect(contentString([{ name: "test" }, { name: "test" }], "and")).toBe(
"test and test",
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index ef41a671..3eaa08ae 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -3,36 +3,39 @@ import {
errorJson,
feedSourcesJson,
feedSourcesJson2,
- feedSourcesJson3,
+ feedSourceSingleJson
} from "./data-fixtures.js";
-import { abortUnhandledRoutes, loginTest } from "./admin-helper.js";
+import { awaitDataRoute, awaitEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
await loginTest({ page });
- await page.route("**/feed-sources*", async (route) => {
- await route.fulfill({ json: feedSourcesJson });
- });
+ await awaitDataRoute(page, "**/feed-sources*", feedSourcesJson);
+
+ await page
+ .locator(".sidebar-nav .nav-link")
+ .getByText("Datakilder")
+ .click();
+
+ await awaitEmptyRoutes(page, ["**/slides*"]);
- await page.locator(".sidebar-nav .nav-link").getByText("Datakilder").click();
await expect(page.locator("h1").getByText("Datakilder")).toBeVisible();
});
test("It loads create datakilde page", async ({ page }) => {
- page.getByText("Opret ny datakilde").click();
+ await page.getByText("Opret ny datakilde").click();
await expect(page.locator("#save")).toBeVisible();
});
test("It display error toast on save error", async ({ page }) => {
- await page.route("**/feed-sources", async (route) => {
- await route.fulfill({ status: 500, json: errorJson });
- });
- page.getByText("Opret ny datakilde").click();
+ await awaitDataRoute(page, "**/feed-sources*", errorJson, 500);
+
+ await page.getByText("Opret ny datakilde").click();
// Displays error toast and stays on page
await expect(
@@ -53,7 +56,8 @@ test.describe("feed sources", () => {
});
test("Cancel create datakilde", async ({ page }) => {
- page.getByText("Opret ny datakilde").click();
+ await page.getByText("Opret ny datakilde").click();
+
await expect(page.locator("#cancel")).toBeVisible();
await page.locator("#cancel").click();
await expect(page.locator("#cancel")).not.toBeVisible();
@@ -67,13 +71,8 @@ test.describe("feed sources", () => {
test("It goes to edit", async ({ page }) => {
await expect(page.locator("#feed-sourceTitle")).not.toBeVisible();
- await page.route("**/feed-sources*", async (route) => {
- await route.fulfill({ json: feedSourcesJson2 });
- });
-
- await page.route("**/feed-sources/*", async (route) => {
- await route.fulfill({ json: feedSourcesJson3 });
- });
+ await awaitDataRoute(page, "**/feed-sources*", feedSourcesJson2);
+ await awaitDataRoute(page, "**/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ", feedSourceSingleJson);
await page.locator("tbody").locator("tr td a").first().click();
await expect(page.locator("#feed-sourceTitle")).toBeVisible();
diff --git a/assets/tests/admin/admin-helper.js b/assets/tests/admin/admin-helper.js
deleted file mode 100644
index 04526597..00000000
--- a/assets/tests/admin/admin-helper.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
- accessConfigJson, adminConfigJson,
- emptyJson,
- feedSourcesJson,
- tokenJson
-} from "./data-fixtures.js";
-import { expect } from "@playwright/test";
-
-const abortUnhandledRoutes = async(page) => {
- // Abort all routes that are not registered.
- await page.route("*", async (route) => {
- await route.abort();
- });
-};
-
-const loginTest = async ({ page }) => {
- await page.goto("/admin/slides/list");
-
- await page.route("**/token", async (route) => {
- await route.fulfill({ json: tokenJson });
- });
-
- await page.route('**/access-config.json*', async (route) => {
- await route.fulfill({ json: accessConfigJson});
- })
-
- await page.route('**/config/admin', async (route) => {
- await route.fulfill({ json: adminConfigJson });
- })
-
- await page.route("**/slides*", async (route) => {
- await route.fulfill({ json: emptyJson });
- });
-
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("admin@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.locator("h1").getByText("Slides")).toBeVisible();
-};
-
-export { loginTest, abortUnhandledRoutes };
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index 750c3997..3e4951ed 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -1,12 +1,12 @@
import { test, expect } from "@playwright/test";
-import { accessConfigJson, adminConfigJson, emptyJson } from "./data-fixtures.js";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import {
+ accessConfigJson,
+ adminConfigJson,
+ emptyJson, tokenAdminJson, tokenEditorJson, tokenTenantsJson
+} from "./data-fixtures.js";
+import { awaitDataRoute, awaitEmptyRoutes, beforeEachTest } from "./test-helper.js";
test.describe("Login works", () => {
- test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
- });
-
test.beforeEach(async ({ page }) => {
await page.route("**/access-config.json", async (route) => {
await route.fulfill({ json: accessConfigJson });
@@ -20,128 +20,47 @@ test.describe("Login works", () => {
test("Login one tenant works", async ({ page }) => {
await page.goto("/admin/playlists/list");
- await page.route("**/playlists*", async (route) => {
- await route.fulfill({ json: emptyJson });
- });
+ await awaitEmptyRoutes(page, ['"**/playlists*"']);
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"]
- }
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com"
- }
- };
- await route.fulfill({ json });
- });
+ await awaitDataRoute(page, "**/token", tokenAdminJson);
await page.locator("#login").click();
await expect(page.locator(".name")).toHaveText("John Doe");
});
test("Login three tenant works", async ({ page }) => {
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Nulla quam ipsam voluptatem cupiditate.",
- roles: ["ROLE_ADMIN"]
- },
- {
- tenantKey: "DEF",
- title: "DEF Tenant",
- description: "Inventore sed libero et.",
- roles: ["ROLE_ADMIN"]
- },
- {
- tenantKey: "XYZ",
- title: "XYC Tenant",
- description: "Itaque quibusdam tempora velit porro ut velit.",
- roles: ["ROLE_ADMIN"]
- }
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com"
- }
- };
- await route.fulfill({ json });
- });
await page.goto("/admin/group/list");
+
+ await awaitDataRoute(page, "**/token", tokenTenantsJson);
+
await page.locator("#login").click();
+
// Expect dropdown with tenants
await expect(page.locator(".dropdown-container")).toBeVisible();
});
test("Login with tenant that has role editor", async ({ page }) => {
- await page.goto("/admin/playlist/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_EDITOR"]
- }
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com"
- }
- };
- await route.fulfill({ json });
- });
+ await page.goto("/admin/playlists/list");
- await page.goto("/admin/group/list");
+ await awaitDataRoute(page, "**/token", tokenEditorJson);
await page.locator("#login").click();
+
await expect(page.locator(".name")).toHaveText("John Doe");
await expect(page.locator(".sidebar-nav").locator(".nav-item")).toHaveCount(
- 4
+ 4,
);
});
- test("Role editor should not be able to visit restricted route",
- async ({ page }) => {
- await page.goto("/admin/playlist/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_EDITOR"]
- }
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com"
- }
- };
- await route.fulfill({ json });
- });
- await page.goto("/admin/shared/list");
- await page.locator("#login").click();
- await expect(page.locator("main").locator("div")).toHaveText(
- "Du har ikke adgang til denne side"
- );
- });
+ test("Role editor should not be able to visit restricted route", async ({
+ page,
+ }) => {
+ await page.goto("/admin/shared/list");
+
+ await awaitDataRoute(page, "**/token", tokenEditorJson);
+ await page.locator("#login").click();
+
+ await expect(page.locator("main").locator("div")).toHaveText(
+ "Du har ikke adgang til denne side",
+ );
+ });
});
diff --git a/assets/tests/admin/admin-media.spec.js b/assets/tests/admin/admin-media.spec.js
index 530d7bc0..67e19aa3 100644
--- a/assets/tests/admin/admin-media.spec.js
+++ b/assets/tests/admin/admin-media.spec.js
@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
test.describe("media list tests", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
@@ -28,7 +28,7 @@ test.describe("media list tests", () => {
media: [],
assets: {
type: "image/jpeg",
- uri: "http://api-display-admin-client.local.itkdev.dk/media/test_3.jpg",
+ uri: "https://display.local.itkdev.dk/fixtures/template/images/mountain1.jpeg",
dimensions: {
height: 3456,
width: 5184,
@@ -51,7 +51,7 @@ test.describe("media list tests", () => {
media: [],
assets: {
type: "image/jpeg",
- uri: "http://api-display-admin-client.local.itkdev.dk/media/test_2.jpg",
+ uri: "https://display.local.itkdev.dk/fixtures/template/images/mountain2.jpeg",
dimensions: {
height: 2592,
width: 3888,
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index 02b4668f..06496233 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
test.describe("Playlist create tests", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index 25403270..f2162453 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
test.describe("Create group page works", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index c684705c..1e002e14 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -1,10 +1,10 @@
import { test, expect } from "@playwright/test";
import { adminConfigJson } from "./data-fixtures.js";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
test.describe("Screen list tests", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test("Test list", async ({ page }) => {
@@ -99,9 +99,9 @@ test.describe("Screen list tests", () => {
});
});
- await page.route('**/config/admin', async (route) => {
+ await page.route("**/config/admin", async (route) => {
await route.fulfill({ json: adminConfigJson });
- })
+ });
await expect(page).toHaveTitle(/OS2Display Admin/);
await page.getByLabel("Email").fill("johndoe@example.com");
diff --git a/assets/tests/admin/admin-shared-list.spec.js b/assets/tests/admin/admin-shared-list.spec.js
index 24e6ee18..58bf87f0 100644
--- a/assets/tests/admin/admin-shared-list.spec.js
+++ b/assets/tests/admin/admin-shared-list.spec.js
@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
test.describe("Shared list tests", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-slides.spec.js b/assets/tests/admin/admin-slides.spec.js
index ce8ffef7..1646fab0 100644
--- a/assets/tests/admin/admin-slides.spec.js
+++ b/assets/tests/admin/admin-slides.spec.js
@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
test.describe("Create slide page works", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-theme.spec.js b/assets/tests/admin/admin-theme.spec.js
index 4ccadfbe..f999b391 100644
--- a/assets/tests/admin/admin-theme.spec.js
+++ b/assets/tests/admin/admin-theme.spec.js
@@ -1,5 +1,5 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes } from "./admin-helper.js";
+import { beforeEachTest } from "./test-helper.js";
const themesJson = {
"@context": "/contexts/Theme",
@@ -276,7 +276,7 @@ const themesJson = {
test.describe("Theme pages work", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index 44828750..d5857698 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -1,10 +1,10 @@
import { test, expect } from "@playwright/test";
-import { abortUnhandledRoutes, loginTest } from "./admin-helper.js";
+import { beforeEachTest, loginTest } from "./test-helper.js";
import { emptyJson } from "./data-fixtures.js";
test.describe("Nav items loads", () => {
test.beforeEach(async ({ page }) => {
- await abortUnhandledRoutes(page);
+ await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index 56f3d735..d8a6d376 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -1,4 +1,4 @@
-const tokenJson = {
+const tokenAdminJson = {
token: "1",
refresh_token: "2",
tenants: [
@@ -6,13 +6,59 @@ const tokenJson = {
tenantKey: "ABC",
title: "ABC Tenant",
description: "Description",
- roles: ["ROLE_ADMIN"]
- }
+ roles: ["ROLE_ADMIN"],
+ },
],
user: {
fullname: "John Doe",
- email: "johndoe@example.com"
- }
+ email: "johndoe@example.com",
+ },
+};
+
+const tokenTenantsJson = {
+ token: "1",
+ refresh_token: "2",
+ tenants: [
+ {
+ tenantKey: "ABC",
+ title: "ABC Tenant",
+ description: "Nulla quam ipsam voluptatem cupiditate.",
+ roles: ["ROLE_ADMIN"],
+ },
+ {
+ tenantKey: "DEF",
+ title: "DEF Tenant",
+ description: "Inventore sed libero et.",
+ roles: ["ROLE_ADMIN"],
+ },
+ {
+ tenantKey: "XYZ",
+ title: "XYC Tenant",
+ description: "Itaque quibusdam tempora velit porro ut velit.",
+ roles: ["ROLE_ADMIN"],
+ },
+ ],
+ user: {
+ fullname: "John Doe",
+ email: "johndoe@example.com",
+ },
+};
+
+const tokenEditorJson = {
+ token: "1",
+ refresh_token: "2",
+ tenants: [
+ {
+ tenantKey: "ABC",
+ title: "ABC Tenant",
+ description: "Description",
+ roles: ["ROLE_EDITOR"],
+ },
+ ],
+ user: {
+ fullname: "John Doe",
+ email: "johndoe@example.com",
+ },
};
const feedSourcesJson = {
@@ -36,7 +82,7 @@ const feedSourcesJson = {
createdBy: "admin@example.com",
id: "01JBBP48CS9CV80XRWRP8CAETJ",
created: "2024-10-29T09:26:25.000Z",
- modified: "2024-10-29T09:26:25.000Z"
+ modified: "2024-10-29T09:26:25.000Z",
},
{
"@id": "/v2/feed-sources/01JB9MSQEH75HC3GG75XCVP2WH",
@@ -48,7 +94,7 @@ const feedSourcesJson = {
secrets: [],
feeds: [
"/v2/feeds/01JB9R7EPN9NPW117C22NY31KH",
- "/v2/feeds/01JBBQMF72W2V36TWF6VXFA5Z7"
+ "/v2/feeds/01JBBQMF72W2V36TWF6VXFA5Z7",
],
admin: [
{
@@ -58,7 +104,7 @@ const feedSourcesJson = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6"
+ formGroupClasses: "col-md-6",
},
{
key: "rss-number-of-entries",
@@ -68,7 +114,7 @@ const feedSourcesJson = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3"
+ formGroupClasses: "col-md-6 mb-3",
},
{
key: "rss-entry-duration",
@@ -77,15 +123,15 @@ const feedSourcesJson = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3"
- }
+ formGroupClasses: "col-md-6 mb-3",
+ },
],
supportedFeedOutputType: "rss",
modifiedBy: "admin@example.com",
createdBy: "admin@example.com",
id: "01JB9MSQEH75HC3GG75XCVP2WH",
created: "2024-10-28T14:24:43.000Z",
- modified: "2024-10-28T15:23:28.000Z"
+ modified: "2024-10-28T15:23:28.000Z",
},
{
"@id": "/v2/feed-sources/01JB1DH8G4CXKGX5JRTYDHDPSP",
@@ -102,7 +148,7 @@ const feedSourcesJson = {
createdBy: "",
id: "01JB1DH8G4CXKGX5JRTYDHDPSP",
created: "2024-10-25T10:43:50.000Z",
- modified: "2024-10-25T10:43:50.000Z"
+ modified: "2024-10-25T10:43:50.000Z",
},
{
"@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
@@ -122,7 +168,7 @@ const feedSourcesJson = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6"
+ formGroupClasses: "col-md-6",
},
{
key: "rss-number-of-entries",
@@ -132,7 +178,7 @@ const feedSourcesJson = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3"
+ formGroupClasses: "col-md-6 mb-3",
},
{
key: "rss-entry-duration",
@@ -141,15 +187,15 @@ const feedSourcesJson = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3"
- }
+ formGroupClasses: "col-md-6 mb-3",
+ },
],
supportedFeedOutputType: "instagram",
modifiedBy: "",
createdBy: "",
id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z"
+ modified: "2024-09-17T09:33:12.000Z",
},
{
"@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
@@ -169,7 +215,7 @@ const feedSourcesJson = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6"
+ formGroupClasses: "col-md-6",
},
{
key: "rss-number-of-entries",
@@ -179,7 +225,7 @@ const feedSourcesJson = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3"
+ formGroupClasses: "col-md-6 mb-3",
},
{
key: "rss-entry-duration",
@@ -188,17 +234,17 @@ const feedSourcesJson = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3"
- }
+ formGroupClasses: "col-md-6 mb-3",
+ },
],
supportedFeedOutputType: "rss",
modifiedBy: "",
createdBy: "",
id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
created: "2024-06-29T05:47:07.000Z",
- modified: "2024-10-21T18:01:25.000Z"
- }
- ]
+ modified: "2024-10-21T18:01:25.000Z",
+ },
+ ],
};
const feedSourcesJson2 = {
@@ -225,7 +271,7 @@ const feedSourcesJson2 = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6"
+ formGroupClasses: "col-md-6",
},
{
key: "rss-number-of-entries",
@@ -235,7 +281,7 @@ const feedSourcesJson2 = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3"
+ formGroupClasses: "col-md-6 mb-3",
},
{
key: "rss-entry-duration",
@@ -244,15 +290,15 @@ const feedSourcesJson2 = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3"
- }
+ formGroupClasses: "col-md-6 mb-3",
+ },
],
supportedFeedOutputType: "instagram",
modifiedBy: "",
createdBy: "",
id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z"
+ modified: "2024-09-17T09:33:12.000Z",
},
{
"@id": "/v2/feed-sources/01J1H8GVVR1CVJ1SQK0JXN1X4Q",
@@ -272,7 +318,7 @@ const feedSourcesJson2 = {
type: "url",
label: "Kilde",
helpText: "Her kan du skrive rss kilden",
- formGroupClasses: "col-md-6"
+ formGroupClasses: "col-md-6",
},
{
key: "rss-number-of-entries",
@@ -282,7 +328,7 @@ const feedSourcesJson2 = {
label: "Antal indgange",
helpText:
"Her kan du skrive, hvor mange indgange, der maksimalt skal vises.",
- formGroupClasses: "col-md-6 mb-3"
+ formGroupClasses: "col-md-6 mb-3",
},
{
key: "rss-entry-duration",
@@ -291,21 +337,21 @@ const feedSourcesJson2 = {
type: "number",
label: "Varighed pr. indgang (i sekunder)",
helpText: "Her skal du skrive varigheden pr. indgang.",
- formGroupClasses: "col-md-6 mb-3"
- }
+ formGroupClasses: "col-md-6 mb-3",
+ },
],
supportedFeedOutputType: "rss",
modifiedBy: "",
createdBy: "",
id: "01J1H8GVVR1CVJ1SQK0JXN1X4Q",
created: "2024-06-29T05:47:07.000Z",
- modified: "2024-10-21T18:01:25.000Z"
- }
- ]
+ modified: "2024-10-21T18:01:25.000Z",
+ },
+ ],
};
-const feedSourcesJson3 = {
- "@id": "/v2/feed-sources/01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
+const feedSourceSingleJson = {
+ "@id": "/v2/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ",
"@type": "FeedSource",
title: "feed_source_abc_notified",
description:
@@ -319,14 +365,14 @@ const feedSourcesJson3 = {
createdBy: "",
id: "01J711Y2Q01VBJ1Y7A1HZQ0ZN6",
created: "2024-09-05T12:18:20.000Z",
- modified: "2024-09-17T09:33:12.000Z"
+ modified: "2024-09-17T09:33:12.000Z",
};
const errorJson = {
"@context": "/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
- "hydra:description": "An error occurred"
+ "hydra:description": "An error occurred",
};
const emptyJson = {
@@ -335,8 +381,8 @@ const emptyJson = {
"hydra:totalItems": 0,
"hydra:view": {
"@id": "/v2/slides?itemsPerPage=0\u0026title=",
- "@type": "hydra:PartialCollectionView"
- }
+ "@type": "hydra:PartialCollectionView",
+ },
};
const adminConfigJson = {
@@ -348,7 +394,7 @@ const adminConfigJson = {
type: "username-password",
enabled: true,
provider: "username-password",
- label: ""
+ label: "",
},
],
enhancedPreview: true,
@@ -361,28 +407,28 @@ const clientConfigJson = {
pullStrategyInterval: 1000 * 60 * 60,
schedulingInterval: 1000 * 60 * 60,
debug: false,
- logging: false
+ logging: false,
};
const accessConfigJson = {
campaign: {
- roles: ["ROLE_ADMIN"]
+ roles: ["ROLE_ADMIN"],
},
screen: {
- roles: ["ROLE_ADMIN"]
+ roles: ["ROLE_ADMIN"],
},
settings: {
- roles: ["ROLE_ADMIN"]
+ roles: ["ROLE_ADMIN"],
},
groups: {
- roles: ["ROLE_ADMIN"]
+ roles: ["ROLE_ADMIN"],
},
shared: {
- roles: ["ROLE_ADMIN"]
+ roles: ["ROLE_ADMIN"],
},
users: {
- roles: ["ROLE_ADMIN", "ROLE_EXTERNAL_USER_ADMIN"]
- }
+ roles: ["ROLE_ADMIN", "ROLE_EXTERNAL_USER_ADMIN"],
+ },
};
const slidesJson1 = {
@@ -400,21 +446,21 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: []
+ options: [],
},
theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0Y8",
onPlaylists: [],
duration: 107879,
published: {
from: null,
- to: null
+ to: null,
},
media: [
"/v2/media/00042YZWK214MP01NA1GF517Q2",
"/v2/media/00TET3FF6K1Q011N5S12621E4H",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK"
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK",
],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -428,20 +474,20 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: []
+ options: [],
},
theme: "",
onPlaylists: [],
duration: 80335,
published: {
from: "2021-03-19T22:20:54.000Z",
- to: "2021-12-28T06:13:08.000Z"
+ to: "2021-12-28T06:13:08.000Z",
},
media: [
"/v2/media/009H64MSPN1HEH0DTV2DEV085B",
- "/v2/media/00SC0JP6PV2QYS06R70SS31K68"
+ "/v2/media/00SC0JP6PV2QYS06R70SS31K68",
],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -455,17 +501,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
- options: []
+ options: [],
},
theme: "",
onPlaylists: [],
duration: 21254,
published: {
from: null,
- to: null
+ to: null,
},
media: ["/v2/media/00YMKGY3FM106Q0SRV077G0KEX"],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -479,17 +525,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000BGWFMBS15N807E60HP91JCX",
- options: []
+ options: [],
},
theme: "",
onPlaylists: [],
duration: 60870,
published: {
from: "2021-02-26T20:12:10.000Z",
- to: "2021-06-08T05:44:41.000Z"
+ to: "2021-06-08T05:44:41.000Z",
},
media: ["/v2/media/00BBYAKF190NMJ0FH118V91VV7"],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -503,17 +549,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: []
+ options: [],
},
theme: "",
onPlaylists: [],
duration: 75535,
published: {
from: null,
- to: "1996-02-16T00:54:17.000Z"
+ to: "1996-02-16T00:54:17.000Z",
},
media: ["/v2/media/0027FWF7Y014RG0KW9053S1AX6"],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -527,17 +573,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: []
+ options: [],
},
theme: "",
onPlaylists: [],
duration: 92829,
published: {
from: "2021-12-29T03:25:23.000Z",
- to: null
+ to: null,
},
media: ["/v2/media/001AX5W2S909NW0K5A0NVE0NS6"],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -551,21 +597,21 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: []
+ options: [],
},
theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YN",
onPlaylists: [],
duration: 41589,
published: {
from: null,
- to: "1989-10-31T03:15:44.000Z"
+ to: "1989-10-31T03:15:44.000Z",
},
media: [
"/v2/media/00CX9N9EJE10WT1PVM10G51N13",
"/v2/media/016HWRGVWJ170F1AF2099T13JW",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK"
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK",
],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -579,17 +625,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: []
+ options: [],
},
theme: "",
onPlaylists: [],
duration: 106091,
published: {
from: "2022-01-11T14:56:13.000Z",
- to: "2022-02-05T09:10:20.000Z"
+ to: "2022-02-05T09:10:20.000Z",
},
media: ["/v2/media/00F1M5J6BY1GS517RP1T1B1306"],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -603,17 +649,17 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/016MHSNKCH1PQW1VY615JC19Y3",
- options: []
+ options: [],
},
theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
onPlaylists: [],
duration: 79809,
published: {
from: "2021-08-10T06:26:30.000Z",
- to: "2021-08-12T15:26:21.000Z"
+ to: "2021-08-12T15:26:21.000Z",
},
media: ["/v2/media/011ZBTXPF8123R1BA31CQR18HA"],
- content: []
+ content: [],
},
{
"@type": "Slide",
@@ -627,31 +673,33 @@ const slidesJson1 = {
createdBy: "",
templateInfo: {
"@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: []
+ options: [],
},
theme: "/v2/themes/01FPFH3WXAX8JMJTQHBV2BYEDM",
onPlaylists: [],
duration: 37983,
published: {
from: "2022-01-24T16:30:24.000Z",
- to: "2022-02-05T09:19:31.000Z"
+ to: "2022-02-05T09:19:31.000Z",
},
media: [
"/v2/media/0010X8D6JJ03G50T1J1FCW1XH6",
"/v2/media/00F1M5J6BY1GS517RP1T1B1306",
- "/v2/media/00KXYB7Z291JXC1SY30G161HQD"
+ "/v2/media/00KXYB7Z291JXC1SY30G161HQD",
],
- content: []
- }
+ content: [],
+ },
],
- "hydra:totalItems": 60
+ "hydra:totalItems": 60,
};
export {
- tokenJson,
+ tokenAdminJson,
+ tokenTenantsJson,
+ tokenEditorJson,
feedSourcesJson,
feedSourcesJson2,
- feedSourcesJson3,
+ feedSourceSingleJson,
errorJson,
emptyJson,
slidesJson1,
diff --git a/assets/tests/admin/test-helper.js b/assets/tests/admin/test-helper.js
new file mode 100644
index 00000000..2cfc370a
--- /dev/null
+++ b/assets/tests/admin/test-helper.js
@@ -0,0 +1,65 @@
+import {
+ accessConfigJson,
+ adminConfigJson,
+ emptyJson,
+ feedSourcesJson,
+ tokenAdminJson,
+} from "./data-fixtures.js";
+import { expect } from "@playwright/test";
+
+const beforeEachTest = async (page) => {
+ // Abort all routes that are not registered.
+ await page.route("*", async (route) => {
+ await route.abort();
+ });
+
+ // Handle calls to cccess-config.
+ await page.route("**/access-config.json*", async (route) => {
+ await route.fulfill({ json: accessConfigJson });
+ });
+
+ // Handle all calls to config.
+ await page.route("**/config/admin", async (route) => {
+ await route.fulfill({ json: adminConfigJson });
+ });
+};
+
+const awaitEmptyRoutes = async (page, routePatterns) => {
+ for (const routePattern of routePatterns) {
+ await page.route(routePattern, async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+ }
+}
+
+const awaitDataRoute = async (page, routePattern, data, status) => {
+ const result = { json: data};
+
+ if (status) {
+ result['status'] = status;
+ }
+
+ await page.route(routePattern, async (route) => {
+ await route.fulfill(result);
+ });
+}
+
+const loginTest = async ({ page }) => {
+ await page.goto("/admin/slides/list");
+
+ await page.route("**/token", async (route) => {
+ await route.fulfill({ json: tokenAdminJson });
+ });
+
+ await page.route("**/slides*", async (route) => {
+ await route.fulfill({ json: emptyJson });
+ });
+
+ await expect(page).toHaveTitle(/OS2Display Admin/);
+ await page.getByLabel("Email").fill("admin@example.com");
+ await page.getByLabel("Kodeord").fill("password");
+ await page.locator("#login").click();
+ await expect(page.locator("h1").getByText("Slides")).toBeVisible();
+};
+
+export { loginTest, beforeEachTest, awaitEmptyRoutes, awaitDataRoute };
From 8bdc7368fa3a95ad39c32ac4fcc307454543de11 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Fri, 8 Aug 2025 09:50:32 +0200
Subject: [PATCH 27/30] 4565: Fixed playlist and media tests
---
assets/tests/admin/admin-campaign.spec.js | 6 +-
assets/tests/admin/admin-feed-sources.spec.js | 12 +-
assets/tests/admin/admin-login.spec.js | 12 +-
assets/tests/admin/admin-media.spec.js | 89 +-------
assets/tests/admin/admin-playlist.spec.js | 214 +++---------------
assets/tests/admin/data-fixtures.js | 141 ++++++++++++
assets/tests/admin/test-helper.js | 6 +-
7 files changed, 198 insertions(+), 282 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 7fc6bb75..3f77d1db 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,5 +1,5 @@
import { test, expect } from "@playwright/test";
-import { awaitDataRoute, awaitEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
+import { fulfillDataRoute, fulfillEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
import { slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
@@ -10,7 +10,7 @@ test.describe("Campaign pages work", () => {
test.beforeEach(async ({ page }) => {
await loginTest({ page });
- await awaitEmptyRoutes(page, ["**/playlists*", "**/screens*", "**/screen-groups*"]);
+ await fulfillEmptyRoutes(page, ["**/playlists*", "**/screens*", "**/screen-groups*"]);
await page.locator(".sidebar-nav .nav-link").getByText("Kampagner").click();
await expect(page.locator("h1").getByText("Kampagner")).toBeVisible();
@@ -25,7 +25,7 @@ test.describe("Campaign pages work", () => {
test("It removes slide", async ({ page }) => {
// Intercept slides in dropdown
- await awaitDataRoute(page, "**/slides*", slidesJson1);
+ await fulfillDataRoute(page, "**/slides*", slidesJson1);
// Pick slide
await page
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 3eaa08ae..869e38d6 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -5,7 +5,7 @@ import {
feedSourcesJson2,
feedSourceSingleJson
} from "./data-fixtures.js";
-import { awaitDataRoute, awaitEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
+import { fulfillDataRoute, fulfillEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
@@ -15,14 +15,14 @@ test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
await loginTest({ page });
- await awaitDataRoute(page, "**/feed-sources*", feedSourcesJson);
+ await fulfillDataRoute(page, "**/feed-sources*", feedSourcesJson);
await page
.locator(".sidebar-nav .nav-link")
.getByText("Datakilder")
.click();
- await awaitEmptyRoutes(page, ["**/slides*"]);
+ await fulfillEmptyRoutes(page, ["**/slides*"]);
await expect(page.locator("h1").getByText("Datakilder")).toBeVisible();
});
@@ -33,7 +33,7 @@ test.describe("feed sources", () => {
});
test("It display error toast on save error", async ({ page }) => {
- await awaitDataRoute(page, "**/feed-sources*", errorJson, 500);
+ await fulfillDataRoute(page, "**/feed-sources*", errorJson, 500);
await page.getByText("Opret ny datakilde").click();
@@ -71,8 +71,8 @@ test.describe("feed sources", () => {
test("It goes to edit", async ({ page }) => {
await expect(page.locator("#feed-sourceTitle")).not.toBeVisible();
- await awaitDataRoute(page, "**/feed-sources*", feedSourcesJson2);
- await awaitDataRoute(page, "**/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ", feedSourceSingleJson);
+ await fulfillDataRoute(page, "**/feed-sources*", feedSourcesJson2);
+ await fulfillDataRoute(page, "**/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ", feedSourceSingleJson);
await page.locator("tbody").locator("tr td a").first().click();
await expect(page.locator("#feed-sourceTitle")).toBeVisible();
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index 3e4951ed..c26dfb24 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -4,7 +4,7 @@ import {
adminConfigJson,
emptyJson, tokenAdminJson, tokenEditorJson, tokenTenantsJson
} from "./data-fixtures.js";
-import { awaitDataRoute, awaitEmptyRoutes, beforeEachTest } from "./test-helper.js";
+import { fulfillDataRoute, fulfillEmptyRoutes, beforeEachTest } from "./test-helper.js";
test.describe("Login works", () => {
test.beforeEach(async ({ page }) => {
@@ -20,9 +20,9 @@ test.describe("Login works", () => {
test("Login one tenant works", async ({ page }) => {
await page.goto("/admin/playlists/list");
- await awaitEmptyRoutes(page, ['"**/playlists*"']);
+ await fulfillEmptyRoutes(page, ['"**/playlists*"']);
- await awaitDataRoute(page, "**/token", tokenAdminJson);
+ await fulfillDataRoute(page, "**/token", tokenAdminJson);
await page.locator("#login").click();
await expect(page.locator(".name")).toHaveText("John Doe");
@@ -31,7 +31,7 @@ test.describe("Login works", () => {
test("Login three tenant works", async ({ page }) => {
await page.goto("/admin/group/list");
- await awaitDataRoute(page, "**/token", tokenTenantsJson);
+ await fulfillDataRoute(page, "**/token", tokenTenantsJson);
await page.locator("#login").click();
@@ -42,7 +42,7 @@ test.describe("Login works", () => {
test("Login with tenant that has role editor", async ({ page }) => {
await page.goto("/admin/playlists/list");
- await awaitDataRoute(page, "**/token", tokenEditorJson);
+ await fulfillDataRoute(page, "**/token", tokenEditorJson);
await page.locator("#login").click();
await expect(page.locator(".name")).toHaveText("John Doe");
@@ -56,7 +56,7 @@ test.describe("Login works", () => {
}) => {
await page.goto("/admin/shared/list");
- await awaitDataRoute(page, "**/token", tokenEditorJson);
+ await fulfillDataRoute(page, "**/token", tokenEditorJson);
await page.locator("#login").click();
await expect(page.locator("main").locator("div")).toHaveText(
diff --git a/assets/tests/admin/admin-media.spec.js b/assets/tests/admin/admin-media.spec.js
index 67e19aa3..fa307bd9 100644
--- a/assets/tests/admin/admin-media.spec.js
+++ b/assets/tests/admin/admin-media.spec.js
@@ -1,5 +1,6 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest } from "./test-helper.js";
+import { fulfillDataRoute, beforeEachTest, loginTest } from "./test-helper.js";
+import { mediaListJson } from "./data-fixtures.js";
test.describe("media list tests", () => {
test.beforeEach(async ({ page }) => {
@@ -7,89 +8,11 @@ test.describe("media list tests", () => {
});
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/media/list");
- await page.route("**/media*", async (route) => {
- const json = {
- "@context": "/contexts/Media",
- "@id": "/v2/media",
- "@type": "hydra:Collection",
- "hydra:member": [
- {
- "@type": "Media",
- "@id": "/v2/media/001AG48FJC1NVA1EW20TSN13BP",
- title: "Laudantium aut exercitationem rerum itaque unde.",
- description:
- "Quia ut iusto dolores reiciendis animi. Magnam aut ut officiis quae. Nostrum magni et dolore dignissimos in totam qui et.",
- license: "Attribution-NonCommercial-NoDerivs License",
- created: "1971-06-13T05:21:39+01:00",
- modified: "2021-12-09T12:01:34+01:00",
- modifiedBy: "",
- createdBy: "",
- media: [],
- assets: {
- type: "image/jpeg",
- uri: "https://display.local.itkdev.dk/fixtures/template/images/mountain1.jpeg",
- dimensions: {
- height: 3456,
- width: 5184,
- },
- sha: "5a08dbb7fd3a074ed8659694c09cdb94fdb16cb1",
- size: 8945324,
- },
- },
- {
- "@type": "Media",
- "@id": "/v2/media/001AX5W2S909NW0K5A0NVE0NS6",
- title: "Ut eos illum quod.",
- description:
- "Et id est illum veniam eos quam placeat. Maxime ab aut aut fugit. Occaecati ut ea et occaecati repellendus amet. Quia consequuntur quod vel deserunt maiores.",
- license: "Attribution-NoDerivs License",
- created: "1971-06-18T06:59:58+01:00",
- modified: "2021-12-09T12:01:34+01:00",
- modifiedBy: "",
- createdBy: "",
- media: [],
- assets: {
- type: "image/jpeg",
- uri: "https://display.local.itkdev.dk/fixtures/template/images/mountain2.jpeg",
- dimensions: {
- height: 2592,
- width: 3888,
- },
- sha: "0654506b260c33544d39e5613716ef112ab38c7c",
- size: 4855058,
- },
- },
- ],
- "hydra:totalItems": 100,
- };
- await route.fulfill({ json });
- });
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
+ await loginTest({ page });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.locator("h1").getByText("Medier")).toBeVisible();
+ await fulfillDataRoute(page, "**/media*", mediaListJson);
+
+ await page.locator(".sidebar-nav .nav-link").getByText("Medier").click();
});
test("It loads media list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index 06496233..326acb55 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -1,5 +1,6 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest } from "./test-helper.js";
+import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import { emptyJson, errorJson, playlistListJson, playlistOnSaveJson, playlistSingleJson } from "./data-fixtures.js";
test.describe("Playlist create tests", () => {
test.beforeEach(async ({ page }) => {
@@ -7,43 +8,12 @@ test.describe("Playlist create tests", () => {
});
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/playlist/create");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/slides*", async (route) => {
- const json = {
- "@context": "/contexts/Slide",
- "@id": "/v2/slides",
- "@type": "hydra:Collection",
- "hydra:member": [],
- "hydra:totalItems": 100,
- };
- await route.fulfill({ json });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(
- page.locator("h1").getByText("Opret ny spilleliste"),
- ).toBeVisible();
+ await loginTest({ page });
+
+ await fulfillEmptyRoutes(page, ["**/tenants*"]);
+
+ await page.getByLabel("Tilføj ny spilleliste").first().click();
+ await expect(page.getByText("Opret ny spilleliste:")).toBeVisible();
});
test("It loads create playlist page", async ({ page }) => {
@@ -51,21 +21,11 @@ test.describe("Playlist create tests", () => {
});
test("It redirects on save", async ({ page }) => {
- await page.route("**/playlists", async (route) => {
- const json = {
- title: "A laudantium aspernatur qui.",
- description: "Description",
- created: "1991-09-10T22:36:56+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- };
- await route.fulfill({ json });
- });
+ await fulfillDataRoute(page, "**/playlists", playlistOnSaveJson);
// Displays success toast and redirects
await expect(
- page.locator(".Toastify").locator(".Toastify__toast--success"),
+ page.locator(".Toastify").locator(".Toastify__toast--success")
).not.toBeVisible();
await page.locator("#save_slide_and_close").click();
await expect(
@@ -73,36 +33,28 @@ test.describe("Playlist create tests", () => {
.locator(".Toastify")
.locator(".Toastify__toast--success")
.getByText(/gemt/)
- .first(),
+ .first()
).toBeVisible();
await expect(page).toHaveURL(/playlist\/list/);
});
test("It display error toast on save error", async ({ page }) => {
- await page.route("**/playlists", async (route) => {
- const json = {
- "@context": "/contexts/Error",
- "@type": "hydra:Error",
- "hydra:title": "An error occurred",
- "hydra:description": "An error occurred",
- };
- await route.fulfill({ status: 500, json });
- });
+ await fulfillDataRoute(page, "**/playlists", errorJson, 500);
// Displays error toast and stays on page
await expect(
- page.locator(".Toastify").locator(".Toastify__toast--error"),
+ page.locator(".Toastify").locator(".Toastify__toast--error")
).not.toBeVisible();
await page.locator("#save_playlist").click();
await expect(
- page.locator(".Toastify").locator(".Toastify__toast--error"),
+ page.locator(".Toastify").locator(".Toastify__toast--error")
).toBeVisible();
await expect(
page
.locator(".Toastify")
.locator(".Toastify__toast--error")
.getByText(/An error occurred/)
- .first(),
+ .first()
).toBeVisible();
await expect(page).toHaveURL(/playlist\/create/);
});
@@ -116,137 +68,37 @@ test.describe("Playlist create tests", () => {
test.describe("Playlist list tests", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/playlist/list");
- await page.route("**/playlists*", async (route) => {
- const json = {
- "@context": "/contexts/Playlist",
- "@id": "/v2/playlists",
- "@type": "hydra:Collection",
- "hydra:member": [
- {
- "@type": "Playlist",
- "@id": "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC",
- title: "Et consequatur voluptatibus dolore ut ut.",
- description:
- "Atque maiores nam in occaecati labore labore inventore quo. Enim nemo totam hic. Ut suscipit id sint sed quia.",
- schedules: [],
- created: "1975-06-08T13:12:49.000Z",
- modified: "2022-01-30T15:42:42.000Z",
- modifiedBy: "",
- createdBy: "",
- slides: "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC/slides",
- campaignScreens: ["/v2/screens/00TH1ZRMZC141K1DMB1H7J03CS"],
- campaignScreenGroups: [],
- isCampaign: true,
- published: {
- from: "2022-03-23T21:30:21.000Z",
- to: "2022-03-25T12:39:29.000Z",
- },
- },
- {
- "@type": "Playlist",
- "@id": "/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P",
- title: "Voluptas molestias nemo et.",
- description:
- "Aperiam quam sunt quia qui. Iusto ut deserunt veritatis nobis dolorem. Aliquid quo vel quia.",
- schedules: [],
- created: "1978-07-12T17:43:59.000Z",
- modified: "2022-01-30T15:42:42.000Z",
- modifiedBy: "",
- createdBy: "",
- slides: "/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P/slides",
- campaignScreens: [],
- campaignScreenGroups: [
- "/v2/screen-groups/00EQWMS5WA1WJE0WD81VF91DFH",
- "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
- "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
- ],
- isCampaign: false,
- published: {
- from: "2021-03-21T02:10:37.000Z",
- to: "2021-11-08T12:13:31.000Z",
- },
- },
- ],
- "hydra:totalItems": 10,
- };
- await route.fulfill({ json });
- });
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/slides*", async (route) => {
- const json = {
- "@context": "/contexts/Slide",
- "@id": "/v2/slides",
- "@type": "hydra:Collection",
- "hydra:member": [],
- "hydra:totalItems": 100,
- };
- await route.fulfill({ json });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
+ await beforeEachTest(page);
+ });
+
+ test.beforeEach(async ({ page }) => {
+ await loginTest({ page });
+
+ await fulfillDataRoute(page, "**/playlists*", playlistListJson);
+
+ await fulfillEmptyRoutes(page, ["**/tenants*"]);
+
+ await page.getByRole("link", { name: "Spillelister", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Spillelister", exact: true })).toBeVisible();
});
test("It loads playlist list", async ({ page }) => {
await expect(
- page.locator("table").locator("tbody").first(),
+ page.locator("table").locator("tbody").first()
).not.toBeEmpty();
await expect(page.locator("tbody").locator("tr td").first()).toBeVisible();
});
test("It goes to edit", async ({ page }) => {
- await page.route("**/playlists/*", async (route) => {
- const json = {
- "@id": "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC",
- title: "Et consequatur voluptatibus dolore ut ut.",
- description:
- "Atque maiores nam in occaecati labore labore inventore quo. Enim nemo totam hic. Ut suscipit id sint sed quia.",
- schedules: [],
- created: "1975-06-08T13:12:49.000Z",
- modified: "2022-01-30T15:42:42.000Z",
- modifiedBy: "",
- createdBy: "",
- slides: "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC/slides",
- campaignScreens: ["/v2/screens/00TH1ZRMZC141K1DMB1H7J03CS"],
- campaignScreenGroups: [],
- isCampaign: true,
- published: {
- from: "2022-03-23T21:30:21.000Z",
- to: "2022-03-25T12:39:29.000Z",
- },
- };
-
- await route.fulfill({ json });
- });
+ await fulfillDataRoute(page, "**/playlists/*", playlistSingleJson);
await expect(page.locator("#playlistTitle")).not.toBeVisible();
await page.locator("tbody").locator("tr td a").nth(0).click();
await expect(page.locator("#playlistTitle")).toBeVisible();
});
- test("The correct amount of column headers loaded (playlist list)", async ({
- page,
- }) => {
- await expect(page.locator("thead").locator("th")).toHaveCount(8);
- });
+ test("The correct amount of column headers loaded (playlist list)",
+ async ({ page }) => {
+ await expect(page.locator("thead").locator("th")).toHaveCount(8);
+ });
});
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index d8a6d376..8851f4d1 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -693,6 +693,143 @@ const slidesJson1 = {
"hydra:totalItems": 60,
};
+const mediaListJson = {
+ "@context": "/contexts/Media",
+ "@id": "/v2/media",
+ "@type": "hydra:Collection",
+ "hydra:member": [
+ {
+ "@type": "Media",
+ "@id": "/v2/media/001AG48FJC1NVA1EW20TSN13BP",
+ title: "Laudantium aut exercitationem rerum itaque unde.",
+ description:
+ "Quia ut iusto dolores reiciendis animi. Magnam aut ut officiis quae. Nostrum magni et dolore dignissimos in totam qui et.",
+ license: "Attribution-NonCommercial-NoDerivs License",
+ created: "1971-06-13T05:21:39+01:00",
+ modified: "2021-12-09T12:01:34+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ media: [],
+ assets: {
+ type: "image/jpeg",
+ uri: "https://display.local.itkdev.dk/fixtures/template/images/mountain1.jpeg",
+ dimensions: {
+ height: 3456,
+ width: 5184,
+ },
+ sha: "5a08dbb7fd3a074ed8659694c09cdb94fdb16cb1",
+ size: 8945324,
+ },
+ },
+ {
+ "@type": "Media",
+ "@id": "/v2/media/001AX5W2S909NW0K5A0NVE0NS6",
+ title: "Ut eos illum quod.",
+ description:
+ "Et id est illum veniam eos quam placeat. Maxime ab aut aut fugit. Occaecati ut ea et occaecati repellendus amet. Quia consequuntur quod vel deserunt maiores.",
+ license: "Attribution-NoDerivs License",
+ created: "1971-06-18T06:59:58+01:00",
+ modified: "2021-12-09T12:01:34+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ media: [],
+ assets: {
+ type: "image/jpeg",
+ uri: "https://display.local.itkdev.dk/fixtures/template/images/mountain2.jpeg",
+ dimensions: {
+ height: 2592,
+ width: 3888,
+ },
+ sha: "0654506b260c33544d39e5613716ef112ab38c7c",
+ size: 4855058,
+ },
+ },
+ ],
+ "hydra:totalItems": 100,
+};
+
+const playlistOnSaveJson = {
+ title: "A laudantium aspernatur qui.",
+ description: "Description",
+ created: "1991-09-10T22:36:56+02:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: ""
+};
+
+const playlistListJson = {
+ "@context": "/contexts/Playlist",
+ "@id": "/v2/playlists",
+ "@type": "hydra:Collection",
+ "hydra:member": [
+ {
+ "@type": "Playlist",
+ "@id": "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC",
+ title: "Et consequatur voluptatibus dolore ut ut.",
+ description:
+ "Atque maiores nam in occaecati labore labore inventore quo. Enim nemo totam hic. Ut suscipit id sint sed quia.",
+ schedules: [],
+ created: "1975-06-08T13:12:49.000Z",
+ modified: "2022-01-30T15:42:42.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ slides: "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC/slides",
+ campaignScreens: ["/v2/screens/00TH1ZRMZC141K1DMB1H7J03CS"],
+ campaignScreenGroups: [],
+ isCampaign: true,
+ published: {
+ from: "2022-03-23T21:30:21.000Z",
+ to: "2022-03-25T12:39:29.000Z"
+ }
+ },
+ {
+ "@type": "Playlist",
+ "@id": "/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P",
+ title: "Voluptas molestias nemo et.",
+ description:
+ "Aperiam quam sunt quia qui. Iusto ut deserunt veritatis nobis dolorem. Aliquid quo vel quia.",
+ schedules: [],
+ created: "1978-07-12T17:43:59.000Z",
+ modified: "2022-01-30T15:42:42.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ slides: "/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P/slides",
+ campaignScreens: [],
+ campaignScreenGroups: [
+ "/v2/screen-groups/00EQWMS5WA1WJE0WD81VF91DFH",
+ "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
+ "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3"
+ ],
+ isCampaign: false,
+ published: {
+ from: "2021-03-21T02:10:37.000Z",
+ to: "2021-11-08T12:13:31.000Z"
+ }
+ }
+ ],
+ "hydra:totalItems": 10
+};
+
+const playlistSingleJson = {
+ "@id": "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC",
+ title: "Et consequatur voluptatibus dolore ut ut.",
+ description:
+ "Atque maiores nam in occaecati labore labore inventore quo. Enim nemo totam hic. Ut suscipit id sint sed quia.",
+ schedules: [],
+ created: "1975-06-08T13:12:49.000Z",
+ modified: "2022-01-30T15:42:42.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ slides: "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC/slides",
+ campaignScreens: ["/v2/screens/00TH1ZRMZC141K1DMB1H7J03CS"],
+ campaignScreenGroups: [],
+ isCampaign: true,
+ published: {
+ from: "2022-03-23T21:30:21.000Z",
+ to: "2022-03-25T12:39:29.000Z"
+ }
+};
+
export {
tokenAdminJson,
tokenTenantsJson,
@@ -706,4 +843,8 @@ export {
accessConfigJson,
clientConfigJson,
adminConfigJson,
+ mediaListJson,
+ playlistOnSaveJson,
+ playlistListJson,
+ playlistSingleJson,
};
diff --git a/assets/tests/admin/test-helper.js b/assets/tests/admin/test-helper.js
index 2cfc370a..a496d445 100644
--- a/assets/tests/admin/test-helper.js
+++ b/assets/tests/admin/test-helper.js
@@ -24,7 +24,7 @@ const beforeEachTest = async (page) => {
});
};
-const awaitEmptyRoutes = async (page, routePatterns) => {
+const fulfillEmptyRoutes = async (page, routePatterns) => {
for (const routePattern of routePatterns) {
await page.route(routePattern, async (route) => {
await route.fulfill({ json: emptyJson });
@@ -32,7 +32,7 @@ const awaitEmptyRoutes = async (page, routePatterns) => {
}
}
-const awaitDataRoute = async (page, routePattern, data, status) => {
+const fulfillDataRoute = async (page, routePattern, data, status) => {
const result = { json: data};
if (status) {
@@ -62,4 +62,4 @@ const loginTest = async ({ page }) => {
await expect(page.locator("h1").getByText("Slides")).toBeVisible();
};
-export { loginTest, beforeEachTest, awaitEmptyRoutes, awaitDataRoute };
+export { loginTest, beforeEachTest, fulfillEmptyRoutes, fulfillDataRoute };
From a27704f063672b0b873ae1851266c997e099f705 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Fri, 8 Aug 2025 10:21:22 +0200
Subject: [PATCH 28/30] 4565: Fixed screen-groups and screen tests
---
assets/tests/admin/admin-playlist.spec.js | 4 +-
.../tests/admin/admin-screen-groups.spec.js | 234 +++---------------
assets/tests/admin/admin-screens.spec.js | 146 ++---------
assets/tests/admin/data-fixtures.js | 184 +++++++++++++-
4 files changed, 229 insertions(+), 339 deletions(-)
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index 326acb55..e20db4e4 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
-import { emptyJson, errorJson, playlistListJson, playlistOnSaveJson, playlistSingleJson } from "./data-fixtures.js";
+import { emptyJson, errorJson, playlistListJson, onSaveJson, playlistSingleJson } from "./data-fixtures.js";
test.describe("Playlist create tests", () => {
test.beforeEach(async ({ page }) => {
@@ -21,7 +21,7 @@ test.describe("Playlist create tests", () => {
});
test("It redirects on save", async ({ page }) => {
- await fulfillDataRoute(page, "**/playlists", playlistOnSaveJson);
+ await fulfillDataRoute(page, "**/playlists", onSaveJson);
// Displays success toast and redirects
await expect(
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index f2162453..dc3647d1 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -1,5 +1,13 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest } from "./test-helper.js";
+import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import {
+ playlistListJson,
+ onSaveJson,
+ errorJson,
+ screenGroupsListJson,
+ screenGroupsSingleJson
+} from "./data-fixtures.js";
+import { json } from "react-router-dom";
test.describe("Create group page works", () => {
test.beforeEach(async ({ page }) => {
@@ -7,32 +15,14 @@ test.describe("Create group page works", () => {
});
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/group/create");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
+ await loginTest({ page });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.locator("h1").getByText("Opret ny gruppe")).toBeVisible();
+ await fulfillEmptyRoutes(page, ["**/screen-groups*"]);
+
+ await page.getByRole("link", { name: "Grupper", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Grupper", exact: true })).toBeVisible();
+ await page.getByRole("button", { name: "Opret ny gruppe", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Opret ny gruppe", exact: true })).toBeVisible();
});
test("It loads create group page", async ({ page }) => {
@@ -40,17 +30,7 @@ test.describe("Create group page works", () => {
});
test("It redirects on save", async ({ page }) => {
- await page.route("**/screen-groups", async (route) => {
- const json = {
- title: "A laudantium aspernatur qui.",
- description: "Description",
- created: "1991-09-10T22:36:56+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- };
- await route.fulfill({ json });
- });
+ await fulfillDataRoute(page, "**/screen-groups", onSaveJson);
// Displays success toast and redirects
await expect(
@@ -74,15 +54,8 @@ test.describe("Create group page works", () => {
});
test("It display error toast on save error", async ({ page }) => {
- await page.route("**/screen-groups", async (route) => {
- const json = {
- "@context": "/contexts/Error",
- "@type": "hydra:Error",
- "hydra:title": "An error occurred",
- "hydra:description": "An error occurred",
- };
- await route.fulfill({ status: 500, json });
- });
+ await fulfillDataRoute(page, "**/screen-groups", errorJson, 500);
+
// Displays error toast and stays on page
await expect(
page.locator(".Toastify").locator(".Toastify__toast--error"),
@@ -97,152 +70,17 @@ test.describe("Create group page works", () => {
test.describe("Groups list works", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/group/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
+ await beforeEachTest(page);
+ });
- await page.route("**/screen-groups*", async (route) => {
- const json = {
- "@id": "/v2/screen-groups",
- "hydra:member": [
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/000RAH746Q1AD8011Z1JNV06N3",
- title: "Cupiditate et quidem autem iusto.",
- description:
- "Eos quibusdam consectetur nisi consequatur voluptas. Unde maxime sunt quidem magnam. Sed ipsa voluptas qui occaecati ea nobis.",
- created: "1970-10-30T08:30:07+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/0012G98YZS0VTK0Z2T02AD1DC3",
- title: "Dignissimos nihil non sit laudantium.",
- description:
- "Maxime dicta magnam est voluptas voluptas. Est omnis expedita harum reprehenderit debitis laboriosam ab omnis. Sed temporibus iste voluptatibus ut qui est non voluptatem.",
- created: "1971-03-05T20:43:43+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/001EZQXKKR0P7X0A3119Z016SB",
- title: "Aut nam accusantium id aut.",
- description:
- "Et est nisi autem nihil. Blanditiis facere repellat et. Est et architecto modi laboriosam corporis et.",
- created: "1971-08-07T23:56:38+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/003J350X2D060H00TE1DW50640",
- title: "Velit rem commodi necessitatibus eos.",
- description:
- "Non sequi sed fugit. Nihil cumque nesciunt hic recusandae rem suscipit sunt. Nostrum voluptatem ut consequatur non illum.",
- created: "1973-11-18T23:15:03+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/003Z784JQS1PNS1RX1003N0NCD",
- title: "Quod esse voluptas ut.",
- description:
- "Deleniti velit est quasi commodi alias est minima. Harum iusto odio aperiam consequatur qui est. Vel ut id aperiam nobis fugiat et modi. Est dolores rerum id sed excepturi et.",
- created: "1974-05-01T02:50:31+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/009YS5ZYPH1B9T0JE01S290T5Y",
- title: "Tenetur voluptatem quo rerum exercitationem.",
- description:
- "Suscipit provident odit in eius sed voluptatibus. Neque aut corporis aspernatur quo qui. Inventore nam est sed sed maiores odio.",
- created: "1980-11-05T17:57:30+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/00C1V2MX2S02N30EXM163A0E6X",
- title: "Distinctio quisquam et totam molestias.",
- description:
- "Ad ipsam architecto eum repellat excepturi. Quos deleniti itaque ut reprehenderit aut rerum autem. Nihil et mollitia voluptatibus quis voluptatem. Ex eaque sint nostrum impedit.",
- created: "1983-02-17T02:51:45+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/00DDTCJCDX0H101N480E180K4B",
- title: "Cumque facere nulla reiciendis.",
- description:
- "Veritatis doloremque delectus voluptas numquam dolores nobis. Dignissimos quo facere eum iure.",
- created: "1984-08-16T16:14:03+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/00GEPM6JRX0V2P0YST0JHA03CC",
- title: "Ea aspernatur odit rerum.",
- description:
- "Adipisci tenetur placeat perspiciatis assumenda. Voluptas officiis magnam reprehenderit possimus non. Tempore delectus numquam veritatis harum natus.",
- created: "1987-12-03T16:33:04+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- {
- "@type": "ScreenGroup",
- "@id": "/v2/screen-groups/00KXGYAJ4A1D5P0EA11SKF0BG8",
- title: "A laudantium aspernatur qui.",
- description:
- "Non fugiat nobis occaecati. Sed ut velit beatae amet ea esse. Quo dolorem commodi magni at. Illum voluptatem neque nobis et ut. Ad rerum tempore vel commodi suscipit corrupti.",
- created: "1991-09-10T22:36:56+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- },
- ],
- "hydra:totalItems": 20,
- };
+ test.beforeEach(async ({ page }) => {
+ await loginTest({ page });
- await route.fulfill({ json });
- });
+ await fulfillEmptyRoutes(page, ['**/screens*']);
+ await fulfillDataRoute(page, "**/screen-groups*", screenGroupsListJson);
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
+ await page.getByRole("link", { name: "Grupper", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Grupper", exact: true })).toBeVisible();
});
test("It loads groups list", async ({ page }) => {
@@ -251,19 +89,7 @@ test.describe("Groups list works", () => {
});
test("It goes to edit (groups list)", async ({ page }) => {
- await page.route("**/screen-groups/*", async (route) => {
- const json = {
- "@id": "/v2/screen-groups/00GEPM6JRX0V2P0YST0JHA03CC",
- title: "Ea aspernatur odit rerum.",
- description:
- "Adipisci tenetur placeat perspiciatis assumenda. Voluptas officiis magnam reprehenderit possimus non. Tempore delectus numquam veritatis harum natus.",
- created: "1987-12-03T16:33:04+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- };
- await route.fulfill({ json });
- });
+ await fulfillDataRoute(page, "**/screen-groups/000RAH746Q1AD8011Z1JNV06N3", screenGroupsSingleJson);
await expect(page.locator("#groupTitle")).not.toBeVisible();
await page.locator("tbody").locator("tr td a").nth(0).click();
@@ -284,11 +110,11 @@ test.describe("Groups list works", () => {
test("It removes all selected", async ({ page }) => {
await page.locator("tbody").locator("tr td input").nth(0).click();
- expect(
+ await expect(
page.locator("tbody").locator("tr").nth(0).getByRole("checkbox"),
).toBeChecked();
await page.locator("#clear-rows-button").click();
- expect(
+ await expect(
page.locator("tbody").locator("tr").nth(0).getByRole("checkbox"),
).not.toBeChecked();
});
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index 1e002e14..b4bb2b3d 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -1,154 +1,38 @@
import { test, expect } from "@playwright/test";
-import { adminConfigJson } from "./data-fixtures.js";
-import { beforeEachTest } from "./test-helper.js";
+import { adminConfigJson, screenGroupsListJson, screensListJson } from "./data-fixtures.js";
+import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
-test.describe("Screen list tests", () => {
+test.describe("Screen", () => {
test.beforeEach(async ({ page }) => {
await beforeEachTest(page);
});
- test("Test list", async ({ page }) => {
- await page.goto("/admin/screen/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
-
- await page.route("**/screens*", async (route) => {
- const json = {
- "@id": "/v2/screens",
- "hydra:totalItems": 2,
- "hydra:member": [
- {
- "@type": "Screen",
- "@id": "/v2/screens/00APXK73HQ11PM0X3P12EG14DZ",
- title: "Ab eos dolorum minima inventore.",
- description:
- "Non inventore ab vitae. Voluptatem assumenda aliquam sunt nulla sint corrupti et. Nihil consectetur facere cum modi aliquid. Non aut voluptas voluptas laudantium.",
- size: "42",
- created: "1981-09-01T17:22:18+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- layout: "/v2/layouts/009S1H8VER00GK086N0M1J16K9",
- location:
- "Natus aut est eveniet deleniti nihil voluptatum. Accusamus similique adipisci at qui molestiae quia nihil eligendi. Delectus repellendus ut asperiores ut debitis.",
- regions: [],
- inScreenGroups: "/v2/screens/00APXK73HQ11PM0X3P12EG14DZ/groups",
- dimensions: {
- width: 1920,
- height: 1200,
- },
- },
- {
- "@type": "Screen",
- "@id": "/v2/screens/00AYESM1AR002E0YKH0JQ70185",
- title: "Accusantium aperiam mollitia consectetur.",
- description:
- "Asperiores id aut temporibus expedita quia rem. Sunt possimus voluptas voluptas exercitationem. Totam odio necessitatibus aut velit. Nisi est voluptates suscipit rerum perspiciatis.",
- size: "55",
- created: "1981-12-04T09:31:11+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- layout: "/v2/layouts/009S1H8VER00GK086N0M1J16K9",
- location:
- "Occaecati beatae iure molestias sapiente nihil. Tempore quo quibusdam odit quia.",
- regions: [],
- inScreenGroups: "/v2/screens/00AYESM1AR002E0YKH0JQ70185/groups",
- dimensions: {
- width: 1920,
- height: 1200,
- },
- },
- ],
- };
- await route.fulfill({ json });
- });
-
- await page.route("**/campaigns*", async (route) => {
- await route.fulfill({
- json: {
- "hydra:member": [],
- "hydra:totalItems": 0,
- },
- });
- });
+ test.beforeEach(async ({ page }) => {
+ await loginTest({ page });
- await page.route("**/screen-groups*", async (route) => {
- await route.fulfill({
- json: {
- "hydra:member": [],
- "hydra:totalItems": 0,
- },
- });
- });
+ await fulfillDataRoute(page, "**/screens*", screensListJson);
- await page.route("**/config/admin", async (route) => {
- await route.fulfill({ json: adminConfigJson });
- });
+ await fulfillEmptyRoutes(page, ["**/campaigns*", "**/screen-groups*", "**/layouts*"]);
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
+ await page.getByRole("link", { name: "Skærme", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Skærme", exact: true })).toBeVisible();
+ });
- await expect(page.locator("h1").getByText("Skærme")).toBeVisible();
+ test("Loads list", async ({ page }) => {
await expect(page.locator("table").locator("tbody")).not.toBeEmpty();
await expect(page.locator("tbody").locator("tr td")).toHaveCount(16);
await expect(page.locator("thead").locator("th")).toHaveCount(8);
});
-});
-
-test.describe("Screen create tests", () => {
- test.beforeEach(async ({ page }) => {
- await page.goto("/admin/screen/create");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
-
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- });
test("It loads create screen page", async ({ page }) => {
+ await page.getByLabel("Tilføj ny skærm").first().click();
+ await expect(page.getByText("Opret ny skærm")).toBeVisible();
await expect(page.locator("#save_screen")).toBeVisible();
});
test("It cancels create screen", async ({ page }) => {
+ await page.getByLabel("Tilføj ny skærm").first().click();
+ await expect(page.getByText("Opret ny skærm")).toBeVisible();
await expect(page.locator("#cancel_screen")).toBeVisible();
await page.locator("#cancel_screen").click();
await expect(page.locator("#cancel_screen")).not.toBeVisible();
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index 8851f4d1..c3a0eb4f 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -748,7 +748,7 @@ const mediaListJson = {
"hydra:totalItems": 100,
};
-const playlistOnSaveJson = {
+const onSaveJson = {
title: "A laudantium aspernatur qui.",
description: "Description",
created: "1991-09-10T22:36:56+02:00",
@@ -830,6 +830,183 @@ const playlistSingleJson = {
}
};
+const screenGroupsListJson = {
+ "@id": "/v2/screen-groups",
+ "hydra:member": [
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/000RAH746Q1AD8011Z1JNV06N3",
+ title: "Cupiditate et quidem autem iusto.",
+ description:
+ "Eos quibusdam consectetur nisi consequatur voluptas. Unde maxime sunt quidem magnam. Sed ipsa voluptas qui occaecati ea nobis.",
+ created: "1970-10-30T08:30:07+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/0012G98YZS0VTK0Z2T02AD1DC3",
+ title: "Dignissimos nihil non sit laudantium.",
+ description:
+ "Maxime dicta magnam est voluptas voluptas. Est omnis expedita harum reprehenderit debitis laboriosam ab omnis. Sed temporibus iste voluptatibus ut qui est non voluptatem.",
+ created: "1971-03-05T20:43:43+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/001EZQXKKR0P7X0A3119Z016SB",
+ title: "Aut nam accusantium id aut.",
+ description:
+ "Et est nisi autem nihil. Blanditiis facere repellat et. Est et architecto modi laboriosam corporis et.",
+ created: "1971-08-07T23:56:38+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/003J350X2D060H00TE1DW50640",
+ title: "Velit rem commodi necessitatibus eos.",
+ description:
+ "Non sequi sed fugit. Nihil cumque nesciunt hic recusandae rem suscipit sunt. Nostrum voluptatem ut consequatur non illum.",
+ created: "1973-11-18T23:15:03+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/003Z784JQS1PNS1RX1003N0NCD",
+ title: "Quod esse voluptas ut.",
+ description:
+ "Deleniti velit est quasi commodi alias est minima. Harum iusto odio aperiam consequatur qui est. Vel ut id aperiam nobis fugiat et modi. Est dolores rerum id sed excepturi et.",
+ created: "1974-05-01T02:50:31+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/009YS5ZYPH1B9T0JE01S290T5Y",
+ title: "Tenetur voluptatem quo rerum exercitationem.",
+ description:
+ "Suscipit provident odit in eius sed voluptatibus. Neque aut corporis aspernatur quo qui. Inventore nam est sed sed maiores odio.",
+ created: "1980-11-05T17:57:30+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/00C1V2MX2S02N30EXM163A0E6X",
+ title: "Distinctio quisquam et totam molestias.",
+ description:
+ "Ad ipsam architecto eum repellat excepturi. Quos deleniti itaque ut reprehenderit aut rerum autem. Nihil et mollitia voluptatibus quis voluptatem. Ex eaque sint nostrum impedit.",
+ created: "1983-02-17T02:51:45+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/00DDTCJCDX0H101N480E180K4B",
+ title: "Cumque facere nulla reiciendis.",
+ description:
+ "Veritatis doloremque delectus voluptas numquam dolores nobis. Dignissimos quo facere eum iure.",
+ created: "1984-08-16T16:14:03+02:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/00GEPM6JRX0V2P0YST0JHA03CC",
+ title: "Ea aspernatur odit rerum.",
+ description:
+ "Adipisci tenetur placeat perspiciatis assumenda. Voluptas officiis magnam reprehenderit possimus non. Tempore delectus numquam veritatis harum natus.",
+ created: "1987-12-03T16:33:04+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ {
+ "@type": "ScreenGroup",
+ "@id": "/v2/screen-groups/00KXGYAJ4A1D5P0EA11SKF0BG8",
+ title: "A laudantium aspernatur qui.",
+ description:
+ "Non fugiat nobis occaecati. Sed ut velit beatae amet ea esse. Quo dolorem commodi magni at. Illum voluptatem neque nobis et ut. Ad rerum tempore vel commodi suscipit corrupti.",
+ created: "1991-09-10T22:36:56+02:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ },
+ ],
+ "hydra:totalItems": 20,
+};
+
+const screenGroupsSingleJson = {
+ "@id": "/v2/screen-groups/00GEPM6JRX0V2P0YST0JHA03CC",
+ title: "Ea aspernatur odit rerum.",
+ description:
+ "Adipisci tenetur placeat perspiciatis assumenda. Voluptas officiis magnam reprehenderit possimus non. Tempore delectus numquam veritatis harum natus.",
+ created: "1987-12-03T16:33:04+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+};
+
+const screensListJson = {
+ "@id": "/v2/screens",
+ "hydra:totalItems": 2,
+ "hydra:member": [
+ {
+ "@type": "Screen",
+ "@id": "/v2/screens/00APXK73HQ11PM0X3P12EG14DZ",
+ title: "Ab eos dolorum minima inventore.",
+ description:
+ "Non inventore ab vitae. Voluptatem assumenda aliquam sunt nulla sint corrupti et. Nihil consectetur facere cum modi aliquid. Non aut voluptas voluptas laudantium.",
+ size: "42",
+ created: "1981-09-01T17:22:18+02:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ layout: "/v2/layouts/009S1H8VER00GK086N0M1J16K9",
+ location:
+ "Natus aut est eveniet deleniti nihil voluptatum. Accusamus similique adipisci at qui molestiae quia nihil eligendi. Delectus repellendus ut asperiores ut debitis.",
+ regions: [],
+ inScreenGroups: "/v2/screens/00APXK73HQ11PM0X3P12EG14DZ/groups",
+ dimensions: {
+ width: 1920,
+ height: 1200,
+ },
+ },
+ {
+ "@type": "Screen",
+ "@id": "/v2/screens/00AYESM1AR002E0YKH0JQ70185",
+ title: "Accusantium aperiam mollitia consectetur.",
+ description:
+ "Asperiores id aut temporibus expedita quia rem. Sunt possimus voluptas voluptas exercitationem. Totam odio necessitatibus aut velit. Nisi est voluptates suscipit rerum perspiciatis.",
+ size: "55",
+ created: "1981-12-04T09:31:11+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ layout: "/v2/layouts/009S1H8VER00GK086N0M1J16K9",
+ location:
+ "Occaecati beatae iure molestias sapiente nihil. Tempore quo quibusdam odit quia.",
+ regions: [],
+ inScreenGroups: "/v2/screens/00AYESM1AR002E0YKH0JQ70185/groups",
+ dimensions: {
+ width: 1920,
+ height: 1200,
+ },
+ },
+ ],
+};
+
export {
tokenAdminJson,
tokenTenantsJson,
@@ -844,7 +1021,10 @@ export {
clientConfigJson,
adminConfigJson,
mediaListJson,
- playlistOnSaveJson,
+ onSaveJson,
playlistListJson,
playlistSingleJson,
+ screenGroupsListJson,
+ screenGroupsSingleJson,
+ screensListJson,
};
From bb7976ea4f626a67e9d48cc6bbd5f918db3a1b69 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Sat, 9 Aug 2025 07:16:42 +0200
Subject: [PATCH 29/30] 4565: Fixed remaining tests
---
assets/tests/admin/admin-campaign.spec.js | 2 +-
assets/tests/admin/admin-feed-sources.spec.js | 2 +-
assets/tests/admin/admin-login.spec.js | 14 +-
assets/tests/admin/admin-media.spec.js | 2 +-
assets/tests/admin/admin-playlist.spec.js | 4 +-
.../tests/admin/admin-screen-groups.spec.js | 4 +-
assets/tests/admin/admin-screens.spec.js | 2 +-
assets/tests/admin/admin-shared-list.spec.js | 90 +--
assets/tests/admin/admin-slides.spec.js | 476 +------------
assets/tests/admin/admin-theme.spec.js | 417 +-----------
assets/tests/admin/admin-top-bar.spec.js | 6 +-
assets/tests/admin/data-fixtures.js | 640 ++++++++++++++++++
assets/tests/admin/test-helper.js | 2 +-
13 files changed, 709 insertions(+), 952 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 3f77d1db..77cc185e 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -8,7 +8,7 @@ test.describe("Campaign pages work", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillEmptyRoutes(page, ["**/playlists*", "**/screens*", "**/screen-groups*"]);
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index 869e38d6..e484c2e1 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -13,7 +13,7 @@ test.describe("feed sources", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillDataRoute(page, "**/feed-sources*", feedSourcesJson);
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index c26dfb24..485abe3e 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -18,9 +18,9 @@ test.describe("Login works", () => {
});
test("Login one tenant works", async ({ page }) => {
- await page.goto("/admin/playlists/list");
+ await page.goto("/admin/playlist/list");
- await fulfillEmptyRoutes(page, ['"**/playlists*"']);
+ await fulfillEmptyRoutes(page, ["**/playlists*"]);
await fulfillDataRoute(page, "**/token", tokenAdminJson);
@@ -29,7 +29,9 @@ test.describe("Login works", () => {
});
test("Login three tenant works", async ({ page }) => {
- await page.goto("/admin/group/list");
+ await page.goto("/admin/playlist/list");
+
+ await fulfillEmptyRoutes(page, ["**/playlists*"]);
await fulfillDataRoute(page, "**/token", tokenTenantsJson);
@@ -40,9 +42,12 @@ test.describe("Login works", () => {
});
test("Login with tenant that has role editor", async ({ page }) => {
- await page.goto("/admin/playlists/list");
+ await page.goto("/admin/playlist/list");
+
+ await fulfillEmptyRoutes(page, ["**/playlists*"]);
await fulfillDataRoute(page, "**/token", tokenEditorJson);
+
await page.locator("#login").click();
await expect(page.locator(".name")).toHaveText("John Doe");
@@ -57,6 +62,7 @@ test.describe("Login works", () => {
await page.goto("/admin/shared/list");
await fulfillDataRoute(page, "**/token", tokenEditorJson);
+
await page.locator("#login").click();
await expect(page.locator("main").locator("div")).toHaveText(
diff --git a/assets/tests/admin/admin-media.spec.js b/assets/tests/admin/admin-media.spec.js
index fa307bd9..4fec028b 100644
--- a/assets/tests/admin/admin-media.spec.js
+++ b/assets/tests/admin/admin-media.spec.js
@@ -8,7 +8,7 @@ test.describe("media list tests", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillDataRoute(page, "**/media*", mediaListJson);
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index e20db4e4..a5879a48 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -8,7 +8,7 @@ test.describe("Playlist create tests", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillEmptyRoutes(page, ["**/tenants*"]);
@@ -72,7 +72,7 @@ test.describe("Playlist list tests", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillDataRoute(page, "**/playlists*", playlistListJson);
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index dc3647d1..dce7dd16 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -15,7 +15,7 @@ test.describe("Create group page works", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillEmptyRoutes(page, ["**/screen-groups*"]);
@@ -74,7 +74,7 @@ test.describe("Groups list works", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillEmptyRoutes(page, ['**/screens*']);
await fulfillDataRoute(page, "**/screen-groups*", screenGroupsListJson);
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index b4bb2b3d..1b0280da 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -8,7 +8,7 @@ test.describe("Screen", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
await fulfillDataRoute(page, "**/screens*", screensListJson);
diff --git a/assets/tests/admin/admin-shared-list.spec.js b/assets/tests/admin/admin-shared-list.spec.js
index 58bf87f0..51576c87 100644
--- a/assets/tests/admin/admin-shared-list.spec.js
+++ b/assets/tests/admin/admin-shared-list.spec.js
@@ -1,5 +1,6 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest } from "./test-helper.js";
+import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import { playlistListJson, screensListJson } from "./data-fixtures.js";
test.describe("Shared list tests", () => {
test.beforeEach(async ({ page }) => {
@@ -7,89 +8,12 @@ test.describe("Shared list tests", () => {
});
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/shared/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/playlists*", async (route) => {
- const json = {
- "@context": "/contexts/Playlist",
- "@id": "/v2/playlists",
- "@type": "hydra:Collection",
- "hydra:member": [
- {
- "@type": "Playlist",
- "@id": "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC",
- title: "Et consequatur voluptatibus dolore ut ut.",
- description:
- "Atque maiores nam in occaecati labore labore inventore quo. Enim nemo totam hic. Ut suscipit id sint sed quia.",
- schedules: [],
- created: "1975-06-08T13:12:49.000Z",
- modified: "2022-01-30T15:42:42.000Z",
- modifiedBy: "",
- createdBy: "",
- slides: "/v2/playlists/004ZP1XQ1G1MVZ1T0100YN0MPC/slides",
- campaignScreens: ["/v2/screens/00TH1ZRMZC141K1DMB1H7J03CS"],
- campaignScreenGroups: [],
- isCampaign: true,
- published: {
- from: "2022-03-23T21:30:21.000Z",
- to: "2022-03-25T12:39:29.000Z",
- },
- },
- {
- "@type": "Playlist",
- "@id": "/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P",
- title: "Voluptas molestias nemo et.",
- description:
- "Aperiam quam sunt quia qui. Iusto ut deserunt veritatis nobis dolorem. Aliquid quo vel quia.",
- schedules: [],
- created: "1978-07-12T17:43:59.000Z",
- modified: "2022-01-30T15:42:42.000Z",
- modifiedBy: "",
- createdBy: "",
- slides: "/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P/slides",
- campaignScreens: [],
- campaignScreenGroups: [
- "/v2/screen-groups/00EQWMS5WA1WJE0WD81VF91DFH",
- "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
- "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
- ],
- isCampaign: false,
- published: {
- from: "2021-03-21T02:10:37.000Z",
- to: "2021-11-08T12:13:31.000Z",
- },
- },
- ],
- "hydra:totalItems": 2,
- };
+ await loginTest(page);
- await route.fulfill({ json });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(
- page.locator("h1").getByText("Delte spillelister"),
- ).toBeVisible();
+ await fulfillDataRoute(page, "**/playlists*", playlistListJson);
+
+ await page.getByRole("link", { name: "Delte spillelister", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Delte spillelister", exact: true })).toBeVisible();
});
test("It loads shared playlist list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-slides.spec.js b/assets/tests/admin/admin-slides.spec.js
index 1646fab0..77d5d981 100644
--- a/assets/tests/admin/admin-slides.spec.js
+++ b/assets/tests/admin/admin-slides.spec.js
@@ -1,130 +1,20 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest } from "./test-helper.js";
+import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import { emptyJson, errorJson, slidesListJson, templatesListJson } from "./data-fixtures.js";
-test.describe("Create slide page works", () => {
+test.describe("Slide create", () => {
test.beforeEach(async ({ page }) => {
await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/slide/create");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/templates?itemsPerPage*", async (route) => {
- const json = {
- "@id": "/v2/templates",
- "hydra:member": [
- {
- "@type": "Template",
- "@id": "/v2/templates/00XZXR5XDH0D1M16K10NYQ0A55",
- title: "Est totam provident sunt.",
- description:
- "Tempora qui minus officia quis consequuntur voluptates. Quasi minima eveniet repudiandae laborum dolor quasi totam qui. Iusto enim inventore molestias amet aut.",
- created: "2002-08-30T14:14:07+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- resources: {
- admin:
- "http://www.harber.com/atque-inventore-consequatur-mollitia-ducimus-veritatis-doloribus-ad",
- schema: "http://www.kulas.net/quia-unde-quos-error-modi-saepe",
- component: "http://keebler.com/",
- assets: {
- type: "css",
- url: "https://www.borer.biz/voluptas-blanditiis-et-quo-aut-culpa-reiciendis-dolorum",
- },
- options: {
- fade: true,
- },
- content: {
- text: "Accusantium exercitationem animi qui provident ipsa distinctio.",
- },
- },
- },
- {
- "@type": "Template",
- "@id": "/v2/templates/016MHSNKCH1PQW1VY615JC19Y3",
- title: "Ut exercitationem est quia ad quas.",
- description:
- "Laborum quod ut ducimus suscipit quia nostrum. Saepe ex voluptas aut. Sit numquam vel est sunt. Cupiditate excepturi non saepe in voluptatem vel rem quaerat. Magni aut eaque vel deleniti.",
- created: "2012-01-28T09:17:22+01:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- resources: {
- admin:
- "https://vandervort.com/sapiente-quo-est-rerum-nihil-sint-placeat-ipsa-id.html",
- schema:
- "http://www.gulgowski.com/debitis-voluptatem-earum-sed-totam-aut-impedit-facere",
- component:
- "https://lehner.com/officia-ducimus-ea-beatae-eum-amet-provident-sint.html",
- assets: {
- type: "css",
- url: "http://www.emmerich.net/aliquam-excepturi-id-et-ab-voluptate.html",
- },
- options: {
- fade: true,
- },
- content: {
- text: "Ut qui assumenda ex vel quod dolorem perspiciatis eos quis.",
- },
- },
- },
- {
- "@type": "Template",
- "@id": "/v2/templates/017X81AEJV2GJE0NC51KKK0EK8",
- title: "Delectus magnam repudiandae molestiae et a.",
- description:
- "Consequuntur est ut commodi sed. Fugiat repellat harum assumenda sed illo voluptatem nobis fugit. At vero consequatur ut dignissimos. Et inventore ipsam ullam ullam dolor debitis quo saepe.",
- created: "2013-06-17T03:02:15+02:00",
- modified: "2021-12-09T12:01:33+01:00",
- modifiedBy: "",
- createdBy: "",
- resources: {
- admin: "http://www.ratke.com/libero-provident-nihil-minus-alias",
- schema: "http://murazik.biz/",
- component:
- "http://kuhlman.biz/inventore-iure-tempora-perspiciatis-repudiandae-numquam-veniam-sequi-dolorem.html",
- assets: {
- type: "css",
- url: "http://dibbert.biz/eius-et-non-autem",
- },
- options: {
- fade: true,
- },
- content: {
- text: "Praesentium at porro aut corporis quis in quia asperiores sed sit.",
- },
- },
- },
- ],
- "hydra:totalItems": 12,
- };
+ await loginTest(page);
- await route.fulfill({ json });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.locator("h1").getByText("Opret nyt slide")).toBeVisible();
+ await fulfillDataRoute(page, "**/templates*", templatesListJson);
+ await fulfillEmptyRoutes(page, ["**/playlists*", "**/themes*"]);
+
+ await page.getByLabel("Tilføj nyt slide").first().click();
+ await expect(page.getByText("Opret nyt slide:")).toBeVisible();
});
test("It loads create slide page", async ({ page }) => {
@@ -132,15 +22,7 @@ test.describe("Create slide page works", () => {
});
test("It display error toast on save error", async ({ page }) => {
- await page.route("**/slides", async (route) => {
- const json = {
- "@context": "/contexts/Error",
- "@type": "hydra:Error",
- "hydra:title": "An error occurred",
- "hydra:description": "An error occurred",
- };
- await route.fulfill({ status: 500, json });
- });
+ await fulfillDataRoute(page, "**/slides", errorJson, 500);
// Displays error toast and stays on page
await expect(
@@ -163,333 +45,23 @@ test.describe("Create slide page works", () => {
});
});
-test.describe("Slides list works", () => {
+test.describe("Slides list", () => {
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/slide/list");
- await page.route("**/slides*", async (route) => {
- const json = {
- "@id": "/v2/slides",
- "hydra:member": [
- {
- "@id": "/v2/slides/0086TQQC671WHA1S150MMF1Q3T",
- title: "Adipisci vero quia.",
- description:
- "Dolores porro ex sed consectetur dolorem aspernatur. Recusandae voluptatem non a aut. Tenetur optio aut fugit reprehenderit. Non dolorum temporibus possimus iure aut quas.",
- created: "1978-12-11T09:47:36.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/00MWCNKC4P0X5C0AT70E741E2V",
- options: [],
- },
- theme: "",
- onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
- duration: 70592,
- published: {
- from: null,
- to: "1989-08-28T18:14:52.000Z",
- },
- media: ["/v2/media/00W2E6VC0V22QK1WYH0CMP151C"],
- },
- {
- "@id": "/v2/slides/00BEFT32281WT51SNJ0JXA11AV",
- title: "Alias et id consequatur.",
- description:
- "Beatae reiciendis provident eos est totam repudiandae molestiae. Qui itaque officiis quibusdam. A nisi minus dolorum excepturi. Atque molestiae non velit ipsum consequatur nisi.",
- created: "1982-06-21T15:09:47.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/00PXXK8ND01SRF18YH1WN004VA",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
- onPlaylists: [],
- duration: 40787,
- published: {
- from: "2021-03-12T18:12:47.000Z",
- to: "2021-05-20T08:42:21.000Z",
- },
- media: [
- "/v2/media/0010X8D6JJ03G50T1J1FCW1XH6",
- "/v2/media/0043AB9VWE08071MNB08Q20JSG",
- "/v2/media/009RGQK5AD19K21CZE11HC1DPX",
- "/v2/media/00HM3QQ61107C41D7M0W2B1CEK",
- "/v2/media/01BTDHQH3Z06N40M9V0TJ41YA8",
- ],
- },
- {
- "@id": "/v2/slides/00BCX948J60YCR1TC009A31MPQ",
- title: "Amet impedit eum quia quo.",
- description:
- "Quis nostrum voluptatum quam aut sint enim. Ut sed occaecati deserunt accusantium. Cupiditate et voluptatum ex quidem. Nobis rerum consequatur fugiat occaecati voluptas et.",
- created: "1982-06-02T00:11:19.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 4902,
- published: {
- from: null,
- to: null,
- },
- media: [
- "/v2/media/00007SBZ470CJ60C7J06H508R8",
- "/v2/media/004MDCEC451GPJ1DW80D1Z026F",
- ],
- },
- {
- "@id": "/v2/slides/000AGMKXFZ0QWX0V5013R80S3S",
- title: "Aperiam maxime autem.",
- description:
- "Ea laboriosam rerum voluptatem. Quos odit veniam cum. Quia non expedita non facere id eum nesciunt. Fugit dolorum ipsa aspernatur.",
- created: "1970-05-11T17:45:13.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/018A0WH44D0X1N176Z16CC0HJP",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 85133,
- published: {
- from: "2021-08-13T23:56:36.000Z",
- to: null,
- },
- media: [
- "/v2/media/00CGESC8E10CZA11EV2AYR1KWC",
- "/v2/media/00HM3QQ61107C41D7M0W2B1CEK",
- "/v2/media/01DCA32QJY1BH600BV2H140JDK",
- ],
- },
- {
- "@id": "/v2/slides/014FR06WMH05WP17B71Q6Z1K7R",
- title: "Architecto dolores facilis et.",
- description:
- "Aspernatur doloremque et perferendis dolorum hic. Ab vel praesentium non pariatur. Omnis ut magni voluptas et. Ducimus harum sed beatae labore.",
- created: "2009-09-25T07:04:00.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/00HH42EEHC05QT14VQ041R1KEY",
- options: [],
- },
- theme: "",
- onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
- duration: 11240,
- published: {
- from: "2020-12-24T06:17:03.000Z",
- to: null,
- },
- media: ["/v2/media/000NDA6BBM1A071RNN0SP40XNJ"],
- },
- {
- "@id": "/v2/slides/00J96KHGSC1HPH0VHW1FSX0CVD",
- title: "Assumenda quaerat sint nihil perspiciatis.",
- description:
- "Eaque quaerat voluptas vitae rerum numquam dolore explicabo. Quas error voluptates quo est vel. Odit cum illum qui aut iure ipsum officiis.",
- created: "1989-11-29T16:39:50.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/001R8FR6VC10G51B200TK60QP3",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YN",
- onPlaylists: [],
- duration: 81995,
- published: {
- from: "2021-11-26T14:53:28.000Z",
- to: null,
- },
- media: [
- "/v2/media/009H64MSPN1HEH0DTV2DEV085B",
- "/v2/media/00H1A2WZ1A06BK0W781ETS1EXZ",
- "/v2/media/01BBCV60M903YC07RP09VN1JBZ",
- ],
- },
- {
- "@id": "/v2/slides/00FTMVQRPS18QD0MBY0RQ30FP0",
- title: "Atque nulla explicabo beatae.",
- description:
- "Repudiandae sapiente voluptatibus dolores voluptatem. Recusandae quia iste voluptates tempora fuga aliquam aut hic.",
- created: "1987-03-29T10:52:22.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01F8MJT0AV24D602FN131008YY",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0Y9",
- onPlaylists: [],
- duration: 32646,
- published: {
- from: "2021-09-04T10:08:04.000Z",
- to: "2021-10-27T01:46:23.000Z",
- },
- media: [
- "/v2/media/000NDA6BBM1A071RNN0SP40XNJ",
- "/v2/media/003M4E1AQG052J0HPM1X670P4F",
- "/v2/media/009RF9AGF80QP60ECM0CY01A1Y",
- "/v2/media/00QWNXTD5X0VSF1EWQ1H7H0YS2",
- ],
- },
- {
- "@id": "/v2/slides/008J6BKZMA0YHM04S813NF0DZV",
- title: "Atque quis aut qui veritatis.",
- description:
- "Dolore expedita labore praesentium beatae. Labore maiores est voluptates cupiditate praesentium. Maiores est dolorem iusto.",
- created: "1979-05-01T14:59:35.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/011763DN4P0FRS1T6B09180KCW",
- options: [],
- },
- theme: "",
- onPlaylists: ["/v2/playlists/01EDTHWKBM0TR3035E0Z631B8E"],
- duration: 86942,
- published: {
- from: "2020-12-26T12:37:10.000Z",
- to: null,
- },
- media: [
- "/v2/media/00JBVT18N31VBA0S3805CN03MC",
- "/v2/media/016SXZGDJR0T321KYJ19B91N1Z",
- "/v2/media/01795VPQZX0GNM00T11JJ71BS8",
- ],
- },
- {
- "@id": "/v2/slides/0118GD1EXJ1CSM1BHW0P7K1KQG",
- title: "Aut odio illum et.",
- description:
- "Voluptatibus dicta dolor suscipit eos. Voluptate atque quia quo blanditiis sint est odio. Voluptatum expedita ipsa ut et placeat laborum. Modi molestias quibusdam sunt ratione nulla sit.",
- created: "2006-03-22T07:17:31.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/000AT4BWMM1GJZ17WE1M9M0RFB",
- options: [],
- },
- theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
- onPlaylists: [],
- duration: 104864,
- published: {
- from: "2021-03-27T10:02:38.000Z",
- to: null,
- },
- media: [
- "/v2/media/002B3H5Z2K10M211AK1ERC02PM",
- "/v2/media/00XA10EH8H0YYY1H4B1CC40SSA",
- ],
- },
- {
- "@id": "/v2/slides/0151GSJGTE1JSE032C14JR0CQ2",
- title: "Aut qui placeat consequatur aut.",
- description:
- "Officiis sit adipisci exercitationem ut vero nihil iste voluptas. Temporibus aut saepe rerum sint. Soluta perferendis aliquid voluptatem eos.",
- created: "2010-05-04T04:35:53.000Z",
- modified: "2021-12-09T12:01:33.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01F8MJT0AV24D602FN131008YY",
- options: [],
- },
- theme: "",
- onPlaylists: [],
- duration: 28141,
- published: {
- from: "2020-12-14T13:20:43.000Z",
- to: "2021-02-11T10:45:45.000Z",
- },
- media: [
- "/v2/media/00KXYB7Z291JXC1SY30G161HQD",
- "/v2/media/01ENQN7X2F0ANK1BNA0J3513JX",
- ],
- },
- ],
- "hydra:totalItems": 100,
- };
- await route.fulfill({ json });
- });
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
-
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
+ await beforeEachTest(page);
});
- test("It loads slides list", async ({ page }) => {
- await expect(page.locator("table").locator("tbody")).not.toBeEmpty();
- await expect(page.locator("tbody").locator("tr td").first()).toBeVisible();
- });
+ test.beforeEach(async ({ page }) => {
+ await loginTest(page);
- test("It goes to edit (slides list)", async ({ page }) => {
- await page.route("**/slides/*", async (route) => {
- const json = {
- "@id": "/v2/slides/000622HP9N1G5P1CMD035H159G",
- title: "Aut consequatur excepturi ut totam aspernatur.",
- description:
- "Et aut harum aut est. Et hic et totam. Possimus veritatis nemo sit repellat dolorem. Distinctio id voluptates laborum voluptas voluptas repellat.",
- created: "1970-03-17T08:57:16.000Z",
- modified: "2022-01-30T15:42:42.000Z",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/00EPSCBVJS0TB0118C1JPM1VPM",
- options: [],
- },
- theme: "/v2/themes/01FTNTE789TEPTT7MC3TYM91JJ",
- onPlaylists: [],
- duration: 9834,
- published: {
- from: "2021-06-02T16:19:12.000Z",
- to: "2021-06-14T01:24:17.000Z",
- },
- media: ["/v2/media/014BH0252D18481TYB050J1WD9"],
- content: [],
- feed: null,
- };
- await route.fulfill({ json });
- });
+ await fulfillDataRoute(page, "**/templates*", templatesListJson);
+ await fulfillDataRoute(page, "**/templates/*", emptyJson);
+ await fulfillDataRoute(page, "**/slides*", slidesListJson);
+ await fulfillEmptyRoutes(page, ["**/playlists*", "**/themes*"]);
- await expect(page.locator("#slidesTitle")).not.toBeVisible();
- await page.locator("tbody").locator("#edit_button").nth(0).click();
- await expect(page.locator("#slidesTitle")).toBeVisible();
+ await page.getByLabel("Tilføj nyt slide").first().click();
+ await expect(page.getByText("Opret nyt slide:")).toBeVisible();
+ await page.getByRole("link", { name: "Slides" }).first().click();
+ await expect(page.getByRole("heading", { name: "Slides" })).toBeVisible();
});
test("The correct amount of column headers loaded", async ({ page }) => {
@@ -498,11 +70,11 @@ test.describe("Slides list works", () => {
test("It removes all selected", async ({ page }) => {
await page.locator("tbody").locator("tr td input").nth(0).click();
- expect(
+ await expect(
page.locator("tbody").locator("tr").nth(0).getByRole("checkbox"),
).toBeChecked();
await page.locator("#clear-rows-button").click();
- expect(
+ await expect(
page.locator("tbody").locator("tr").nth(0).getByRole("checkbox"),
).not.toBeChecked();
});
diff --git a/assets/tests/admin/admin-theme.spec.js b/assets/tests/admin/admin-theme.spec.js
index f999b391..5aa19d05 100644
--- a/assets/tests/admin/admin-theme.spec.js
+++ b/assets/tests/admin/admin-theme.spec.js
@@ -1,331 +1,30 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest } from "./test-helper.js";
+import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import { errorJson, feedSourcesJson2, screensListJson, themesJson, themesSingleJson } from "./data-fixtures.js";
-const themesJson = {
- "@context": "/contexts/Theme",
- "@id": "/v2/themes",
- "@type": "hydra:Collection",
- "hydra:member": [
- {
- "@type": "Theme",
- "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQB",
- title: "Consequatur quisquam recusandae asperiores accusamus.",
- description:
- "Occaecati debitis et saepe eum sint dolorem. Enim ipsum inventore sed libero et velit qui suscipit. Deserunt laudantium quibusdam enim nostrum soluta qui ipsam non.",
- onSlides: [],
- created: "2022-01-30T15:42:42+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- css: "",
- },
- {
- "@type": "Theme",
- "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
- title: "Sit vitae voluptas sint non.",
- description:
- "Optio quos qui illo error. Laborum vero a officia id corporis. Saepe provident esse hic eligendi. Culpa ut ab voluptas sed a.",
- onSlides: [
- {
- "@type": "Slide",
- "@id": "/v2/slides/007ZR8C9811R741WAP1KHK0T09",
- title: "Mollitia iure culpa exercitationem.",
- description:
- "Facilis nihil minus vel eum. Ut corrupti dicta quo modi temporibus est.",
- created: "1978-09-14T10:51:02+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
- onPlaylists: [],
- duration: 92789,
- published: {
- from: "2021-08-04T05:24:19+02:00",
- to: "2021-11-14T19:59:53+01:00",
- },
- media: ["/v2/media/00MTYFFTN30XNZ0F350YM31TN5"],
- content: [],
- feed: null,
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00GYC65JP01DEG1F6H0R5Q0JBA",
- title: "Voluptatem recusandae hic.",
- description:
- "Nulla occaecati praesentium quia magni ipsum dolor. Et aliquid natus molestiae ut quis. Ad voluptatum qui consequatur deleniti labore est. Voluptas hic veritatis quidem molestias qui.",
- created: "1988-06-15T11:26:36+02:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
- onPlaylists: [],
- duration: 78938,
- published: {
- from: "2021-10-09T12:14:12+02:00",
- to: "2021-12-24T16:18:08+01:00",
- },
- media: [
- "/v2/media/00YB5658GH0TAE1A1N0XBB0YR7",
- "/v2/media/01CVTNA9Y917EX09MY0FNX0GKA",
- "/v2/media/01E4S5SPXR19MP1KGY16TD1XG2",
- ],
- content: [],
- feed: null,
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00V28394SD1WBY1BPE1STN13MD",
- title: "Reprehenderit neque nam mollitia quia.",
- description:
- "Omnis aliquam ea architecto dignissimos. Harum provident asperiores neque consequatur sit sed. Quasi ipsa illum et qui deleniti quo.",
- created: "1999-06-23T10:05:00+02:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
- onPlaylists: [],
- duration: 69299,
- published: {
- from: "2021-06-09T03:25:34+02:00",
- to: "2021-11-05T02:30:21+01:00",
- },
- media: ["/v2/media/0041NS3DFY1EMS0XGQ025B0425"],
- content: [],
- feed: null,
- },
- ],
- created: "2022-01-30T15:42:42+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- css: "",
- },
- {
- "@type": "Theme",
- "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
- title: "Enim ex eveniet facere.",
- description:
- "Delectus aut nam et eum. Fugit repellendus illo veritatis. Ex esse veritatis voluptate vel possimus. Aut incidunt sunt cumque asperiores incidunt iure sequi.",
- onSlides: [
- {
- "@type": "Slide",
- "@id": "/v2/slides/003VYYZPPN1MQ61MEM1TE10G2J",
- title: "Quos ducimus culpa consequuntur nulla aliquid.",
- description:
- "At quia quia voluptatibus eius. Delectus quia consequuntur aut nihil. Impedit sit aut dolorum aut dolore. Dolore beatae ipsa voluptas.",
- created: "1974-03-21T14:49:33+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
- onPlaylists: ["/v2/playlists/00XVQEW1EV0N3K0JZQ0TYS0T1G"],
- duration: 77194,
- published: {
- from: "2021-07-02T08:33:02+02:00",
- to: "2022-03-12T20:52:07+01:00",
- },
- media: [
- "/v2/media/00GEQ02WW10SZ21F9G1MAZ0KR8",
- "/v2/media/00MTYFFTN30XNZ0F350YM31TN5",
- "/v2/media/00SSYSBFHR16PM09MQ0B0K0202",
- "/v2/media/00X6A9GBZM0EHF05AA0B350D8E",
- ],
- content: [],
- feed: null,
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00EBKSK8ZZ0Y301VFR0WGQ05F4",
- title: "Maiores repudiandae quibusdam et rerum.",
- description:
- "At totam ut animi nisi ut ut qui. Aspernatur omnis quod temporibus non quo numquam. Dignissimos non eius numquam neque. Numquam modi tempora minus ad aut aut sit.",
- created: "1985-08-21T22:37:57+02:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/0044JYNRTJ1KD0128318R80B3Q",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
- onPlaylists: [],
- duration: 66516,
- published: {
- from: "2021-08-30T14:57:29+02:00",
- to: "2021-10-24T12:24:48+02:00",
- },
- media: ["/v2/media/00031XCV6Z1W860V5R0SXB0D6R"],
- content: [],
- feed: null,
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00VRS9JQ7C1BZZ1NBA1XE50E19",
- title: "Doloremque cum aliquam quis sint.",
- description:
- "Est quos beatae voluptatem optio et sit. Culpa fugiat quam et quisquam error a. Aut molestias quaerat quia aut non ipsum autem. Sunt aspernatur eos dolores quas alias. Culpa aut maiores consectetur.",
- created: "2000-03-29T12:07:31+02:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
- onPlaylists: [],
- duration: 28295,
- published: {
- from: "2022-03-18T13:47:21+01:00",
- to: "2022-03-19T12:34:17+01:00",
- },
- media: [
- "/v2/media/003NVKRN4E183T0C431JF7036P",
- "/v2/media/00C07KS3R00PEV24RF09870SH9",
- "/v2/media/0170X462SF1P3205JP1R6K0553",
- ],
- content: [],
- feed: null,
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/00X2XD9Y011VB31K2T10JW0NR1",
- title: "Eveniet repellendus et autem repellat.",
- description:
- "Rerum praesentium quo sequi. Accusamus fugiat voluptatem est quam. Esse voluptatem quia fugiat nisi delectus omnis.",
- created: "2001-09-04T01:28:51+02:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
- onPlaylists: ["/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P"],
- duration: 99209,
- published: {
- from: "2021-11-11T07:58:12+01:00",
- to: "2021-11-13T19:36:00+01:00",
- },
- media: [
- "/v2/media/00J8PGYF1N12T60T200QN50KKJ",
- "/v2/media/014S7FGP500Z8P18ZW12631TCP",
- "/v2/media/019PTTMBQB0Z2D05VQ0HVC1M5M",
- ],
- content: [],
- feed: null,
- },
- {
- "@type": "Slide",
- "@id": "/v2/slides/011KV2WHQS0NDK1Q1Q01GY0XPS",
- title: "Harum ducimus reiciendis.",
- description:
- "Est aut quis omnis. Cumque id officiis molestias accusamus est molestias. Nulla qui aut quo sunt et.",
- created: "2006-08-10T03:26:54+02:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- templateInfo: {
- "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
- options: [],
- },
- theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
- onPlaylists: [],
- duration: 7509,
- published: {
- from: "2021-07-22T07:48:05+02:00",
- to: "2021-09-03T23:11:43+02:00",
- },
- media: [
- "/v2/media/008ARWMTYJ0SX810490JQQ0DAK",
- "/v2/media/00E98GAQXH1Y2C1G131MVH0YWZ",
- "/v2/media/00MTYFFTN30XNZ0F350YM31TN5",
- "/v2/media/0142VZYZ7H0XHE1XJB1M730VGS",
- "/v2/media/015H8MEPVH13BE15A11MHJ0KAM",
- ],
- content: [],
- feed: null,
- },
- ],
- created: "2022-01-30T15:42:42+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- css: "",
- },
- ],
- "hydra:totalItems": 20,
-};
-
-test.describe("Theme pages work", () => {
+test.describe("Theme", () => {
test.beforeEach(async ({ page }) => {
await beforeEachTest(page);
});
test.beforeEach(async ({ page }) => {
- await page.goto("/admin/themes/list");
- await page.route("**/themes*", async (route) => {
- await route.fulfill({ json: themesJson });
- });
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- await expect(page.locator("h1").getByText("Temaer")).toBeVisible();
+ await loginTest(page);
+
+ await fulfillDataRoute(page, "**/themes*", themesJson);
+// await fulfillEmptyRoutes(page, ["**/campaigns*", "**/screen-groups*", "**/layouts*"]);
+
+ await page.getByRole("link", { name: "Temaer", exact: true }).click();
+ await expect(page.getByRole("heading", { name: "Temaer", exact: true })).toBeVisible();
});
test("It loads create theme page", async ({ page }) => {
- page.getByText("Opret nyt tema").click();
+ await page.getByText("Opret nyt tema").click();
await expect(page.locator("#save_theme")).toBeVisible();
});
test("It display error toast on save error", async ({ page }) => {
- await page.route("**/themes", async (route) => {
- const json = {
- "@context": "/contexts/Error",
- "@type": "hydra:Error",
- "hydra:title": "An error occurred",
- "hydra:description": "An error occurred",
- };
- await route.fulfill({ status: 500, json });
- });
- page.getByText("Opret nyt tema").click();
+ await fulfillDataRoute(page, "**/themes", errorJson, 500);
+ await page.getByText("Opret nyt tema").click();
// Displays error toast and stays on page
await expect(
@@ -346,43 +45,11 @@ test.describe("Theme pages work", () => {
});
test("It cancels create theme", async ({ page }) => {
- page.getByText("Opret nyt tema").click();
+ await page.getByText("Opret nyt tema").click();
await expect(page.locator("#cancel_theme")).toBeVisible();
await page.locator("#cancel_theme").click();
await expect(page.locator("#cancel_theme")).not.toBeVisible();
});
-});
-
-test.describe("Themes list work", () => {
- test.beforeEach(async ({ page }) => {
- await page.goto("/admin/themes/list");
- await page.route("**/token", async (route) => {
- const json = {
- token: "1",
- refresh_token: "2",
- tenants: [
- {
- tenantKey: "ABC",
- title: "ABC Tenant",
- description: "Description",
- roles: ["ROLE_ADMIN"],
- },
- ],
- user: {
- fullname: "John Doe",
- email: "johndoe@example.com",
- },
- };
- await route.fulfill({ json });
- });
- await page.route("**/themes*", async (route) => {
- await route.fulfill({ json: themesJson });
- });
- await expect(page).toHaveTitle(/OS2Display Admin/);
- await page.getByLabel("Email").fill("johndoe@example.com");
- await page.getByLabel("Kodeord").fill("password");
- await page.locator("#login").click();
- });
test("It loads themes list", async ({ page }) => {
await expect(page.locator("table").locator("tbody")).not.toBeEmpty();
@@ -392,61 +59,7 @@ test.describe("Themes list work", () => {
test("It goes to edit", async ({ page }) => {
await expect(page.locator("#themeTitle")).not.toBeVisible();
- await page.route("**/themes*", async (route) => {
- const json = {
- "@context": "/contexts/Theme",
- "@id": "/v2/themes",
- "@type": "hydra:Collection",
- "hydra:member": [
- {
- "@type": "Theme",
- "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQB",
- title: "Consequatur quisquam recusandae asperiores accusamus.",
- description:
- "Occaecati debitis et saepe eum sint dolorem. Enim ipsum inventore sed libero et velit qui suscipit. Deserunt laudantium quibusdam enim nostrum soluta qui ipsam non.",
- onSlides: [],
- created: "2022-01-30T15:42:42+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- css: "",
- },
- {
- "@type": "Theme",
- "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
- title: "Sit vitae voluptas sint non.",
- description:
- "Optio quos qui illo error. Laborum vero a officia id corporis. Saepe provident esse hic eligendi. Culpa ut ab voluptas sed a.",
- onSlides: [],
- created: "2022-01-30T15:42:42+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- css: "",
- },
- ],
- "hydra:totalItems": 2,
- };
- await route.fulfill({ json });
- });
-
- await page.route("**/themes/*", async (route) => {
- const json = {
- "@type": "Theme",
- "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQN",
- title: "Hic minus et omnis porro.",
- description:
- "Odit quia nisi accusantium natus. Ut explicabo corporis eligendi ut. Sapiente ut qui quidem explicabo optio amet velit aut. Iure sed alias asperiores perspiciatis deserunt omnis inventore mollitia.",
- onSlides: [],
- created: "2022-01-30T15:42:42+01:00",
- modified: "2022-01-30T15:42:42+01:00",
- modifiedBy: "",
- createdBy: "",
- css: "",
- };
-
- await route.fulfill({ json });
- });
+ await fulfillDataRoute(page, "**/themes/*", themesSingleJson);
await page.locator("tbody").locator("tr td a").first().click();
await expect(page.locator("#themeTitle")).toBeVisible();
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index d5857698..cf0533ac 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -1,5 +1,5 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, loginTest } from "./test-helper.js";
+import { beforeEachTest, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
import { emptyJson } from "./data-fixtures.js";
test.describe("Nav items loads", () => {
@@ -8,7 +8,7 @@ test.describe("Nav items loads", () => {
});
test.beforeEach(async ({ page }) => {
- await loginTest({ page });
+ await loginTest(page);
});
test("It loads", async ({ page }) => {
@@ -95,6 +95,8 @@ test.describe("Nav items loads", () => {
});
test("It navigates to create screen", async ({ page }) => {
+ await fulfillEmptyRoutes(page, ["**/screen-groups*", "**/layouts*"]);
+
await page.getByLabel("Tilføj ny skærm").first().click();
await expect(page.locator("h1")).toHaveText("Opret ny skærm");
});
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index c3a0eb4f..d37a2d98 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -1007,6 +1007,642 @@ const screensListJson = {
],
};
+const templatesListJson = {
+ "@id": "/v2/templates",
+ "hydra:member": [
+ {
+ "@type": "Template",
+ "@id": "/v2/templates/00XZXR5XDH0D1M16K10NYQ0A55",
+ title: "Est totam provident sunt.",
+ description:
+ "Tempora qui minus officia quis consequuntur voluptates. Quasi minima eveniet repudiandae laborum dolor quasi totam qui. Iusto enim inventore molestias amet aut.",
+ created: "2002-08-30T14:14:07+02:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ resources: {
+ admin:
+ "http://www.harber.com/atque-inventore-consequatur-mollitia-ducimus-veritatis-doloribus-ad",
+ schema: "http://www.kulas.net/quia-unde-quos-error-modi-saepe",
+ component: "http://keebler.com/",
+ assets: {
+ type: "css",
+ url: "https://www.borer.biz/voluptas-blanditiis-et-quo-aut-culpa-reiciendis-dolorum",
+ },
+ options: {
+ fade: true,
+ },
+ content: {
+ text: "Accusantium exercitationem animi qui provident ipsa distinctio.",
+ },
+ },
+ },
+ {
+ "@type": "Template",
+ "@id": "/v2/templates/016MHSNKCH1PQW1VY615JC19Y3",
+ title: "Ut exercitationem est quia ad quas.",
+ description:
+ "Laborum quod ut ducimus suscipit quia nostrum. Saepe ex voluptas aut. Sit numquam vel est sunt. Cupiditate excepturi non saepe in voluptatem vel rem quaerat. Magni aut eaque vel deleniti.",
+ created: "2012-01-28T09:17:22+01:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ resources: {
+ admin:
+ "https://vandervort.com/sapiente-quo-est-rerum-nihil-sint-placeat-ipsa-id.html",
+ schema:
+ "http://www.gulgowski.com/debitis-voluptatem-earum-sed-totam-aut-impedit-facere",
+ component:
+ "https://lehner.com/officia-ducimus-ea-beatae-eum-amet-provident-sint.html",
+ assets: {
+ type: "css",
+ url: "http://www.emmerich.net/aliquam-excepturi-id-et-ab-voluptate.html",
+ },
+ options: {
+ fade: true,
+ },
+ content: {
+ text: "Ut qui assumenda ex vel quod dolorem perspiciatis eos quis.",
+ },
+ },
+ },
+ {
+ "@type": "Template",
+ "@id": "/v2/templates/017X81AEJV2GJE0NC51KKK0EK8",
+ title: "Delectus magnam repudiandae molestiae et a.",
+ description:
+ "Consequuntur est ut commodi sed. Fugiat repellat harum assumenda sed illo voluptatem nobis fugit. At vero consequatur ut dignissimos. Et inventore ipsam ullam ullam dolor debitis quo saepe.",
+ created: "2013-06-17T03:02:15+02:00",
+ modified: "2021-12-09T12:01:33+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ resources: {
+ admin: "http://www.ratke.com/libero-provident-nihil-minus-alias",
+ schema: "http://murazik.biz/",
+ component:
+ "http://kuhlman.biz/inventore-iure-tempora-perspiciatis-repudiandae-numquam-veniam-sequi-dolorem.html",
+ assets: {
+ type: "css",
+ url: "http://dibbert.biz/eius-et-non-autem",
+ },
+ options: {
+ fade: true,
+ },
+ content: {
+ text: "Praesentium at porro aut corporis quis in quia asperiores sed sit.",
+ },
+ },
+ },
+ ],
+ "hydra:totalItems": 12,
+};
+
+const slidesListJson = {
+ "@id": "/v2/slides",
+ "hydra:member": [
+ {
+ "@id": "/v2/slides/0086TQQC671WHA1S150MMF1Q3T",
+ title: "Adipisci vero quia.",
+ description:
+ "Dolores porro ex sed consectetur dolorem aspernatur. Recusandae voluptatem non a aut. Tenetur optio aut fugit reprehenderit. Non dolorum temporibus possimus iure aut quas.",
+ created: "1978-12-11T09:47:36.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/00MWCNKC4P0X5C0AT70E741E2V",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
+ duration: 70592,
+ published: {
+ from: null,
+ to: "1989-08-28T18:14:52.000Z",
+ },
+ media: ["/v2/media/00W2E6VC0V22QK1WYH0CMP151C"],
+ },
+ {
+ "@id": "/v2/slides/00BEFT32281WT51SNJ0JXA11AV",
+ title: "Alias et id consequatur.",
+ description:
+ "Beatae reiciendis provident eos est totam repudiandae molestiae. Qui itaque officiis quibusdam. A nisi minus dolorum excepturi. Atque molestiae non velit ipsum consequatur nisi.",
+ created: "1982-06-21T15:09:47.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/00PXXK8ND01SRF18YH1WN004VA",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
+ onPlaylists: [],
+ duration: 40787,
+ published: {
+ from: "2021-03-12T18:12:47.000Z",
+ to: "2021-05-20T08:42:21.000Z",
+ },
+ media: [
+ "/v2/media/0010X8D6JJ03G50T1J1FCW1XH6",
+ "/v2/media/0043AB9VWE08071MNB08Q20JSG",
+ "/v2/media/009RGQK5AD19K21CZE11HC1DPX",
+ "/v2/media/00HM3QQ61107C41D7M0W2B1CEK",
+ "/v2/media/01BTDHQH3Z06N40M9V0TJ41YA8",
+ ],
+ },
+ {
+ "@id": "/v2/slides/00BCX948J60YCR1TC009A31MPQ",
+ title: "Amet impedit eum quia quo.",
+ description:
+ "Quis nostrum voluptatum quam aut sint enim. Ut sed occaecati deserunt accusantium. Cupiditate et voluptatum ex quidem. Nobis rerum consequatur fugiat occaecati voluptas et.",
+ created: "1982-06-02T00:11:19.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/000YR9PMQC0GMC1TP90V9N07WX",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 4902,
+ published: {
+ from: null,
+ to: null,
+ },
+ media: [
+ "/v2/media/00007SBZ470CJ60C7J06H508R8",
+ "/v2/media/004MDCEC451GPJ1DW80D1Z026F",
+ ],
+ },
+ {
+ "@id": "/v2/slides/000AGMKXFZ0QWX0V5013R80S3S",
+ title: "Aperiam maxime autem.",
+ description:
+ "Ea laboriosam rerum voluptatem. Quos odit veniam cum. Quia non expedita non facere id eum nesciunt. Fugit dolorum ipsa aspernatur.",
+ created: "1970-05-11T17:45:13.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/018A0WH44D0X1N176Z16CC0HJP",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 85133,
+ published: {
+ from: "2021-08-13T23:56:36.000Z",
+ to: null,
+ },
+ media: [
+ "/v2/media/00CGESC8E10CZA11EV2AYR1KWC",
+ "/v2/media/00HM3QQ61107C41D7M0W2B1CEK",
+ "/v2/media/01DCA32QJY1BH600BV2H140JDK",
+ ],
+ },
+ {
+ "@id": "/v2/slides/014FR06WMH05WP17B71Q6Z1K7R",
+ title: "Architecto dolores facilis et.",
+ description:
+ "Aspernatur doloremque et perferendis dolorum hic. Ab vel praesentium non pariatur. Omnis ut magni voluptas et. Ducimus harum sed beatae labore.",
+ created: "2009-09-25T07:04:00.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/00HH42EEHC05QT14VQ041R1KEY",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: ["/v2/playlists/00S7ZQK8Y90R351YES1DJN0RKR"],
+ duration: 11240,
+ published: {
+ from: "2020-12-24T06:17:03.000Z",
+ to: null,
+ },
+ media: ["/v2/media/000NDA6BBM1A071RNN0SP40XNJ"],
+ },
+ {
+ "@id": "/v2/slides/00J96KHGSC1HPH0VHW1FSX0CVD",
+ title: "Assumenda quaerat sint nihil perspiciatis.",
+ description:
+ "Eaque quaerat voluptas vitae rerum numquam dolore explicabo. Quas error voluptates quo est vel. Odit cum illum qui aut iure ipsum officiis.",
+ created: "1989-11-29T16:39:50.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/001R8FR6VC10G51B200TK60QP3",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YN",
+ onPlaylists: [],
+ duration: 81995,
+ published: {
+ from: "2021-11-26T14:53:28.000Z",
+ to: null,
+ },
+ media: [
+ "/v2/media/009H64MSPN1HEH0DTV2DEV085B",
+ "/v2/media/00H1A2WZ1A06BK0W781ETS1EXZ",
+ "/v2/media/01BBCV60M903YC07RP09VN1JBZ",
+ ],
+ },
+ {
+ "@id": "/v2/slides/00FTMVQRPS18QD0MBY0RQ30FP0",
+ title: "Atque nulla explicabo beatae.",
+ description:
+ "Repudiandae sapiente voluptatibus dolores voluptatem. Recusandae quia iste voluptates tempora fuga aliquam aut hic.",
+ created: "1987-03-29T10:52:22.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01F8MJT0AV24D602FN131008YY",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0Y9",
+ onPlaylists: [],
+ duration: 32646,
+ published: {
+ from: "2021-09-04T10:08:04.000Z",
+ to: "2021-10-27T01:46:23.000Z",
+ },
+ media: [
+ "/v2/media/000NDA6BBM1A071RNN0SP40XNJ",
+ "/v2/media/003M4E1AQG052J0HPM1X670P4F",
+ "/v2/media/009RF9AGF80QP60ECM0CY01A1Y",
+ "/v2/media/00QWNXTD5X0VSF1EWQ1H7H0YS2",
+ ],
+ },
+ {
+ "@id": "/v2/slides/008J6BKZMA0YHM04S813NF0DZV",
+ title: "Atque quis aut qui veritatis.",
+ description:
+ "Dolore expedita labore praesentium beatae. Labore maiores est voluptates cupiditate praesentium. Maiores est dolorem iusto.",
+ created: "1979-05-01T14:59:35.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/011763DN4P0FRS1T6B09180KCW",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: ["/v2/playlists/01EDTHWKBM0TR3035E0Z631B8E"],
+ duration: 86942,
+ published: {
+ from: "2020-12-26T12:37:10.000Z",
+ to: null,
+ },
+ media: [
+ "/v2/media/00JBVT18N31VBA0S3805CN03MC",
+ "/v2/media/016SXZGDJR0T321KYJ19B91N1Z",
+ "/v2/media/01795VPQZX0GNM00T11JJ71BS8",
+ ],
+ },
+ {
+ "@id": "/v2/slides/0118GD1EXJ1CSM1BHW0P7K1KQG",
+ title: "Aut odio illum et.",
+ description:
+ "Voluptatibus dicta dolor suscipit eos. Voluptate atque quia quo blanditiis sint est odio. Voluptatum expedita ipsa ut et placeat laborum. Modi molestias quibusdam sunt ratione nulla sit.",
+ created: "2006-03-22T07:17:31.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/000AT4BWMM1GJZ17WE1M9M0RFB",
+ options: [],
+ },
+ theme: "/v2/themes/01FPFH3WX93S4575W6Q9T8K0YB",
+ onPlaylists: [],
+ duration: 104864,
+ published: {
+ from: "2021-03-27T10:02:38.000Z",
+ to: null,
+ },
+ media: [
+ "/v2/media/002B3H5Z2K10M211AK1ERC02PM",
+ "/v2/media/00XA10EH8H0YYY1H4B1CC40SSA",
+ ],
+ },
+ {
+ "@id": "/v2/slides/0151GSJGTE1JSE032C14JR0CQ2",
+ title: "Aut qui placeat consequatur aut.",
+ description:
+ "Officiis sit adipisci exercitationem ut vero nihil iste voluptas. Temporibus aut saepe rerum sint. Soluta perferendis aliquid voluptatem eos.",
+ created: "2010-05-04T04:35:53.000Z",
+ modified: "2021-12-09T12:01:33.000Z",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01F8MJT0AV24D602FN131008YY",
+ options: [],
+ },
+ theme: "",
+ onPlaylists: [],
+ duration: 28141,
+ published: {
+ from: "2020-12-14T13:20:43.000Z",
+ to: "2021-02-11T10:45:45.000Z",
+ },
+ media: [
+ "/v2/media/00KXYB7Z291JXC1SY30G161HQD",
+ "/v2/media/01ENQN7X2F0ANK1BNA0J3513JX",
+ ],
+ },
+ ],
+ "hydra:totalItems": 100,
+};
+
+const themesJson = {
+ "@context": "/contexts/Theme",
+ "@id": "/v2/themes",
+ "@type": "hydra:Collection",
+ "hydra:member": [
+ {
+ "@type": "Theme",
+ "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQB",
+ title: "Consequatur quisquam recusandae asperiores accusamus.",
+ description:
+ "Occaecati debitis et saepe eum sint dolorem. Enim ipsum inventore sed libero et velit qui suscipit. Deserunt laudantium quibusdam enim nostrum soluta qui ipsam non.",
+ onSlides: [],
+ created: "2022-01-30T15:42:42+01:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ css: "",
+ },
+ {
+ "@type": "Theme",
+ "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
+ title: "Sit vitae voluptas sint non.",
+ description:
+ "Optio quos qui illo error. Laborum vero a officia id corporis. Saepe provident esse hic eligendi. Culpa ut ab voluptas sed a.",
+ onSlides: [
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/007ZR8C9811R741WAP1KHK0T09",
+ title: "Mollitia iure culpa exercitationem.",
+ description:
+ "Facilis nihil minus vel eum. Ut corrupti dicta quo modi temporibus est.",
+ created: "1978-09-14T10:51:02+01:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
+ onPlaylists: [],
+ duration: 92789,
+ published: {
+ from: "2021-08-04T05:24:19+02:00",
+ to: "2021-11-14T19:59:53+01:00",
+ },
+ media: ["/v2/media/00MTYFFTN30XNZ0F350YM31TN5"],
+ content: [],
+ feed: null,
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00GYC65JP01DEG1F6H0R5Q0JBA",
+ title: "Voluptatem recusandae hic.",
+ description:
+ "Nulla occaecati praesentium quia magni ipsum dolor. Et aliquid natus molestiae ut quis. Ad voluptatum qui consequatur deleniti labore est. Voluptas hic veritatis quidem molestias qui.",
+ created: "1988-06-15T11:26:36+02:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/002BAP34VD1EHG0E4J0D2Y00JW",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
+ onPlaylists: [],
+ duration: 78938,
+ published: {
+ from: "2021-10-09T12:14:12+02:00",
+ to: "2021-12-24T16:18:08+01:00",
+ },
+ media: [
+ "/v2/media/00YB5658GH0TAE1A1N0XBB0YR7",
+ "/v2/media/01CVTNA9Y917EX09MY0FNX0GKA",
+ "/v2/media/01E4S5SPXR19MP1KGY16TD1XG2",
+ ],
+ content: [],
+ feed: null,
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00V28394SD1WBY1BPE1STN13MD",
+ title: "Reprehenderit neque nam mollitia quia.",
+ description:
+ "Omnis aliquam ea architecto dignissimos. Harum provident asperiores neque consequatur sit sed. Quasi ipsa illum et qui deleniti quo.",
+ created: "1999-06-23T10:05:00+02:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQC",
+ onPlaylists: [],
+ duration: 69299,
+ published: {
+ from: "2021-06-09T03:25:34+02:00",
+ to: "2021-11-05T02:30:21+01:00",
+ },
+ media: ["/v2/media/0041NS3DFY1EMS0XGQ025B0425"],
+ content: [],
+ feed: null,
+ },
+ ],
+ created: "2022-01-30T15:42:42+01:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ css: "",
+ },
+ {
+ "@type": "Theme",
+ "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
+ title: "Enim ex eveniet facere.",
+ description:
+ "Delectus aut nam et eum. Fugit repellendus illo veritatis. Ex esse veritatis voluptate vel possimus. Aut incidunt sunt cumque asperiores incidunt iure sequi.",
+ onSlides: [
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/003VYYZPPN1MQ61MEM1TE10G2J",
+ title: "Quos ducimus culpa consequuntur nulla aliquid.",
+ description:
+ "At quia quia voluptatibus eius. Delectus quia consequuntur aut nihil. Impedit sit aut dolorum aut dolore. Dolore beatae ipsa voluptas.",
+ created: "1974-03-21T14:49:33+01:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
+ onPlaylists: ["/v2/playlists/00XVQEW1EV0N3K0JZQ0TYS0T1G"],
+ duration: 77194,
+ published: {
+ from: "2021-07-02T08:33:02+02:00",
+ to: "2022-03-12T20:52:07+01:00",
+ },
+ media: [
+ "/v2/media/00GEQ02WW10SZ21F9G1MAZ0KR8",
+ "/v2/media/00MTYFFTN30XNZ0F350YM31TN5",
+ "/v2/media/00SSYSBFHR16PM09MQ0B0K0202",
+ "/v2/media/00X6A9GBZM0EHF05AA0B350D8E",
+ ],
+ content: [],
+ feed: null,
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00EBKSK8ZZ0Y301VFR0WGQ05F4",
+ title: "Maiores repudiandae quibusdam et rerum.",
+ description:
+ "At totam ut animi nisi ut ut qui. Aspernatur omnis quod temporibus non quo numquam. Dignissimos non eius numquam neque. Numquam modi tempora minus ad aut aut sit.",
+ created: "1985-08-21T22:37:57+02:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/0044JYNRTJ1KD0128318R80B3Q",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
+ onPlaylists: [],
+ duration: 66516,
+ published: {
+ from: "2021-08-30T14:57:29+02:00",
+ to: "2021-10-24T12:24:48+02:00",
+ },
+ media: ["/v2/media/00031XCV6Z1W860V5R0SXB0D6R"],
+ content: [],
+ feed: null,
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00VRS9JQ7C1BZZ1NBA1XE50E19",
+ title: "Doloremque cum aliquam quis sint.",
+ description:
+ "Est quos beatae voluptatem optio et sit. Culpa fugiat quam et quisquam error a. Aut molestias quaerat quia aut non ipsum autem. Sunt aspernatur eos dolores quas alias. Culpa aut maiores consectetur.",
+ created: "2000-03-29T12:07:31+02:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
+ onPlaylists: [],
+ duration: 28295,
+ published: {
+ from: "2022-03-18T13:47:21+01:00",
+ to: "2022-03-19T12:34:17+01:00",
+ },
+ media: [
+ "/v2/media/003NVKRN4E183T0C431JF7036P",
+ "/v2/media/00C07KS3R00PEV24RF09870SH9",
+ "/v2/media/0170X462SF1P3205JP1R6K0553",
+ ],
+ content: [],
+ feed: null,
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/00X2XD9Y011VB31K2T10JW0NR1",
+ title: "Eveniet repellendus et autem repellat.",
+ description:
+ "Rerum praesentium quo sequi. Accusamus fugiat voluptatem est quam. Esse voluptatem quia fugiat nisi delectus omnis.",
+ created: "2001-09-04T01:28:51+02:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/017BG9P0E0103F0TFS17FM016M",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
+ onPlaylists: ["/v2/playlists/007TM6JDGF1ECH07J10ZHY0S7P"],
+ duration: 99209,
+ published: {
+ from: "2021-11-11T07:58:12+01:00",
+ to: "2021-11-13T19:36:00+01:00",
+ },
+ media: [
+ "/v2/media/00J8PGYF1N12T60T200QN50KKJ",
+ "/v2/media/014S7FGP500Z8P18ZW12631TCP",
+ "/v2/media/019PTTMBQB0Z2D05VQ0HVC1M5M",
+ ],
+ content: [],
+ feed: null,
+ },
+ {
+ "@type": "Slide",
+ "@id": "/v2/slides/011KV2WHQS0NDK1Q1Q01GY0XPS",
+ title: "Harum ducimus reiciendis.",
+ description:
+ "Est aut quis omnis. Cumque id officiis molestias accusamus est molestias. Nulla qui aut quo sunt et.",
+ created: "2006-08-10T03:26:54+02:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ templateInfo: {
+ "@id": "/v2/templates/01FGC8EXSE1KCC1PTR0NHB0H3R",
+ options: [],
+ },
+ theme: "/v2/themes/01FTNTE788816N6YCW9NVM2JQD",
+ onPlaylists: [],
+ duration: 7509,
+ published: {
+ from: "2021-07-22T07:48:05+02:00",
+ to: "2021-09-03T23:11:43+02:00",
+ },
+ media: [
+ "/v2/media/008ARWMTYJ0SX810490JQQ0DAK",
+ "/v2/media/00E98GAQXH1Y2C1G131MVH0YWZ",
+ "/v2/media/00MTYFFTN30XNZ0F350YM31TN5",
+ "/v2/media/0142VZYZ7H0XHE1XJB1M730VGS",
+ "/v2/media/015H8MEPVH13BE15A11MHJ0KAM",
+ ],
+ content: [],
+ feed: null,
+ },
+ ],
+ created: "2022-01-30T15:42:42+01:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ css: "",
+ },
+ ],
+ "hydra:totalItems": 20,
+};
+
+const themesSingleJson = {
+ "@type": "Theme",
+ "@id": "/v2/themes/01FTNTE788816N6YCW9NVM2JQN",
+ title: "Hic minus et omnis porro.",
+ description:
+ "Odit quia nisi accusantium natus. Ut explicabo corporis eligendi ut. Sapiente ut qui quidem explicabo optio amet velit aut. Iure sed alias asperiores perspiciatis deserunt omnis inventore mollitia.",
+ onSlides: [],
+ created: "2022-01-30T15:42:42+01:00",
+ modified: "2022-01-30T15:42:42+01:00",
+ modifiedBy: "",
+ createdBy: "",
+ css: "",
+};
+
export {
tokenAdminJson,
tokenTenantsJson,
@@ -1027,4 +1663,8 @@ export {
screenGroupsListJson,
screenGroupsSingleJson,
screensListJson,
+ templatesListJson,
+ slidesListJson,
+ themesJson,
+ themesSingleJson,
};
diff --git a/assets/tests/admin/test-helper.js b/assets/tests/admin/test-helper.js
index a496d445..2324517e 100644
--- a/assets/tests/admin/test-helper.js
+++ b/assets/tests/admin/test-helper.js
@@ -44,7 +44,7 @@ const fulfillDataRoute = async (page, routePattern, data, status) => {
});
}
-const loginTest = async ({ page }) => {
+const loginTest = async (page) => {
await page.goto("/admin/slides/list");
await page.route("**/token", async (route) => {
From f33a1bdca9038907c8c2fd7863dc6fc254e4de90 Mon Sep 17 00:00:00 2001
From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com>
Date: Sat, 9 Aug 2025 07:20:07 +0200
Subject: [PATCH 30/30] 4565: Applied coding standards
---
assets/tests/admin/admin-campaign.spec.js | 13 +++++-
assets/tests/admin/admin-feed-sources.spec.js | 15 +++++--
assets/tests/admin/admin-login.spec.js | 11 ++++-
assets/tests/admin/admin-playlist.spec.js | 40 +++++++++++++------
.../tests/admin/admin-screen-groups.spec.js | 33 +++++++++++----
assets/tests/admin/admin-screens.spec.js | 23 +++++++++--
assets/tests/admin/admin-shared-list.spec.js | 15 +++++--
assets/tests/admin/admin-slides.spec.js | 14 ++++++-
assets/tests/admin/admin-theme.spec.js | 21 ++++++++--
assets/tests/admin/admin-top-bar.spec.js | 6 ++-
assets/tests/admin/data-fixtures.js | 20 +++++-----
assets/tests/admin/test-helper.js | 8 ++--
12 files changed, 163 insertions(+), 56 deletions(-)
diff --git a/assets/tests/admin/admin-campaign.spec.js b/assets/tests/admin/admin-campaign.spec.js
index 77cc185e..fcc15ee2 100644
--- a/assets/tests/admin/admin-campaign.spec.js
+++ b/assets/tests/admin/admin-campaign.spec.js
@@ -1,5 +1,10 @@
import { test, expect } from "@playwright/test";
-import { fulfillDataRoute, fulfillEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
+import {
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ beforeEachTest,
+ loginTest,
+} from "./test-helper.js";
import { slidesJson1 } from "./data-fixtures.js";
test.describe("Campaign pages work", () => {
@@ -10,7 +15,11 @@ test.describe("Campaign pages work", () => {
test.beforeEach(async ({ page }) => {
await loginTest(page);
- await fulfillEmptyRoutes(page, ["**/playlists*", "**/screens*", "**/screen-groups*"]);
+ await fulfillEmptyRoutes(page, [
+ "**/playlists*",
+ "**/screens*",
+ "**/screen-groups*",
+ ]);
await page.locator(".sidebar-nav .nav-link").getByText("Kampagner").click();
await expect(page.locator("h1").getByText("Kampagner")).toBeVisible();
diff --git a/assets/tests/admin/admin-feed-sources.spec.js b/assets/tests/admin/admin-feed-sources.spec.js
index e484c2e1..263cb1d3 100644
--- a/assets/tests/admin/admin-feed-sources.spec.js
+++ b/assets/tests/admin/admin-feed-sources.spec.js
@@ -3,9 +3,14 @@ import {
errorJson,
feedSourcesJson,
feedSourcesJson2,
- feedSourceSingleJson
+ feedSourceSingleJson,
} from "./data-fixtures.js";
-import { fulfillDataRoute, fulfillEmptyRoutes, beforeEachTest, loginTest } from "./test-helper.js";
+import {
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ beforeEachTest,
+ loginTest,
+} from "./test-helper.js";
test.describe("feed sources", () => {
test.beforeEach(async ({ page }) => {
@@ -72,7 +77,11 @@ test.describe("feed sources", () => {
await expect(page.locator("#feed-sourceTitle")).not.toBeVisible();
await fulfillDataRoute(page, "**/feed-sources*", feedSourcesJson2);
- await fulfillDataRoute(page, "**/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ", feedSourceSingleJson);
+ await fulfillDataRoute(
+ page,
+ "**/feed-sources/01JBBP48CS9CV80XRWRP8CAETJ",
+ feedSourceSingleJson,
+ );
await page.locator("tbody").locator("tr td a").first().click();
await expect(page.locator("#feed-sourceTitle")).toBeVisible();
diff --git a/assets/tests/admin/admin-login.spec.js b/assets/tests/admin/admin-login.spec.js
index 485abe3e..3f141b4e 100644
--- a/assets/tests/admin/admin-login.spec.js
+++ b/assets/tests/admin/admin-login.spec.js
@@ -2,9 +2,16 @@ import { test, expect } from "@playwright/test";
import {
accessConfigJson,
adminConfigJson,
- emptyJson, tokenAdminJson, tokenEditorJson, tokenTenantsJson
+ emptyJson,
+ tokenAdminJson,
+ tokenEditorJson,
+ tokenTenantsJson,
} from "./data-fixtures.js";
-import { fulfillDataRoute, fulfillEmptyRoutes, beforeEachTest } from "./test-helper.js";
+import {
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ beforeEachTest,
+} from "./test-helper.js";
test.describe("Login works", () => {
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-playlist.spec.js b/assets/tests/admin/admin-playlist.spec.js
index a5879a48..d1fc39b5 100644
--- a/assets/tests/admin/admin-playlist.spec.js
+++ b/assets/tests/admin/admin-playlist.spec.js
@@ -1,6 +1,17 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
-import { emptyJson, errorJson, playlistListJson, onSaveJson, playlistSingleJson } from "./data-fixtures.js";
+import {
+ beforeEachTest,
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
+import {
+ emptyJson,
+ errorJson,
+ playlistListJson,
+ onSaveJson,
+ playlistSingleJson,
+} from "./data-fixtures.js";
test.describe("Playlist create tests", () => {
test.beforeEach(async ({ page }) => {
@@ -25,7 +36,7 @@ test.describe("Playlist create tests", () => {
// Displays success toast and redirects
await expect(
- page.locator(".Toastify").locator(".Toastify__toast--success")
+ page.locator(".Toastify").locator(".Toastify__toast--success"),
).not.toBeVisible();
await page.locator("#save_slide_and_close").click();
await expect(
@@ -33,7 +44,7 @@ test.describe("Playlist create tests", () => {
.locator(".Toastify")
.locator(".Toastify__toast--success")
.getByText(/gemt/)
- .first()
+ .first(),
).toBeVisible();
await expect(page).toHaveURL(/playlist\/list/);
});
@@ -43,18 +54,18 @@ test.describe("Playlist create tests", () => {
// Displays error toast and stays on page
await expect(
- page.locator(".Toastify").locator(".Toastify__toast--error")
+ page.locator(".Toastify").locator(".Toastify__toast--error"),
).not.toBeVisible();
await page.locator("#save_playlist").click();
await expect(
- page.locator(".Toastify").locator(".Toastify__toast--error")
+ page.locator(".Toastify").locator(".Toastify__toast--error"),
).toBeVisible();
await expect(
page
.locator(".Toastify")
.locator(".Toastify__toast--error")
.getByText(/An error occurred/)
- .first()
+ .first(),
).toBeVisible();
await expect(page).toHaveURL(/playlist\/create/);
});
@@ -79,12 +90,14 @@ test.describe("Playlist list tests", () => {
await fulfillEmptyRoutes(page, ["**/tenants*"]);
await page.getByRole("link", { name: "Spillelister", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Spillelister", exact: true })).toBeVisible();
+ await expect(
+ page.getByRole("heading", { name: "Spillelister", exact: true }),
+ ).toBeVisible();
});
test("It loads playlist list", async ({ page }) => {
await expect(
- page.locator("table").locator("tbody").first()
+ page.locator("table").locator("tbody").first(),
).not.toBeEmpty();
await expect(page.locator("tbody").locator("tr td").first()).toBeVisible();
});
@@ -97,8 +110,9 @@ test.describe("Playlist list tests", () => {
await expect(page.locator("#playlistTitle")).toBeVisible();
});
- test("The correct amount of column headers loaded (playlist list)",
- async ({ page }) => {
- await expect(page.locator("thead").locator("th")).toHaveCount(8);
- });
+ test("The correct amount of column headers loaded (playlist list)", async ({
+ page,
+ }) => {
+ await expect(page.locator("thead").locator("th")).toHaveCount(8);
+ });
});
diff --git a/assets/tests/admin/admin-screen-groups.spec.js b/assets/tests/admin/admin-screen-groups.spec.js
index dce7dd16..cf3b466a 100644
--- a/assets/tests/admin/admin-screen-groups.spec.js
+++ b/assets/tests/admin/admin-screen-groups.spec.js
@@ -1,11 +1,16 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import {
+ beforeEachTest,
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
import {
playlistListJson,
onSaveJson,
errorJson,
screenGroupsListJson,
- screenGroupsSingleJson
+ screenGroupsSingleJson,
} from "./data-fixtures.js";
import { json } from "react-router-dom";
@@ -20,9 +25,15 @@ test.describe("Create group page works", () => {
await fulfillEmptyRoutes(page, ["**/screen-groups*"]);
await page.getByRole("link", { name: "Grupper", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Grupper", exact: true })).toBeVisible();
- await page.getByRole("button", { name: "Opret ny gruppe", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Opret ny gruppe", exact: true })).toBeVisible();
+ await expect(
+ page.getByRole("heading", { name: "Grupper", exact: true }),
+ ).toBeVisible();
+ await page
+ .getByRole("button", { name: "Opret ny gruppe", exact: true })
+ .click();
+ await expect(
+ page.getByRole("heading", { name: "Opret ny gruppe", exact: true }),
+ ).toBeVisible();
});
test("It loads create group page", async ({ page }) => {
@@ -76,11 +87,13 @@ test.describe("Groups list works", () => {
test.beforeEach(async ({ page }) => {
await loginTest(page);
- await fulfillEmptyRoutes(page, ['**/screens*']);
+ await fulfillEmptyRoutes(page, ["**/screens*"]);
await fulfillDataRoute(page, "**/screen-groups*", screenGroupsListJson);
await page.getByRole("link", { name: "Grupper", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Grupper", exact: true })).toBeVisible();
+ await expect(
+ page.getByRole("heading", { name: "Grupper", exact: true }),
+ ).toBeVisible();
});
test("It loads groups list", async ({ page }) => {
@@ -89,7 +102,11 @@ test.describe("Groups list works", () => {
});
test("It goes to edit (groups list)", async ({ page }) => {
- await fulfillDataRoute(page, "**/screen-groups/000RAH746Q1AD8011Z1JNV06N3", screenGroupsSingleJson);
+ await fulfillDataRoute(
+ page,
+ "**/screen-groups/000RAH746Q1AD8011Z1JNV06N3",
+ screenGroupsSingleJson,
+ );
await expect(page.locator("#groupTitle")).not.toBeVisible();
await page.locator("tbody").locator("tr td a").nth(0).click();
diff --git a/assets/tests/admin/admin-screens.spec.js b/assets/tests/admin/admin-screens.spec.js
index 1b0280da..1a859f23 100644
--- a/assets/tests/admin/admin-screens.spec.js
+++ b/assets/tests/admin/admin-screens.spec.js
@@ -1,6 +1,15 @@
import { test, expect } from "@playwright/test";
-import { adminConfigJson, screenGroupsListJson, screensListJson } from "./data-fixtures.js";
-import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import {
+ adminConfigJson,
+ screenGroupsListJson,
+ screensListJson,
+} from "./data-fixtures.js";
+import {
+ beforeEachTest,
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
test.describe("Screen", () => {
test.beforeEach(async ({ page }) => {
@@ -12,10 +21,16 @@ test.describe("Screen", () => {
await fulfillDataRoute(page, "**/screens*", screensListJson);
- await fulfillEmptyRoutes(page, ["**/campaigns*", "**/screen-groups*", "**/layouts*"]);
+ await fulfillEmptyRoutes(page, [
+ "**/campaigns*",
+ "**/screen-groups*",
+ "**/layouts*",
+ ]);
await page.getByRole("link", { name: "Skærme", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Skærme", exact: true })).toBeVisible();
+ await expect(
+ page.getByRole("heading", { name: "Skærme", exact: true }),
+ ).toBeVisible();
});
test("Loads list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-shared-list.spec.js b/assets/tests/admin/admin-shared-list.spec.js
index 51576c87..7244ae2a 100644
--- a/assets/tests/admin/admin-shared-list.spec.js
+++ b/assets/tests/admin/admin-shared-list.spec.js
@@ -1,5 +1,10 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import {
+ beforeEachTest,
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
import { playlistListJson, screensListJson } from "./data-fixtures.js";
test.describe("Shared list tests", () => {
@@ -12,8 +17,12 @@ test.describe("Shared list tests", () => {
await fulfillDataRoute(page, "**/playlists*", playlistListJson);
- await page.getByRole("link", { name: "Delte spillelister", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Delte spillelister", exact: true })).toBeVisible();
+ await page
+ .getByRole("link", { name: "Delte spillelister", exact: true })
+ .click();
+ await expect(
+ page.getByRole("heading", { name: "Delte spillelister", exact: true }),
+ ).toBeVisible();
});
test("It loads shared playlist list", async ({ page }) => {
diff --git a/assets/tests/admin/admin-slides.spec.js b/assets/tests/admin/admin-slides.spec.js
index 77d5d981..a93d3112 100644
--- a/assets/tests/admin/admin-slides.spec.js
+++ b/assets/tests/admin/admin-slides.spec.js
@@ -1,6 +1,16 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
-import { emptyJson, errorJson, slidesListJson, templatesListJson } from "./data-fixtures.js";
+import {
+ beforeEachTest,
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
+import {
+ emptyJson,
+ errorJson,
+ slidesListJson,
+ templatesListJson,
+} from "./data-fixtures.js";
test.describe("Slide create", () => {
test.beforeEach(async ({ page }) => {
diff --git a/assets/tests/admin/admin-theme.spec.js b/assets/tests/admin/admin-theme.spec.js
index 5aa19d05..8c9da305 100644
--- a/assets/tests/admin/admin-theme.spec.js
+++ b/assets/tests/admin/admin-theme.spec.js
@@ -1,6 +1,17 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, fulfillDataRoute, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
-import { errorJson, feedSourcesJson2, screensListJson, themesJson, themesSingleJson } from "./data-fixtures.js";
+import {
+ beforeEachTest,
+ fulfillDataRoute,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
+import {
+ errorJson,
+ feedSourcesJson2,
+ screensListJson,
+ themesJson,
+ themesSingleJson,
+} from "./data-fixtures.js";
test.describe("Theme", () => {
test.beforeEach(async ({ page }) => {
@@ -11,10 +22,12 @@ test.describe("Theme", () => {
await loginTest(page);
await fulfillDataRoute(page, "**/themes*", themesJson);
-// await fulfillEmptyRoutes(page, ["**/campaigns*", "**/screen-groups*", "**/layouts*"]);
+ // await fulfillEmptyRoutes(page, ["**/campaigns*", "**/screen-groups*", "**/layouts*"]);
await page.getByRole("link", { name: "Temaer", exact: true }).click();
- await expect(page.getByRole("heading", { name: "Temaer", exact: true })).toBeVisible();
+ await expect(
+ page.getByRole("heading", { name: "Temaer", exact: true }),
+ ).toBeVisible();
});
test("It loads create theme page", async ({ page }) => {
diff --git a/assets/tests/admin/admin-top-bar.spec.js b/assets/tests/admin/admin-top-bar.spec.js
index cf0533ac..72fcdba4 100644
--- a/assets/tests/admin/admin-top-bar.spec.js
+++ b/assets/tests/admin/admin-top-bar.spec.js
@@ -1,5 +1,9 @@
import { test, expect } from "@playwright/test";
-import { beforeEachTest, fulfillEmptyRoutes, loginTest } from "./test-helper.js";
+import {
+ beforeEachTest,
+ fulfillEmptyRoutes,
+ loginTest,
+} from "./test-helper.js";
import { emptyJson } from "./data-fixtures.js";
test.describe("Nav items loads", () => {
diff --git a/assets/tests/admin/data-fixtures.js b/assets/tests/admin/data-fixtures.js
index d37a2d98..503c7284 100644
--- a/assets/tests/admin/data-fixtures.js
+++ b/assets/tests/admin/data-fixtures.js
@@ -754,7 +754,7 @@ const onSaveJson = {
created: "1991-09-10T22:36:56+02:00",
modified: "2021-12-09T12:01:33+01:00",
modifiedBy: "",
- createdBy: ""
+ createdBy: "",
};
const playlistListJson = {
@@ -779,8 +779,8 @@ const playlistListJson = {
isCampaign: true,
published: {
from: "2022-03-23T21:30:21.000Z",
- to: "2022-03-25T12:39:29.000Z"
- }
+ to: "2022-03-25T12:39:29.000Z",
+ },
},
{
"@type": "Playlist",
@@ -798,16 +798,16 @@ const playlistListJson = {
campaignScreenGroups: [
"/v2/screen-groups/00EQWMS5WA1WJE0WD81VF91DFH",
"/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
- "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3"
+ "/v2/screen-groups/0135RY0QPR1DVF0ZT70YHS1NX3",
],
isCampaign: false,
published: {
from: "2021-03-21T02:10:37.000Z",
- to: "2021-11-08T12:13:31.000Z"
- }
- }
+ to: "2021-11-08T12:13:31.000Z",
+ },
+ },
],
- "hydra:totalItems": 10
+ "hydra:totalItems": 10,
};
const playlistSingleJson = {
@@ -826,8 +826,8 @@ const playlistSingleJson = {
isCampaign: true,
published: {
from: "2022-03-23T21:30:21.000Z",
- to: "2022-03-25T12:39:29.000Z"
- }
+ to: "2022-03-25T12:39:29.000Z",
+ },
};
const screenGroupsListJson = {
diff --git a/assets/tests/admin/test-helper.js b/assets/tests/admin/test-helper.js
index 2324517e..d29f9e41 100644
--- a/assets/tests/admin/test-helper.js
+++ b/assets/tests/admin/test-helper.js
@@ -30,19 +30,19 @@ const fulfillEmptyRoutes = async (page, routePatterns) => {
await route.fulfill({ json: emptyJson });
});
}
-}
+};
const fulfillDataRoute = async (page, routePattern, data, status) => {
- const result = { json: data};
+ const result = { json: data };
if (status) {
- result['status'] = status;
+ result["status"] = status;
}
await page.route(routePattern, async (route) => {
await route.fulfill(result);
});
-}
+};
const loginTest = async (page) => {
await page.goto("/admin/slides/list");