super-productivity/package.json
Johannes Millan 40d7118e17 feat(e2e): add Docker-based E2E test isolation
Add Docker setup for running E2E tests with the Angular dev server
containerized while Playwright runs on the host. Supports multiple
instances via configurable ports.

New files:
- Dockerfile.e2e.dev: Dev server image
- docker-compose.e2e.yaml: E2E orchestration config
- scripts/wait-for-app.sh: Health check script

New npm scripts:
- e2e:docker: Run E2E with containerized app
- e2e:docker:webdav: Same but includes WebDAV for sync tests

Usage: APP_PORT=4343 npm run e2e:docker
2026-01-04 17:09:39 +01:00

286 lines
16 KiB
JSON

{
"name": "superProductivity",
"version": "16.8.2",
"description": "ToDo list and Time Tracking",
"keywords": [
"ToDo",
"Task Management",
"Jira",
"GitHub",
"Time Tracking"
],
"homepage": "https://super-productivity.com",
"repository": {
"type": "git",
"url": "git://github.com/johannesjo/super-productivity.git"
},
"license": "MIT",
"author": "Johannes Millan <contact@super-productivity.com> (http://super-productivity.com)",
"main": "./electron/main.js",
"scripts": {
"env": "node ./tools/load-env.js",
"assemble:android:prod": "cd android && ./gradlew assembleRelease && cd ..",
"assemble:android:stage": "cd android && ./gradlew assembleDebug && cd ..",
"prebuild": "npm run env && node ./tools/git-version.js && npm run build:packages",
"prepare": "husky && ts-patch install && npm run plugin-api:build",
"build": "npm run buildAllElectron:noTests:prod",
"build:packages": "node ./packages/build-packages.js",
"buildAllElectron:noTests:prod": "npm run lint && npm run buildFrontend:prod:es6 && npm run electron:build",
"buildAllElectron:prod": "npm run env && npm run preCheck && npm run buildFrontend:prod:es6 && npm run electron:build",
"buildAllElectron:stage": "npm run preCheck && npm run buildFrontend:stage:es6 && npm run electron:build",
"buildFrontend:prod:es6": "npm run prebuild && cross-env BROWSERSLIST_ENV='modern' ng build --configuration production && npm run removeWOFF1",
"buildFrontend:prod:watch": "npm run prebuild && ng build --configuration production --watch",
"buildFrontend:prodWeb": "npm run prebuild && ng build --configuration productionWeb",
"buildFrontend:stage:es6": "npm run prebuild && cross-env BROWSERSLIST_ENV='modern' ng build --configuration stage && npm run removeWOFF1",
"buildFrontend:stageWeb": "npm run prebuild && ng build --configuration stageWeb",
"buildFrontend:stageWeb:unminified": "npm run prebuild && ng build --configuration stageWeb --optimization=false --aot=false",
"dist": "npm run buildAllElectron:prod && electron-builder",
"dist:android": "npm run buildFrontend:stageWeb:unminified && npm run sync:android && npm run assemble:android:stage && echo 'Staging Android APK generated at android/app/build/outputs/apk/debug/'",
"dist:android:prod": "npm run buildFrontend:prodWeb && npm run sync:android && npm run assemble:android:prod && echo 'Production Android APK generated at android/app/build/outputs/apk/release/'",
"dist:linuxAndWin": "npm run buildAllElectron:prod && electron-builder --linux --win",
"dist:mac:dl": "cp tools/mac-profiles/dl.provisionprofile embedded.provisionprofile && electron-builder --mac",
"dist:mac:mas": "cp tools/mac-profiles/mas.provisionprofile embedded.provisionprofile; electron-builder --mac mas --config=build/electron-builder.mas.yaml",
"dist:mac:mas:buildOnly": "electron-builder --config=build/electron-builder.mas.yaml",
"dist:mac:mas:dev": "cp tools/mac-profiles/mas-dev.provisionprofile embedded.provisionprofile; electron-builder --mac mas-dev --config=build/electron-builder.mas-dev.yaml",
"dist:mac:mas:x64": "cp tools/mac-profiles/mas.provisionprofile embedded.provisionprofile; electron-builder --mac mas --config=build/electron-builder.mas.yaml --x64",
"dist:only": "electron-builder",
"dist:win": "npm run buildAllElectron:noTests:prod && electron-builder --win",
"dist:win:appx": "npm run buildAllElectron:prod && electron-builder --win --config=build/electron-builder.appx.yaml",
"dist:win:only": "electron-builder --win",
"dist:win:store": "git pull && npm run && copy electron-builder.win-store.yaml electron-builder.yaml && npm run dist:win && git checkout electron-builder.yaml || git checkout electron-builder.yaml",
"droid": "npm run buildFrontend:stageWeb:unminified && npx cap sync",
"pree2e": "npm run plugins:build:silent",
"e2e": "npx playwright test --config e2e/playwright.config.ts --reporter=line",
"e2e:ui": "npx playwright test --config e2e/playwright.config.ts --ui",
"e2e:file": "npx playwright test --config e2e/playwright.config.ts --reporter=list",
"e2e:debug": "npx playwright test --config e2e/playwright.config.ts --debug",
"e2e:headed": "npx playwright test --config e2e/playwright.config.ts --headed",
"e2e:show-report": "npx playwright show-report .tmp/e2e-test-results/playwright-report",
"e2e:report": "PLAYWRIGHT_HTML_REPORT=1 npx playwright test --config e2e/playwright.config.ts",
"e2e:webdav": "docker compose up -d webdav && ./scripts/wait-for-webdav.sh && npm run e2e -- --grep webdav; docker compose down",
"e2e:docker": "docker compose -f docker-compose.e2e.yaml up -d app && ./scripts/wait-for-app.sh && E2E_BASE_URL=http://localhost:${APP_PORT:-4242} npm run e2e; docker compose -f docker-compose.e2e.yaml down",
"e2e:docker:webdav": "docker compose -f docker-compose.e2e.yaml up -d && ./scripts/wait-for-app.sh && ./scripts/wait-for-webdav.sh && E2E_BASE_URL=http://localhost:${APP_PORT:-4242} npm run e2e; docker compose -f docker-compose.e2e.yaml down",
"electron": "NODE_ENV=PROD electron .",
"electron:build": "tsc -p electron/tsconfig.electron.json",
"electron:watch": "tsc -p electron/tsconfig.electron.json --watch",
"electronBuilderOnly": "electron-builder",
"empty": "echo 'EMPTY YEAH'",
"install:android": "adb install -r android/app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk && echo 'Staging APK installed successfully.'",
"install:android:prod": "adb install -r android/app/build/outputs/apk/fdroid/release/app-fdroid-release.apk && echo 'Production APK installed successfully.'",
"int": "node ./tools/extract-i18n-single.js",
"int:clean": "ngx-translate-extract --input ./src --output ./src/assets/i18n/*.json --clean --sort --format namespaced-json --marker _",
"int:find": "ngx-translate-extract --input ./src --output ./src/assets/i18n/*.json --sort --format namespaced-json --marker _",
"int:test": "node ./tools/test-lng-files.js",
"int:watch": "node ./tools/extract-i18n-watch.js",
"lint": "npm run lint:ts && npm run lint:scss",
"lint:ts": "ng lint",
"lint:scss": "stylelint \"**/*.scss\" -- --custom-formatter @csstools/stylelint-formatter-github",
"localInstall": "sudo echo 'Starting local install' && rm -Rf ./.tmp/angular-dist/ && rm -Rf ./.tmp/app-builds/ && npm run buildAllElectron:stage && electron-builder --linux deb && sudo dpkg -i .tmp/app-builds/superProductivity*.deb",
"localInstall:mac": "sudo echo 'Starting local install MAC. Don`t forget APPLEID & APPLEIDPASS !!' && npm run buildAllElectron:noTests:prod && sudo echo '' && electron-builder && sudo cp -rf .tmp/app-builds/mac/superProductivity.app/ /Applications/superProductivity.app",
"localInstall:prod": "sudo echo 'Starting local install PROD' && rm -Rf ./.tmp/angular-dist/ && rm -Rf ./.tmp/app-builds/ && npm run buildAllElectron:prod && electron-builder --linux deb && sudo dpkg -i .tmp/app-builds/superProductivity*.deb",
"localInstall:quick": "sudo echo 'Starting local install QUICK' && rm -Rf ./.tmp/angular-dist/ && rm -Rf ./.tmp/app-builds/ && npm run buildFrontend:stage:es6 && npm run electron:build && electron-builder --linux deb && sudo dpkg -i .tmp/app-builds/superProductivity*.deb",
"localInstall:test:snap": "sudo echo 'Starting local install SNAP QUICK' && rm -Rf ./.tmp/angular-dist/ && rm -Rf ./.tmp/app-builds/ && npm run buildFrontend:stage:es6 && npm run electron:build && electron-builder --linux snap && sudo snap install --dangerous .tmp/app-builds/superProductivity*.snap",
"ng": "ng",
"pack": "electron-builder --dir",
"preCheck": "npm run lint && npm run test & npm run int:test && npm run e2e",
"release": "npm run release.changelog && npm run dist",
"release.changelog": "conventional-changelog -i CHANGELOG.md -s -p angular",
"removeWOFF1": "node ./tools/remove-woff.js",
"serveProd": "ng serve --configuration production",
"start": "npm run electron:build && cross-env NODE_ENV=DEV electron .",
"startFrontend": "npm run env && ng serve",
"startFrontend:e2e": "npm run env && ng serve --port=4242",
"startFrontend:prod": "npm run env && ng serve --configuration production",
"startFrontend:stage": "npm run env && ng serve --configuration stage",
"sync:android": "npx cap sync android",
"stats": "ng build --configuration production --source-map --stats-json && npx esbuild-visualizer --metadata .tmp/angular-dist/stats.json && xdg-open stats.html",
"test": "cross-env TZ='Europe/Berlin' ng test --watch=false && npm run test:tz:ci",
"test:once": "cross-env TZ='Europe/Berlin' ng test --watch=false",
"test:watch": "cross-env TZ='Europe/Berlin' ng test --browsers ChromeHeadless",
"test:tz:ci": "npm run test:tz:la",
"test:tz:la": "cross-env TZ='America/Los_Angeles' ng test --watch=false --include='**/*.spec.ts'",
"test:tz:tokyo": "cross-env TZ='Asia/Tokyo' ng test --watch=false --include='**/*.spec.ts'",
"test:tz:sydney": "cross-env TZ='Australia/Sydney' ng test --watch=false --include='**/*.spec.ts'",
"test:tz:utc": "cross-env TZ='UTC' ng test --watch=false --include='**/*.spec.ts'",
"test:tz:all": "npm run test && npm run test:tz:la && npm run test:tz:tokyo && npm run test:tz:sydney && npm run test:tz:utc",
"test:date-utils": "cross-env TZ='Europe/Berlin' ng test --watch=false --include='src/app/util/**/format-*.spec.ts' --include='src/app/util/**/date-*.spec.ts'",
"test:date-utils:tz": "npm run test:date-utils && cross-env TZ='America/Los_Angeles' npm run test:date-utils && cross-env TZ='Asia/Tokyo' npm run test:date-utils",
"version": "npm run prebuild && npm run release.changelog && node ./tools/bump-android-version.js && git add -A",
"prettier": "pretty-quick",
"prettier:file": "prettier --write",
"lint:file": "ng lint --lint-file-patterns",
"test:file": "cross-env TZ='Europe/Berlin' ng test --watch=false --include",
"test:fast": "cross-env TZ='Europe/Berlin' NODE_OPTIONS='--max-old-space-size=4096' ng test --watch=false --no-code-coverage --source-map=false",
"test:fast:watch": "cross-env TZ='Europe/Berlin' NODE_OPTIONS='--max-old-space-size=4096' ng test --browsers ChromeHeadless --no-code-coverage --source-map=false",
"test:shard:features": "cross-env TZ='Europe/Berlin' ng test --watch=false --include='src/app/features/**/*.spec.ts'",
"test:shard:pfapi": "cross-env TZ='Europe/Berlin' ng test --watch=false --include='src/app/pfapi/**/*.spec.ts'",
"test:shard:ui": "cross-env TZ='Europe/Berlin' ng test --watch=false --include='src/app/ui/**/*.spec.ts'",
"test:shard:core": "cross-env TZ='Europe/Berlin' ng test --watch=false --include='src/app/core/**/*.spec.ts'",
"test:shard:util": "cross-env TZ='Europe/Berlin' ng test --watch=false --include='src/app/util/**/*.spec.ts'",
"checkFile": "node tools/check-file.js",
"clean:translations": "node ./tools/clean-translations.js",
"plugin-api:build": "cd packages/plugin-api && npm run build",
"plugin-api:build:watch": "cd packages/plugin-api && npm run build:watch",
"vite-plugin:build": "cd packages/vite-plugin && npm run build",
"plugins:build": "npm run vite-plugin:build && cd packages/plugin-dev && npm run build:all",
"plugins:build:silent": "npm run vite-plugin:build && cd packages/plugin-dev && npm run build:all:silent"
},
"resolutions": {
"sass": "1.32.6",
"@ctrl/tinycolor": "4.1.0"
},
"dependencies": {
"electron-dl": "^3.5.2",
"electron-localshortcut": "^3.2.1",
"electron-log": "^5.4.3",
"electron-window-state": "^5.0.3",
"fs-extra": "^11.3.2",
"hash-wasm": "^4.12.0",
"node-fetch": "^2.7.0"
},
"devDependencies": {
"@angular-builders/custom-webpack": "^20.0.0",
"@angular-devkit/build-angular": "^20.3.13",
"@angular-eslint/builder": "^20.5.0",
"@angular-eslint/eslint-plugin": "^20.5.0",
"@angular-eslint/eslint-plugin-template": "^20.5.0",
"@angular-eslint/schematics": "^20.5.0",
"@angular-eslint/template-parser": "^20.5.0",
"@angular/animations": "^20.3.15",
"@angular/cdk": "^20.2.10",
"@angular/cli": "^20.3.13",
"@angular/common": "^20.3.15",
"@angular/compiler": "^20.3.15",
"@angular/compiler-cli": "^20.3.15",
"@angular/core": "^20.3.15",
"@angular/forms": "^20.3.15",
"@angular/language-service": "^20.3.15",
"@angular/material": "^20.2.10",
"@angular/platform-browser": "^20.3.15",
"@angular/platform-browser-dynamic": "^20.3.15",
"@angular/platform-server": "^20.3.15",
"@angular/router": "^20.3.15",
"@angular/service-worker": "^20.3.15",
"@capacitor/android": "^7.4.4",
"@capacitor/app": "^7.1.0",
"@capacitor/cli": "^7.4.4",
"@capacitor/core": "^7.4.3",
"@capacitor/filesystem": "^7.1.1",
"@capacitor/local-notifications": "^7.0.1",
"@capacitor/share": "^7.0.2",
"@capawesome/capacitor-android-dark-mode-support": "^7.0.0",
"@capawesome/capacitor-background-task": "^7.0.1",
"@csstools/stylelint-formatter-github": "^1.0.0",
"@dotenv-run/cli": "^1.3.6",
"@electron/notarize": "^3.1.1",
"@fontsource/open-sans": "^5.2.6",
"@nextcloud/cdav-library": "^1.5.3",
"@ngrx/effects": "^20.0.0",
"@ngrx/entity": "^20.0.0",
"@ngrx/schematics": "^20.1.0",
"@ngrx/store": "20.0.0",
"@ngrx/store-devtools": "^20.0.0",
"@ngx-formly/core": "7.0.0",
"@ngx-formly/material": "7.0.0",
"@ngx-translate/core": "^17.0.0",
"@ngx-translate/http-loader": "^17.0.0",
"@playwright/test": "^1.56.1",
"@schematics/angular": "^20.1.4",
"@types/electron": "^1.4.38",
"@types/electron-localshortcut": "^3.1.3",
"@types/file-saver": "^2.0.5",
"@types/jasmine": "^3.10.2",
"@types/jasminewd2": "~2.0.13",
"@types/node": "20.12.4",
"@types/node-fetch": "^2.6.6",
"@types/object-path": "^0.11.4",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "7.18.0",
"@typescript-eslint/types": "^8.17.0",
"@typescript-eslint/utils": "^8.51.0",
"angular-material-css-vars": "^9.1.1",
"baseline-browser-mapping": "^2.9.11",
"canvas-confetti": "^1.9.4",
"chai": "^5.1.2",
"chart.js": "^4.4.7",
"chrono-node": "^2.8.3",
"clipboard": "^2.0.11",
"conventional-changelog-cli": "^5.0.0",
"core-js": "^3.39.0",
"cross-env": "^7.0.3",
"detect-it": "^4.0.1",
"electron": "37.10.3",
"electron-builder": "^26.3.3",
"eslint": "^8.57.1",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsdoc": "61.4.1",
"eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-prettier": "^5.2.1",
"fflate": "^0.8.2",
"file-saver": "^2.0.5",
"glob": "^9.3.5",
"husky": "^9.1.7",
"ical.js": "^2.1.0",
"idb": "^8.0.3",
"jasmine-core": "^5.10.0",
"jasmine-marbles": "^0.9.2",
"jasmine-spec-reporter": "~7.0.0",
"jira2md": "git+https://github.com/johannesjo/J2M.git",
"karma": "~6.4.2",
"karma-chrome-launcher": "~3.2.0",
"karma-cli": "^2.0.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "^1.6.0",
"karma-spec-reporter": "^0.0.36",
"marked": "^12.0.2",
"nanoid": "^5.1.6",
"new-github-issue-url": "^1.1.0",
"ng2-charts": "^8.0.0",
"ngx-markdown": "^20.0.0",
"playwright": "^1.56.1",
"prettier": "^3.5.1",
"pretty-quick": "^4.1.1",
"query-string": "^7.1.3",
"rxjs": "^7.8.2",
"shepherd.js": "^11.2.0",
"spark-md5": "^3.0.2",
"stacktrace-js": "^2.0.2",
"start-server-and-test": "^2.0.9",
"stylelint": "^16.18.0",
"stylelint-config-recommended-scss": "^14.1.0",
"ts-node": "~10.9.2",
"ts-patch": "^3.3.0",
"tslib": "^2.7.0",
"typescript": "~5.8.3",
"typia": "^9.1.0"
},
"overrides": {
"ngx-markdown": {
"marked": "12.0.2"
},
"@conventional-changelog/git-client": "^2.5.1"
},
"optionalDependencies": {
"@lmdb/lmdb-darwin-x64": "^3.2.0",
"@lmdb/lmdb-linux-x64": "^3.4.3",
"@lmdb/lmdb-win32-x64": "^3.2.0",
"@rollup/rollup-darwin-x64": "4.53.3",
"@rollup/rollup-linux-x64-gnu": "4.27.4",
"@rollup/rollup-win32-x64-msvc": "4.52.3"
},
"workspaces": [
"packages/*"
],
"publish": [
{
"provider": "github",
"repo": "super-productivity",
"owner": "johannesjo"
}
],
"volta": {
"node": "22.18.0"
}
}