plum-e2e 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -70
- package/backend/Dockerfile +4 -2
- package/backend/_scaffold/utils/browser.ts +1 -0
- package/backend/app.js +4 -2
- package/backend/config/scripts/generate-report.js +38 -30
- package/{.prettierignore → backend/entrypoint.sh} +7 -6
- package/backend/package-lock.json +453 -10
- package/backend/package.json +5 -2
- package/backend/prisma/migrations/20260614000000_init/migration.sql +35 -0
- package/backend/prisma/migrations/20260614000001_add_project/migration.sql +8 -0
- package/backend/prisma/migrations/migration_lock.toml +3 -0
- package/backend/prisma/schema.prisma +53 -0
- package/backend/routes/backup.routes.js +50 -0
- package/backend/routes/cron.routes.js +9 -60
- package/backend/routes/reports.routes.js +39 -6
- package/backend/routes/settings.routes.js +43 -0
- package/backend/server.js +52 -1
- package/backend/services/backupService.js +88 -0
- package/backend/services/cronService.js +68 -78
- package/backend/{routes/schedules.routes.js → services/prisma.js} +3 -13
- package/backend/services/reportService.js +48 -20
- package/backend/services/settingsService.js +36 -0
- package/bin/plum.js +216 -34
- package/docker-compose.yml +24 -0
- package/frontend/.svelte-kit/adapter-node/.vite/manifest.json +190 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/Badge.DLLowvEA.css +17 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/Button.cBruH0aD.css +17 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_layout.D7eM-6MV.css +17 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.BVnUajEa.css +17 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.CGnCsn5q.css +17 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.DBhBrHFz.css +17 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.DOqo0UR4.css +17 -0
- package/frontend/.svelte-kit/adapter-node/chunks/Badge.js +30 -0
- package/frontend/.svelte-kit/adapter-node/chunks/Button.js +32 -0
- package/frontend/.svelte-kit/adapter-node/chunks/attributes.js +34 -0
- package/frontend/.svelte-kit/adapter-node/chunks/client.js +59 -0
- package/{backend/services/scheduleService.js → frontend/.svelte-kit/adapter-node/chunks/equality.js} +13 -16
- package/frontend/.svelte-kit/adapter-node/chunks/escaping.js +36 -0
- package/frontend/.svelte-kit/adapter-node/chunks/exports.js +247 -0
- package/frontend/.svelte-kit/adapter-node/chunks/index.js +1135 -0
- package/frontend/.svelte-kit/adapter-node/chunks/internal.js +695 -0
- package/frontend/.svelte-kit/adapter-node/chunks/reports.js +57 -0
- package/frontend/.svelte-kit/adapter-node/entries/fallbacks/error.svelte.js +44 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/_layout.svelte.js +181 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/_page.svelte.js +164 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/reports/_page.svelte.js +141 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/reports/_slug_/_page.svelte.js +42 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/scheduled-tests/_page.svelte.js +179 -0
- package/frontend/.svelte-kit/adapter-node/index.js +3144 -0
- package/frontend/.svelte-kit/adapter-node/internal.js +30 -0
- package/frontend/.svelte-kit/adapter-node/manifest-full.js +77 -0
- package/frontend/.svelte-kit/adapter-node/manifest.js +81 -0
- package/frontend/.svelte-kit/adapter-node/nodes/0.js +25 -0
- package/frontend/.svelte-kit/adapter-node/nodes/1.js +25 -0
- package/frontend/.svelte-kit/adapter-node/nodes/2.js +25 -0
- package/frontend/.svelte-kit/adapter-node/nodes/3.js +25 -0
- package/frontend/.svelte-kit/adapter-node/nodes/4.js +25 -0
- package/frontend/.svelte-kit/adapter-node/nodes/5.js +25 -0
- package/frontend/.svelte-kit/ambient.d.ts +240 -0
- package/frontend/.svelte-kit/generated/client/app.js +51 -0
- package/frontend/.svelte-kit/generated/client/matchers.js +18 -0
- package/frontend/.svelte-kit/generated/client/nodes/0.js +18 -0
- package/frontend/.svelte-kit/generated/client/nodes/1.js +18 -0
- package/frontend/.svelte-kit/generated/client/nodes/2.js +18 -0
- package/frontend/.svelte-kit/generated/client/nodes/3.js +18 -0
- package/frontend/.svelte-kit/generated/client/nodes/4.js +18 -0
- package/frontend/.svelte-kit/generated/client/nodes/5.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/app.js +51 -0
- package/frontend/.svelte-kit/generated/client-optimized/matchers.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/nodes/0.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/nodes/1.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/nodes/2.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/nodes/3.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/nodes/4.js +18 -0
- package/frontend/.svelte-kit/generated/client-optimized/nodes/5.js +18 -0
- package/frontend/.svelte-kit/generated/root.js +20 -0
- package/frontend/.svelte-kit/generated/root.svelte +83 -0
- package/frontend/.svelte-kit/generated/server/internal.js +65 -0
- package/frontend/.svelte-kit/non-ambient.d.ts +42 -0
- package/frontend/.svelte-kit/output/client/.vite/manifest.json +289 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/0.CnXRuPt4.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/2.CGnCsn5q.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/3.BVnUajEa.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/4.DBhBrHFz.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/5.D93VAB-w.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/Badge.DLLowvEA.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/Button.cBruH0aD.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_layout.D7eM-6MV.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.BVnUajEa.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.CGnCsn5q.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.DBhBrHFz.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.DOqo0UR4.css +17 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/B0bn91RF.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/B1kE5jmt.js +23 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BKz6FZdB.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/Be4iUAB0.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BpaMqo9O.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/Bt3-Z7H1.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CHV2KnPr.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CJ8q7g9Y.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/Cit9MuSg.js +20 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CwBTqcbj.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DBk3zeq4.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DFJLQFic.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DTUE7kkY.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/IYPwzKs_.js +20 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/oc0we5Us.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/rVEKg0Ak.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/entry/app.C2MbX06K.js +19 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/entry/start.GiBry-lw.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/0.BsCYK-Tn.js +21 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/1.N4gjrCnX.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/2.D9yQNzK8.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/3.CBC5WvNb.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/4.BU6UZHSE.js +19 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/5.Dzzfrntl.js +18 -0
- package/frontend/.svelte-kit/output/client/_app/version.json +1 -0
- package/frontend/.svelte-kit/output/client/favicon.png +0 -0
- package/frontend/.svelte-kit/output/server/.vite/manifest.json +190 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/Badge.DLLowvEA.css +17 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/Button.cBruH0aD.css +17 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_layout.D7eM-6MV.css +17 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.BVnUajEa.css +17 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.CGnCsn5q.css +17 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.DBhBrHFz.css +17 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.DOqo0UR4.css +17 -0
- package/frontend/.svelte-kit/output/server/chunks/Badge.js +30 -0
- package/frontend/.svelte-kit/output/server/chunks/Button.js +32 -0
- package/frontend/.svelte-kit/output/server/chunks/attributes.js +34 -0
- package/frontend/.svelte-kit/output/server/chunks/client.js +59 -0
- package/frontend/.svelte-kit/output/server/chunks/equality.js +31 -0
- package/frontend/.svelte-kit/output/server/chunks/escaping.js +36 -0
- package/frontend/.svelte-kit/output/server/chunks/exports.js +247 -0
- package/frontend/.svelte-kit/output/server/chunks/index.js +1135 -0
- package/frontend/.svelte-kit/output/server/chunks/internal.js +695 -0
- package/frontend/.svelte-kit/output/server/chunks/reports.js +57 -0
- package/frontend/.svelte-kit/output/server/entries/fallbacks/error.svelte.js +44 -0
- package/frontend/.svelte-kit/output/server/entries/pages/_layout.svelte.js +181 -0
- package/frontend/.svelte-kit/output/server/entries/pages/_page.svelte.js +164 -0
- package/frontend/.svelte-kit/output/server/entries/pages/reports/_page.svelte.js +141 -0
- package/frontend/.svelte-kit/output/server/entries/pages/reports/_slug_/_page.svelte.js +42 -0
- package/frontend/.svelte-kit/output/server/entries/pages/scheduled-tests/_page.svelte.js +179 -0
- package/frontend/.svelte-kit/output/server/index.js +3144 -0
- package/frontend/.svelte-kit/output/server/internal.js +30 -0
- package/frontend/.svelte-kit/output/server/manifest-full.js +77 -0
- package/frontend/.svelte-kit/output/server/manifest.js +77 -0
- package/frontend/.svelte-kit/output/server/nodes/0.js +25 -0
- package/frontend/.svelte-kit/output/server/nodes/1.js +25 -0
- package/frontend/.svelte-kit/output/server/nodes/2.js +25 -0
- package/frontend/.svelte-kit/output/server/nodes/3.js +25 -0
- package/frontend/.svelte-kit/output/server/nodes/4.js +25 -0
- package/frontend/.svelte-kit/output/server/nodes/5.js +25 -0
- package/frontend/.svelte-kit/tsconfig.json +49 -0
- package/frontend/build/client/_app/immutable/assets/0.CnXRuPt4.css +17 -0
- package/frontend/build/client/_app/immutable/assets/0.CnXRuPt4.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/0.CnXRuPt4.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/2.CGnCsn5q.css +17 -0
- package/frontend/build/client/_app/immutable/assets/2.CGnCsn5q.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/2.CGnCsn5q.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/3.BVnUajEa.css +17 -0
- package/frontend/build/client/_app/immutable/assets/3.BVnUajEa.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/3.BVnUajEa.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/4.DBhBrHFz.css +17 -0
- package/frontend/build/client/_app/immutable/assets/4.DBhBrHFz.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/4.DBhBrHFz.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/5.D93VAB-w.css +17 -0
- package/frontend/build/client/_app/immutable/assets/5.D93VAB-w.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/5.D93VAB-w.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/Badge.DLLowvEA.css +17 -0
- package/frontend/build/client/_app/immutable/assets/Badge.DLLowvEA.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/Badge.DLLowvEA.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/Button.cBruH0aD.css +17 -0
- package/frontend/build/client/_app/immutable/assets/Button.cBruH0aD.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/Button.cBruH0aD.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_layout.D7eM-6MV.css +17 -0
- package/frontend/build/client/_app/immutable/assets/_layout.D7eM-6MV.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_layout.D7eM-6MV.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BVnUajEa.css +17 -0
- package/frontend/build/client/_app/immutable/assets/_page.BVnUajEa.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BVnUajEa.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.CGnCsn5q.css +17 -0
- package/frontend/build/client/_app/immutable/assets/_page.CGnCsn5q.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.CGnCsn5q.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.DBhBrHFz.css +17 -0
- package/frontend/build/client/_app/immutable/assets/_page.DBhBrHFz.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.DBhBrHFz.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.DOqo0UR4.css +17 -0
- package/frontend/build/client/_app/immutable/assets/_page.DOqo0UR4.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.DOqo0UR4.css.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/B0bn91RF.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/B0bn91RF.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/B0bn91RF.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/B1kE5jmt.js +23 -0
- package/frontend/build/client/_app/immutable/chunks/B1kE5jmt.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/B1kE5jmt.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BKz6FZdB.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/BKz6FZdB.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BKz6FZdB.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/Be4iUAB0.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/Be4iUAB0.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/Be4iUAB0.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BpaMqo9O.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/BpaMqo9O.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BpaMqo9O.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/Bt3-Z7H1.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/Bt3-Z7H1.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/Bt3-Z7H1.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CHV2KnPr.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/CHV2KnPr.js.br +18 -0
- package/frontend/build/client/_app/immutable/chunks/CHV2KnPr.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CJ8q7g9Y.js +18 -0
- package/{resources/comments-format.text → frontend/build/client/_app/immutable/chunks/CJ8q7g9Y.js.br} +0 -0
- package/frontend/build/client/_app/immutable/chunks/CJ8q7g9Y.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/Cit9MuSg.js +20 -0
- package/frontend/build/client/_app/immutable/chunks/Cit9MuSg.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/Cit9MuSg.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CwBTqcbj.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/CwBTqcbj.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CwBTqcbj.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DBk3zeq4.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/DBk3zeq4.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DBk3zeq4.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DFJLQFic.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/DFJLQFic.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DFJLQFic.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DTUE7kkY.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/DTUE7kkY.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DTUE7kkY.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/IYPwzKs_.js +20 -0
- package/frontend/build/client/_app/immutable/chunks/IYPwzKs_.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/IYPwzKs_.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/oc0we5Us.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/oc0we5Us.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/oc0we5Us.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/rVEKg0Ak.js +18 -0
- package/frontend/build/client/_app/immutable/chunks/rVEKg0Ak.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/rVEKg0Ak.js.gz +0 -0
- package/frontend/build/client/_app/immutable/entry/app.C2MbX06K.js +19 -0
- package/frontend/build/client/_app/immutable/entry/app.C2MbX06K.js.br +0 -0
- package/frontend/build/client/_app/immutable/entry/app.C2MbX06K.js.gz +0 -0
- package/frontend/build/client/_app/immutable/entry/start.GiBry-lw.js +18 -0
- package/frontend/build/client/_app/immutable/entry/start.GiBry-lw.js.br +18 -0
- package/frontend/build/client/_app/immutable/entry/start.GiBry-lw.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/0.BsCYK-Tn.js +21 -0
- package/frontend/build/client/_app/immutable/nodes/0.BsCYK-Tn.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/0.BsCYK-Tn.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/1.N4gjrCnX.js +18 -0
- package/frontend/build/client/_app/immutable/nodes/1.N4gjrCnX.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/1.N4gjrCnX.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/2.D9yQNzK8.js +18 -0
- package/frontend/build/client/_app/immutable/nodes/2.D9yQNzK8.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/2.D9yQNzK8.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/3.CBC5WvNb.js +18 -0
- package/frontend/build/client/_app/immutable/nodes/3.CBC5WvNb.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/3.CBC5WvNb.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/4.BU6UZHSE.js +19 -0
- package/frontend/build/client/_app/immutable/nodes/4.BU6UZHSE.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/4.BU6UZHSE.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/5.Dzzfrntl.js +18 -0
- package/frontend/build/client/_app/immutable/nodes/5.Dzzfrntl.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/5.Dzzfrntl.js.gz +0 -0
- package/frontend/build/client/_app/version.json +1 -0
- package/frontend/build/client/_app/version.json.br +0 -0
- package/frontend/build/client/_app/version.json.gz +0 -0
- package/frontend/build/client/favicon.png +0 -0
- package/frontend/build/env.js +111 -0
- package/frontend/build/handler.js +1511 -0
- package/frontend/build/index.js +362 -0
- package/frontend/build/server/chunks/0-BFfqmlsS.js +26 -0
- package/frontend/build/server/chunks/0-BFfqmlsS.js.map +17 -0
- package/frontend/build/server/chunks/1-hso3H4Ax.js +26 -0
- package/frontend/build/server/chunks/1-hso3H4Ax.js.map +17 -0
- package/frontend/build/server/chunks/2-BSZWXCWp.js +26 -0
- package/frontend/build/server/chunks/2-BSZWXCWp.js.map +17 -0
- package/frontend/build/server/chunks/3-BYumY9dv.js +26 -0
- package/frontend/build/server/chunks/3-BYumY9dv.js.map +17 -0
- package/frontend/build/server/chunks/4-2UUrCVtM.js +26 -0
- package/frontend/build/server/chunks/4-2UUrCVtM.js.map +17 -0
- package/frontend/build/server/chunks/5-C2_y_fwT.js +26 -0
- package/frontend/build/server/chunks/5-C2_y_fwT.js.map +17 -0
- package/frontend/build/server/chunks/Badge-CC4U7C0c.js +30 -0
- package/frontend/build/server/chunks/Badge-CC4U7C0c.js.map +17 -0
- package/frontend/build/server/chunks/Button-BLkPicwS.js +33 -0
- package/frontend/build/server/chunks/Button-BLkPicwS.js.map +17 -0
- package/frontend/build/server/chunks/_layout.svelte-Bfxcj9C6.js +183 -0
- package/frontend/build/server/chunks/_layout.svelte-Bfxcj9C6.js.map +17 -0
- package/frontend/build/server/chunks/_page.svelte-DEK6UvaI.js +45 -0
- package/frontend/build/server/chunks/_page.svelte-DEK6UvaI.js.map +17 -0
- package/frontend/build/server/chunks/_page.svelte-DScVdHOq.js +142 -0
- package/frontend/build/server/chunks/_page.svelte-DScVdHOq.js.map +17 -0
- package/frontend/build/server/chunks/_page.svelte-Ns7w2sZt.js +180 -0
- package/frontend/build/server/chunks/_page.svelte-Ns7w2sZt.js.map +17 -0
- package/frontend/build/server/chunks/_page.svelte-s6ZIOitT.js +165 -0
- package/frontend/build/server/chunks/_page.svelte-s6ZIOitT.js.map +17 -0
- package/frontend/build/server/chunks/attributes-BeaNKpgU.js +34 -0
- package/frontend/build/server/chunks/attributes-BeaNKpgU.js.map +17 -0
- package/frontend/build/server/chunks/client-C9IaEwNo.js +52 -0
- package/frontend/build/server/chunks/client-C9IaEwNo.js.map +17 -0
- package/frontend/build/server/chunks/error.svelte-HKBv5sQT.js +45 -0
- package/frontend/build/server/chunks/error.svelte-HKBv5sQT.js.map +17 -0
- package/frontend/build/server/chunks/escaping-CqgfEcN3.js +36 -0
- package/frontend/build/server/chunks/escaping-CqgfEcN3.js.map +17 -0
- package/frontend/build/server/chunks/exports-OxlCJ8yE.js +192 -0
- package/frontend/build/server/chunks/exports-OxlCJ8yE.js.map +17 -0
- package/frontend/build/server/chunks/index-CjHlq1kt.js +1076 -0
- package/frontend/build/server/chunks/index-CjHlq1kt.js.map +17 -0
- package/frontend/build/server/chunks/reports-D3ZeYSmi.js +56 -0
- package/frontend/build/server/chunks/reports-D3ZeYSmi.js.map +17 -0
- package/frontend/build/server/index.js +5015 -0
- package/frontend/build/server/index.js.map +17 -0
- package/frontend/build/server/manifest.js +84 -0
- package/frontend/build/server/manifest.js.map +17 -0
- package/frontend/build/shims.js +49 -0
- package/frontend/package-lock.json +2 -2
- package/frontend/package.json +1 -1
- package/frontend/src/lib/api/reports.js +38 -27
- package/frontend/src/lib/api/schedules.js +9 -25
- package/frontend/src/lib/api/settings.js +48 -0
- package/frontend/src/lib/components/layout/Nav.svelte +2 -1
- package/frontend/src/lib/components/layout/RunnerPanel.svelte +160 -21
- package/frontend/src/lib/components/ui/Terminal.svelte +2 -2
- package/frontend/src/lib/stores/runner.js +9 -0
- package/frontend/src/routes/+page.svelte +10 -3
- package/frontend/src/routes/reports/+page.svelte +342 -51
- package/frontend/src/routes/reports/[slug]/+page.svelte +2 -0
- package/frontend/src/routes/scheduled-tests/+page.svelte +247 -11
- package/frontend/src/routes/settings/+page.svelte +410 -0
- package/package.json +6 -2
- package/.claude/settings.local.json +0 -27
- package/.husky/pre-commit +0 -2
- package/.prettierrc +0 -15
- package/.vscode/settings.json +0 -10
- package/backend/config/scripts/create-settings.js +0 -53
- package/license-config.json +0 -37
package/README.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
<a href="https://www.npmjs.com/package/plum-e2e"><img src="https://img.shields.io/npm/v/plum-e2e?color=7c3aed&label=plum-e2e" alt="npm version" /></a>
|
|
5
|
+
<a href="https://github.com/silverlunah/plum/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-blue" alt="license" /></a>
|
|
6
|
+
<a href="https://github.com/silverlunah/plum/wiki"><img src="https://img.shields.io/badge/docs-wiki-informational" alt="docs" /></a>
|
|
6
7
|
</p>
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
<p align="center">
|
|
10
|
+
A ready-to-use E2E test automation environment built on <a href="https://playwright.dev">Playwright</a> + <a href="https://cucumber.io">Cucumber</a>.<br/>
|
|
11
|
+
Write tests in Gherkin, run them from the CLI or UI, and view reports — all in one place.
|
|
12
|
+
</p>
|
|
11
13
|
|
|
12
14
|
---
|
|
13
15
|
|
|
14
|
-
##
|
|
16
|
+
## Requirements
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
- [Node.js](https://nodejs.org) (v18+)
|
|
19
|
+
- [Docker](https://www.docker.com) — only needed for `plum start`
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- [Node.js](https://nodejs.org)
|
|
21
|
-
- [Docker](https://www.docker.com) (required for `plum start`)
|
|
21
|
+
---
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## Quick Start
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
npm install -g plum-e2e
|
|
@@ -28,38 +28,117 @@ mkdir my-tests && cd my-tests
|
|
|
28
28
|
plum init
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Setup & Configuration
|
|
34
|
+
|
|
35
|
+
### `plum init`
|
|
36
|
+
|
|
37
|
+
Scaffolds a new project in the current directory. Run this once after creating your project folder.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
plum init
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Creates the following structure:
|
|
32
44
|
|
|
33
45
|
<pre>
|
|
34
|
-
╠═ tests
|
|
35
|
-
║ ╠═ features
|
|
36
|
-
║ ╠═ step_definitions
|
|
37
|
-
║ ╠═ pages
|
|
38
|
-
║ ╚═ utils
|
|
39
|
-
╠═ .vscode
|
|
40
|
-
║ ╚═ settings.json
|
|
41
|
-
|
|
46
|
+
╠═ tests/
|
|
47
|
+
║ ╠═ features/ — Gherkin .feature files (your test cases)
|
|
48
|
+
║ ╠═ step_definitions/ — TypeScript step implementations
|
|
49
|
+
║ ╠═ pages/ — Page Object Models
|
|
50
|
+
║ ╚═ utils/ — Browser setup, hooks, shared helpers
|
|
51
|
+
╠═ .vscode/
|
|
52
|
+
║ ╚═ settings.json — Cucumber extension config (step linking)
|
|
53
|
+
╠═ .env — Environment config (BASE_URL, IS_HEADLESS)
|
|
54
|
+
╠═ .gitignore — Pre-configured to ignore .plum/ and reports/
|
|
55
|
+
╚═ plum.plugins.json — Add extra npm packages for your tests here
|
|
42
56
|
</pre>
|
|
43
57
|
|
|
44
|
-
|
|
58
|
+
Also installs all Plum dependencies and the [Cucumber VS Code extension](https://marketplace.visualstudio.com/items?itemName=cucumberopen.cucumber-official) for step definition linking.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### `.env` — Environment Config
|
|
45
63
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
Plum creates a `.env` in your project root. Edit it to point at your app:
|
|
65
|
+
|
|
66
|
+
```env
|
|
67
|
+
BASE_URL=https://your-app.com
|
|
68
|
+
IS_HEADLESS=false
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
| Variable | Description |
|
|
72
|
+
| ------------- | -------------------------------------------------------- |
|
|
73
|
+
| `BASE_URL` | The base URL Playwright navigates to during tests |
|
|
74
|
+
| `IS_HEADLESS` | Run the browser headlessly (`true`) or visibly (`false`) |
|
|
53
75
|
|
|
54
76
|
---
|
|
55
77
|
|
|
56
|
-
###
|
|
78
|
+
### `plum.plugins.json` — Adding Packages
|
|
57
79
|
|
|
58
|
-
|
|
80
|
+
If your tests need extra npm packages (e.g. a faker library, an assertion helper), add them to `plum.plugins.json`:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"@faker-js/faker": "^9.0.0",
|
|
86
|
+
"dayjs": "^1.11.0"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Plum installs these automatically before running tests. Commit this file so your whole team shares the same dependencies.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Development Commands
|
|
96
|
+
|
|
97
|
+
### `plum dev` — Run Tests Locally
|
|
98
|
+
|
|
99
|
+
Runs tests directly on your machine without Docker. This is the fastest way to write and debug tests.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
plum dev # run all tests
|
|
103
|
+
plum dev @test-login-1 # run a single scenario by tag
|
|
104
|
+
plum dev @suite-login # run a whole suite by tag
|
|
105
|
+
plum dev --parallel 4 # run all tests across 4 workers
|
|
106
|
+
plum dev --parallel 4 @suite-x # run a suite in parallel
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> Syncs your `tests/` folder into Plum, installs dependencies, and runs Cucumber.
|
|
59
110
|
|
|
60
|
-
|
|
111
|
+
---
|
|
61
112
|
|
|
62
|
-
|
|
113
|
+
### `plum start` — Run via Docker
|
|
114
|
+
|
|
115
|
+
Starts the full Plum stack (backend + UI) in Docker. Use this when you want the web interface at `http://localhost:5173` to trigger, monitor, and schedule tests.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
plum start
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
> Requires Docker to be running. Automatically rebuilds if you've changed plugins or config.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### `plum create-step` — Generate a Step
|
|
126
|
+
|
|
127
|
+
Interactive prompt that generates a new step definition and its Page Object method.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
plum create-step
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Follow the prompts to describe the action — Plum writes the boilerplate so you just fill in the implementation.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Writing a Test
|
|
138
|
+
|
|
139
|
+
Tests follow a three-layer structure: **Feature → Step Definition → Page Object**.
|
|
140
|
+
|
|
141
|
+
### 1. Feature File
|
|
63
142
|
|
|
64
143
|
```gherkin
|
|
65
144
|
# tests/features/Login.feature
|
|
@@ -74,9 +153,9 @@ Feature: Login
|
|
|
74
153
|
Then I should see the dashboard
|
|
75
154
|
```
|
|
76
155
|
|
|
77
|
-
|
|
156
|
+
Use tags (`@suite-login`, `@test-login-1`) to filter which tests to run.
|
|
78
157
|
|
|
79
|
-
|
|
158
|
+
### 2. Page Object
|
|
80
159
|
|
|
81
160
|
```typescript
|
|
82
161
|
// tests/pages/LoginPage.ts
|
|
@@ -100,9 +179,9 @@ export class LoginPage {
|
|
|
100
179
|
}
|
|
101
180
|
```
|
|
102
181
|
|
|
103
|
-
|
|
182
|
+
Methods are **static** — they use `page()` internally so you never pass a page instance around.
|
|
104
183
|
|
|
105
|
-
|
|
184
|
+
### 3. Step Definition
|
|
106
185
|
|
|
107
186
|
```typescript
|
|
108
187
|
// tests/step_definitions/LoginSteps.ts
|
|
@@ -123,59 +202,52 @@ Then('I should see the dashboard', async () => {
|
|
|
123
202
|
});
|
|
124
203
|
```
|
|
125
204
|
|
|
126
|
-
|
|
205
|
+
---
|
|
127
206
|
|
|
128
|
-
|
|
129
|
-
plum dev @test-login-1 # run a single scenario
|
|
130
|
-
plum dev @suite-login # run the whole suite
|
|
131
|
-
plum dev # run all tests
|
|
132
|
-
```
|
|
207
|
+
## Command Reference
|
|
133
208
|
|
|
134
|
-
|
|
209
|
+
| Command | When to use |
|
|
210
|
+
| ----------------------- | -------------------------------------------- |
|
|
211
|
+
| `plum init` | First-time setup in a new project folder |
|
|
212
|
+
| `plum dev` | Run all tests locally |
|
|
213
|
+
| `plum dev @tag` | Run tests matching a tag locally |
|
|
214
|
+
| `plum dev --parallel N` | Run tests across N parallel workers locally |
|
|
215
|
+
| `plum start` | Start the full UI stack via Docker |
|
|
216
|
+
| `plum create-step` | Interactively scaffold a new step definition |
|
|
135
217
|
|
|
136
|
-
|
|
218
|
+
---
|
|
137
219
|
|
|
138
|
-
|
|
220
|
+
## For Contributors
|
|
139
221
|
|
|
140
|
-
|
|
222
|
+
> Only relevant if you're developing Plum itself.
|
|
141
223
|
|
|
142
224
|
```bash
|
|
143
225
|
git clone https://github.com/silverlunah/plum.git
|
|
144
226
|
cd plum
|
|
145
|
-
npm run init
|
|
227
|
+
npm run init # installs root + backend + frontend dependencies
|
|
146
228
|
```
|
|
147
229
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
### Backend Local Commands
|
|
151
|
-
|
|
152
|
-
Run these from the `backend/` directory:
|
|
153
|
-
|
|
154
|
-
| Command | Description |
|
|
155
|
-
| -------------------------- | ---------------------------------------------------------------- |
|
|
156
|
-
| `npm run init` | Create `.env` and copy scaffold into `backend/tests/` |
|
|
157
|
-
| `npm test [-- tag]` | Run tests from `backend/tests/` directly |
|
|
158
|
-
| `npm test -- --parallel N` | Run tests in parallel with N workers |
|
|
159
|
-
| `npm run create-step` | Interactive prompt to generate a step definition and page object |
|
|
230
|
+
### Backend
|
|
160
231
|
|
|
161
232
|
```bash
|
|
162
233
|
cd backend
|
|
163
|
-
npm run init
|
|
164
|
-
npm test
|
|
165
|
-
npm test -- @test-1
|
|
166
|
-
npm test -- --parallel 4
|
|
167
|
-
npm run create-step
|
|
234
|
+
npm run init # set up .env and local test scaffold
|
|
235
|
+
npm test # run all tests
|
|
236
|
+
npm test -- @test-1 # run a specific test by tag
|
|
237
|
+
npm test -- --parallel 4 # run tests in parallel
|
|
238
|
+
npm run create-step # generate a step definition interactively
|
|
168
239
|
```
|
|
169
240
|
|
|
170
241
|
### Docker
|
|
171
242
|
|
|
172
243
|
```bash
|
|
173
|
-
npm run docker:up # build and start all services
|
|
244
|
+
npm run docker:up # build and start all services in detached mode
|
|
174
245
|
npm run docker:down # stop all services
|
|
175
246
|
```
|
|
176
247
|
|
|
177
248
|
---
|
|
178
249
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
250
|
+
<p align="center">
|
|
251
|
+
Plum is free to use. If you'd like to show some love:<br/>
|
|
252
|
+
<a href="https://www.paypal.me/silverlunah">PayPal</a> · <a href="https://wise.com/pay/me/janneserjosee">Wise</a>
|
|
253
|
+
</p>
|
package/backend/Dockerfile
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# along with Plum. If not, see https://www.gnu.org/licenses/.
|
|
16
16
|
#
|
|
17
17
|
|
|
18
|
-
FROM mcr.microsoft.com/playwright:v1.
|
|
18
|
+
FROM mcr.microsoft.com/playwright:v1.50.0
|
|
19
19
|
WORKDIR /app
|
|
20
20
|
|
|
21
21
|
COPY package.json package-lock.json ./
|
|
@@ -24,7 +24,9 @@ RUN npx playwright install --with-deps
|
|
|
24
24
|
|
|
25
25
|
COPY . .
|
|
26
26
|
|
|
27
|
+
RUN npx prisma generate
|
|
27
28
|
RUN npm run create-env && sed -i 's/^IS_HEADLESS=false/IS_HEADLESS=true/' .env
|
|
28
29
|
|
|
29
30
|
EXPOSE 3001
|
|
30
|
-
|
|
31
|
+
RUN chmod +x /app/entrypoint.sh
|
|
32
|
+
ENTRYPOINT ["/bin/sh", "/app/entrypoint.sh"]
|
package/backend/app.js
CHANGED
|
@@ -26,12 +26,14 @@ app.use(express.json());
|
|
|
26
26
|
const testRoutes = require('./routes/tests.routes');
|
|
27
27
|
const reportRoutes = require('./routes/reports.routes');
|
|
28
28
|
const cronRoutes = require('./routes/cron.routes');
|
|
29
|
-
const
|
|
29
|
+
const settingsRoutes = require('./routes/settings.routes');
|
|
30
|
+
const backupRoutes = require('./routes/backup.routes');
|
|
30
31
|
|
|
31
32
|
app.use('/tests', testRoutes);
|
|
32
33
|
app.use('/reports', reportRoutes);
|
|
33
34
|
app.use('/cron-jobs', cronRoutes);
|
|
34
35
|
app.use('/reports', express.static('reports'));
|
|
35
|
-
app.use('/
|
|
36
|
+
app.use('/settings', settingsRoutes);
|
|
37
|
+
app.use('/backup', backupRoutes);
|
|
36
38
|
|
|
37
39
|
module.exports = app;
|
|
@@ -17,42 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
const fs = require('fs');
|
|
19
19
|
const path = require('path');
|
|
20
|
-
const { reportsHistory } = require('../settings.json');
|
|
21
|
-
|
|
22
20
|
const reportsDir = 'reports';
|
|
23
21
|
const screenshotsDir = path.join(reportsDir, 'screenshots');
|
|
24
|
-
const maxReports = reportsHistory;
|
|
25
22
|
|
|
26
23
|
if (!fs.existsSync(reportsDir)) fs.mkdirSync(reportsDir, { recursive: true });
|
|
27
24
|
if (!fs.existsSync(screenshotsDir)) fs.mkdirSync(screenshotsDir, { recursive: true });
|
|
28
25
|
|
|
29
|
-
// Clean up old timestamped report JSON files
|
|
30
|
-
const existingReports = fs
|
|
31
|
-
.readdirSync(reportsDir)
|
|
32
|
-
.filter((f) => f.endsWith('.json') && (f.startsWith('PASS_') || f.startsWith('FAIL_')))
|
|
33
|
-
.sort(
|
|
34
|
-
(a, b) =>
|
|
35
|
-
fs.statSync(path.join(reportsDir, b)).mtime - fs.statSync(path.join(reportsDir, a)).mtime
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
while (existingReports.length >= maxReports) {
|
|
39
|
-
fs.unlinkSync(path.join(reportsDir, existingReports.pop()));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Clean up old screenshots
|
|
43
|
-
const existingScreenshots = fs
|
|
44
|
-
.readdirSync(screenshotsDir)
|
|
45
|
-
.filter((f) => f.endsWith('.png') || f.endsWith('.jpg'))
|
|
46
|
-
.sort(
|
|
47
|
-
(a, b) =>
|
|
48
|
-
fs.statSync(path.join(screenshotsDir, b)).mtime -
|
|
49
|
-
fs.statSync(path.join(screenshotsDir, a)).mtime
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
while (existingScreenshots.length >= maxReports) {
|
|
53
|
-
fs.unlinkSync(path.join(screenshotsDir, existingScreenshots.pop()));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
26
|
// Determine PASS/FAIL from cucumber JSON output
|
|
57
27
|
const jsonReportFile = path.join(reportsDir, 'cucumber_report.json');
|
|
58
28
|
let status = 'PASS';
|
|
@@ -86,6 +56,44 @@ const reportFileName = `${status}_cucumber_report_${process.env.TRIGGER}_${tag}_
|
|
|
86
56
|
if (fs.existsSync(jsonReportFile)) {
|
|
87
57
|
fs.copyFileSync(jsonReportFile, path.join(reportsDir, reportFileName));
|
|
88
58
|
console.log(`Report saved: ${reportFileName}`);
|
|
59
|
+
|
|
60
|
+
// Persist metadata to database
|
|
61
|
+
(async () => {
|
|
62
|
+
try {
|
|
63
|
+
const { PrismaClient } = require('@prisma/client');
|
|
64
|
+
const prisma = new PrismaClient();
|
|
65
|
+
|
|
66
|
+
const triggerType = process.env.TRIGGER || 'command-line-trigger';
|
|
67
|
+
const builtInTriggers = ['manual-trigger', 'command-line-trigger', 'undefined'];
|
|
68
|
+
let cronJobId = null;
|
|
69
|
+
|
|
70
|
+
if (!builtInTriggers.includes(triggerType)) {
|
|
71
|
+
const job = await prisma.cronJob.findUnique({ where: { taskName: triggerType } });
|
|
72
|
+
if (job) cronJobId = job.id;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const rawTag = process.env.TAG || '@all-tests';
|
|
76
|
+
const tags = rawTag.replace(/^\(|\)$/g, '');
|
|
77
|
+
|
|
78
|
+
await prisma.report.upsert({
|
|
79
|
+
where: { fileName: reportFileName },
|
|
80
|
+
create: {
|
|
81
|
+
fileName: reportFileName,
|
|
82
|
+
status,
|
|
83
|
+
tags,
|
|
84
|
+
triggerType,
|
|
85
|
+
runners: runnerCount,
|
|
86
|
+
cronJobId
|
|
87
|
+
},
|
|
88
|
+
update: {}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
await prisma.$disconnect();
|
|
92
|
+
console.log('Report metadata saved to database.');
|
|
93
|
+
} catch (e) {
|
|
94
|
+
console.error('Could not save report metadata to DB:', e.message);
|
|
95
|
+
}
|
|
96
|
+
})();
|
|
89
97
|
} else {
|
|
90
98
|
console.log('Skipping report save — no cucumber_report.json.');
|
|
91
99
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#!/bin/sh
|
|
2
2
|
# This file is part of Plum.
|
|
3
3
|
#
|
|
4
4
|
# Plum is free software: you can redistribute it and/or modify
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
#
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with Plum. If not, see https://www.gnu.org/licenses/.
|
|
16
|
-
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
echo "Running database migrations..."
|
|
19
|
+
npx prisma migrate deploy
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
pnpm-lock.yaml
|
|
21
|
-
yarn.lock
|
|
21
|
+
echo "Starting server..."
|
|
22
|
+
exec node server.js
|