diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c4d4545dab..28f382788a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -404,6 +404,7 @@ jobs: runs-on: ${{ matrix.runner }} permissions: contents: read + actions: write defaults: run: working-directory: ./e2e @@ -416,58 +417,75 @@ jobs: with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false submodules: 'recursive' token: ${{ steps.token.outputs.token }} - - name: Setup pnpm - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - - name: Setup Node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version-file: './e2e/.nvmrc' - cache: 'pnpm' - cache-dependency-path: '**/pnpm-lock.yaml' - - name: Run setup typescript-sdk - run: pnpm install --frozen-lockfile && pnpm build - working-directory: ./open-api/typescript-sdk - if: ${{ !cancelled() }} - - name: Run setup web - run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync - working-directory: ./web - if: ${{ !cancelled() }} - - name: Run setup cli - run: pnpm install --frozen-lockfile && pnpm build - working-directory: ./cli - if: ${{ !cancelled() }} - - name: Install dependencies - run: pnpm install --frozen-lockfile - if: ${{ !cancelled() }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + - name: Build Docker images from cache + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml --profile test build - name: Start Docker Compose - run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + run: docker compose up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 if: ${{ !cancelled() }} - name: Run e2e tests (api & cli) - env: - VITEST_DISABLE_DOCKER_SETUP: true - run: pnpm test - if: ${{ !cancelled() }} - - name: Run e2e tests (maintenance) - env: - VITEST_DISABLE_DOCKER_SETUP: true - run: pnpm test:maintenance + run: docker compose --profile test run --rm e2e-runner pnpm test if: ${{ !cancelled() }} - name: Capture Docker logs if: always() run: docker compose logs --no-color > docker-compose-logs.txt + - name: Archive Docker logs + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + if: always() + with: + name: e2e-server-docker-logs-${{ matrix.runner }} + path: e2e/docker-compose-logs.txt + e2e-tests-server-maintenance: + name: End-to-End Tests (Server Maintenance) + needs: pre-job + if: ${{ fromJSON(needs.pre-job.outputs.should_run).e2e == true || fromJSON(needs.pre-job.outputs.should_run).server == true || fromJSON(needs.pre-job.outputs.should_run).cli == true }} + runs-on: ${{ matrix.runner }} + permissions: + contents: read + actions: write + defaults: + run: working-directory: ./e2e + strategy: + matrix: + runner: [ubuntu-latest, ubuntu-24.04-arm] + steps: + - id: token + uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + with: + app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} + private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + submodules: 'recursive' + token: ${{ steps.token.outputs.token }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + - name: Build Docker images from cache + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml --profile test build + - name: Start Docker Compose + run: docker compose up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + if: ${{ !cancelled() }} + - name: Run e2e tests (maintenance) + run: docker compose --profile test run --rm e2e-runner pnpm test:maintenance + if: ${{ !cancelled() }} + - name: Capture Docker logs + if: always() + run: docker compose logs --no-color > docker-compose-logs.txt - name: Archive Docker logs uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: always() with: - name: e2e-server-docker-logs-${{ matrix.runner }} + name: e2e-server-maintenance-docker-logs-${{ matrix.runner }} path: e2e/docker-compose-logs.txt e2e-tests-web: name: End-to-End Tests (Web) @@ -476,6 +494,7 @@ jobs: runs-on: ${{ matrix.runner }} permissions: contents: read + actions: write defaults: run: working-directory: ./e2e @@ -488,38 +507,21 @@ jobs: with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false submodules: 'recursive' token: ${{ steps.token.outputs.token }} - - name: Setup pnpm - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - - name: Setup Node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version-file: './e2e/.nvmrc' - cache: 'pnpm' - cache-dependency-path: '**/pnpm-lock.yaml' - - name: Run setup typescript-sdk - run: pnpm install --frozen-lockfile && pnpm build - working-directory: ./open-api/typescript-sdk - if: ${{ !cancelled() }} - - name: Install dependencies - run: pnpm install --frozen-lockfile - if: ${{ !cancelled() }} - - name: Install Playwright Browsers - run: pnpm exec playwright install chromium --only-shell - if: ${{ !cancelled() }} - - name: Docker build - run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + - name: Build Docker images from cache + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml --profile test build + - name: Start Docker Compose + run: docker compose up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 if: ${{ !cancelled() }} - name: Run e2e tests (web) - env: - PLAYWRIGHT_DISABLE_WEBSERVER: true - run: pnpm test:web + run: docker compose --profile test run --rm e2e-runner pnpm test:web if: ${{ !cancelled() }} - name: Archive e2e test (web) results uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 @@ -527,10 +529,50 @@ jobs: with: name: e2e-web-test-results-${{ matrix.runner }} path: e2e/playwright-report/ + - name: Capture Docker logs + if: always() + run: docker compose logs --no-color > docker-compose-logs.txt + - name: Archive Docker logs + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + if: always() + with: + name: e2e-web-docker-logs-${{ matrix.runner }} + path: e2e/docker-compose-logs.txt + e2e-tests-web-ui: + name: End-to-End Tests (Web UI) + needs: pre-job + if: ${{ fromJSON(needs.pre-job.outputs.should_run).e2e == true || fromJSON(needs.pre-job.outputs.should_run).web == true }} + runs-on: ${{ matrix.runner }} + permissions: + contents: read + actions: write + defaults: + run: + working-directory: ./e2e + strategy: + matrix: + runner: [ubuntu-latest, ubuntu-24.04-arm] + steps: + - id: token + uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + with: + app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} + private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + submodules: 'recursive' + token: ${{ steps.token.outputs.token }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + - name: Build Docker images from cache + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml --profile test build + - name: Start Docker Compose + run: docker compose up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + if: ${{ !cancelled() }} - name: Run ui tests (web) - env: - PLAYWRIGHT_DISABLE_WEBSERVER: true - run: pnpm test:web:ui + run: docker compose --profile test run --rm e2e-runner pnpm test:web:ui if: ${{ !cancelled() }} - name: Archive ui test (web) results uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 @@ -538,10 +580,50 @@ jobs: with: name: e2e-ui-test-results-${{ matrix.runner }} path: e2e/playwright-report/ + - name: Capture Docker logs + if: always() + run: docker compose logs --no-color > docker-compose-logs.txt + - name: Archive Docker logs + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + if: always() + with: + name: e2e-web-ui-docker-logs-${{ matrix.runner }} + path: e2e/docker-compose-logs.txt + e2e-tests-web-maintenance: + name: End-to-End Tests (Web Maintenance) + needs: pre-job + if: ${{ fromJSON(needs.pre-job.outputs.should_run).e2e == true || fromJSON(needs.pre-job.outputs.should_run).web == true }} + runs-on: ${{ matrix.runner }} + permissions: + contents: read + actions: write + defaults: + run: + working-directory: ./e2e + strategy: + matrix: + runner: [ubuntu-latest, ubuntu-24.04-arm] + steps: + - id: token + uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1 + with: + app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} + private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + submodules: 'recursive' + token: ${{ steps.token.outputs.token }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + - name: Build Docker images from cache + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml --profile test build + - name: Start Docker Compose + run: docker compose up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + if: ${{ !cancelled() }} - name: Run maintenance tests - env: - PLAYWRIGHT_DISABLE_WEBSERVER: true - run: pnpm test:web:maintenance + run: docker compose --profile test run --rm e2e-runner pnpm test:web:maintenance if: ${{ !cancelled() }} - name: Archive maintenance tests (web) results uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 @@ -552,16 +634,22 @@ jobs: - name: Capture Docker logs if: always() run: docker compose logs --no-color > docker-compose-logs.txt - working-directory: ./e2e - name: Archive Docker logs uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: always() with: - name: e2e-web-docker-logs-${{ matrix.runner }} + name: e2e-web-maintenance-docker-logs-${{ matrix.runner }} path: e2e/docker-compose-logs.txt success-check-e2e: name: End-to-End Tests Success - needs: [e2e-tests-server-cli, e2e-tests-web] + needs: + [ + e2e-tests-server-cli, + e2e-tests-server-maintenance, + e2e-tests-web, + e2e-tests-web-ui, + e2e-tests-web-maintenance, + ] permissions: {} runs-on: ubuntu-latest if: always() diff --git a/Makefile b/Makefile index 4d76913d8f..2b2fe767cd 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ e2e-update: @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans e2e-down: - docker compose -f ./e2e/docker-compose.yml down --remove-orphans + docker compose -f ./e2e/docker-compose.yml --profile test down --remove-orphans prod: @trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --remove-orphans @@ -101,10 +101,30 @@ check-web: pnpm --filter immich-web run check:svelte test-%: pnpm --filter $(call map-package,$*) run test -test-e2e: - docker compose -f ./e2e/docker-compose.yml build - pnpm --filter immich-e2e run test - pnpm --filter immich-e2e run test:web +test-e2e: build-e2e test-e2e-server test-e2e-server-maintenance test-e2e-web test-e2e-web-ui test-e2e-web-maintenance + +test-e2e-server: + docker compose -f ./e2e/docker-compose.yml up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + docker compose -f ./e2e/docker-compose.yml --profile test run --rm e2e-runner pnpm test + +test-e2e-server-maintenance: + docker compose -f ./e2e/docker-compose.yml up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + docker compose -f ./e2e/docker-compose.yml --profile test run --rm e2e-runner pnpm test:maintenance + +test-e2e-web: + docker compose -f ./e2e/docker-compose.yml up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + docker compose -f ./e2e/docker-compose.yml --profile test run --rm e2e-runner pnpm test:web + +test-e2e-web-ui: + docker compose -f ./e2e/docker-compose.yml up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + docker compose -f ./e2e/docker-compose.yml --profile test run --rm e2e-runner pnpm test:web:ui + +test-e2e-web-maintenance: + docker compose -f ./e2e/docker-compose.yml up -d --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 + docker compose -f ./e2e/docker-compose.yml --profile test run --rm e2e-runner pnpm test:web:maintenance + +build-e2e: + docker compose -f ./e2e/docker-compose.yml --profile test build test-medium: docker run \ --rm \ diff --git a/e2e-auth-server/auth-server.ts b/e2e-auth-server/auth-server.ts index 9aef56510d..a94c8ae22c 100644 --- a/e2e-auth-server/auth-server.ts +++ b/e2e-auth-server/auth-server.ts @@ -71,6 +71,7 @@ const setup = async () => { const redirectUris = [ 'http://127.0.0.1:2285/auth/login', 'https://photos.immich.app/oauth/mobile-redirect', + ...(process.env.EXTRA_REDIRECT_URIS?.split(',').filter(Boolean) ?? []), ]; const port = 2286; const host = '0.0.0.0'; diff --git a/e2e-auth-server/package.json b/e2e-auth-server/package.json index 73ede1b7c4..8005abc749 100644 --- a/e2e-auth-server/package.json +++ b/e2e-auth-server/package.json @@ -1,6 +1,7 @@ { "name": "@immich/e2e-auth-server", "version": "0.1.0", + "packageManager": "pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017", "type": "module", "main": "auth-server.ts", "scripts": { diff --git a/e2e/Dockerfile.playwright b/e2e/Dockerfile.playwright new file mode 100644 index 0000000000..aeb3470cf4 --- /dev/null +++ b/e2e/Dockerfile.playwright @@ -0,0 +1,40 @@ +FROM node:22-bookworm-slim + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" + +RUN corepack enable && corepack prepare pnpm@10.30.3 --activate + +RUN apt-get update && apt-get install -y --no-install-recommends \ + docker.io \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml .pnpmfile.cjs ./ +COPY open-api/typescript-sdk/package.json open-api/typescript-sdk/ +COPY cli/package.json cli/ +COPY web/package.json web/ +COPY e2e/package.json e2e/ +COPY e2e-auth-server/package.json e2e-auth-server/ + +RUN pnpm install --frozen-lockfile + +COPY open-api/typescript-sdk/ open-api/typescript-sdk/ +RUN pnpm --filter @immich/sdk build + +COPY cli/ cli/ +RUN pnpm --filter @immich/cli build && ln -s /app/cli/bin/immich /app/cli/node_modules/.bin/immich + +COPY web/svelte.config.js web/vite.config.ts web/tsconfig.json web/ +COPY web/src/ web/src/ +COPY web/static/ web/static/ +RUN pnpm --filter immich-web exec svelte-kit sync + +COPY e2e/ e2e/ +COPY e2e-auth-server/ e2e-auth-server/ + +RUN pnpm --filter immich-e2e exec playwright install --with-deps chromium + +WORKDIR /app/e2e diff --git a/e2e/Dockerfile.playwright.dockerignore b/e2e/Dockerfile.playwright.dockerignore new file mode 100644 index 0000000000..9e96ca5a4f --- /dev/null +++ b/e2e/Dockerfile.playwright.dockerignore @@ -0,0 +1,23 @@ +.vscode/ +.github/ +.git/ +*.log +*.tmp +*.temp + +**/node_modules/ +**/.pnpm-store/ +**/dist/ +**/coverage/ +**/build/ + +design/ +docker/ +docs/ +fastlane/ +machine-learning/ +misc/ +mobile/ +server/ +plugins/ +i18n/ diff --git a/e2e/docker-compose.ci.yml b/e2e/docker-compose.ci.yml new file mode 100644 index 0000000000..efcc690180 --- /dev/null +++ b/e2e/docker-compose.ci.yml @@ -0,0 +1,23 @@ +name: immich-e2e + +services: + immich-server: + build: + cache_from: + - type=gha,scope=e2e-server-${RUNNER_ARCH:-X64} + cache_to: + - type=gha,mode=max,scope=e2e-server-${RUNNER_ARCH:-X64} + + e2e-auth-server: + build: + cache_from: + - type=gha,scope=e2e-auth-${RUNNER_ARCH:-X64} + cache_to: + - type=gha,mode=max,scope=e2e-auth-${RUNNER_ARCH:-X64} + + e2e-runner: + build: + cache_from: + - type=gha,scope=e2e-runner-${RUNNER_ARCH:-X64} + cache_to: + - type=gha,mode=max,scope=e2e-runner-${RUNNER_ARCH:-X64} diff --git a/e2e/docker-compose.yml b/e2e/docker-compose.yml index 957de4698e..32a61e048e 100644 --- a/e2e/docker-compose.yml +++ b/e2e/docker-compose.yml @@ -5,6 +5,8 @@ services: container_name: immich-e2e-auth-server build: context: ../e2e-auth-server + environment: + EXTRA_REDIRECT_URIS: http://immich-server:2285/auth/login ports: - 2286:2286 @@ -65,3 +67,29 @@ services: timeout: 5s retries: 30 start_period: 10s + + e2e-runner: + container_name: immich-e2e-runner + build: + context: ../ + dockerfile: e2e/Dockerfile.playwright + network_mode: 'service:immich-server' + shm_size: 1gb + environment: + PLAYWRIGHT_DB_HOST: database + PLAYWRIGHT_DB_PORT: '5432' + PLAYWRIGHT_DISABLE_WEBSERVER: 'true' + PLAYWRIGHT_AUTH_SERVER_URL: http://e2e-auth-server:2286 + VITEST_DISABLE_DOCKER_SETUP: 'true' + CI: '${CI:-}' + volumes: + - ./test-assets:/app/e2e/test-assets + - ./playwright-report:/app/e2e/playwright-report + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + immich-server: + condition: service_started + database: + condition: service_healthy + profiles: + - test diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 040546b7bb..2e9b920b6e 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -7,6 +7,7 @@ dotenv.config({ quiet: true, path: resolve(import.meta.dirname, '.env') }); export const playwrightHost = process.env.PLAYWRIGHT_HOST ?? '127.0.0.1'; export const playwrightDbHost = process.env.PLAYWRIGHT_DB_HOST ?? '127.0.0.1'; +export const playwrightDbPort = process.env.PLAYWRIGHT_DB_PORT ?? '5435'; export const playwriteBaseUrl = process.env.PLAYWRIGHT_BASE_URL ?? `http://${playwrightHost}:2285`; export const playwriteSlowMo = Number.parseInt(process.env.PLAYWRIGHT_SLOW_MO ?? '0'); export const playwrightDisableWebserver = process.env.PLAYWRIGHT_DISABLE_WEBSERVER; @@ -43,7 +44,7 @@ const config: PlaywrightTestConfig = { use: { ...devices['Desktop Chrome'] }, testDir: './src/ui/specs', fullyParallel: true, - workers: process.env.CI ? 3 : Math.max(1, Math.round(cpus().length * 0.75) - 1), + workers: process.env.CI ? 3 : Math.min(10, Math.max(1, Math.round(cpus().length * 0.75) - 1)), }, { name: 'maintenance', diff --git a/e2e/src/specs/server/api/oauth.e2e-spec.ts b/e2e/src/specs/server/api/oauth.e2e-spec.ts index ae9064375f..53ae9c4c3a 100644 --- a/e2e/src/specs/server/api/oauth.e2e-spec.ts +++ b/e2e/src/specs/server/api/oauth.e2e-spec.ts @@ -15,7 +15,7 @@ import { beforeAll, describe, expect, it } from 'vitest'; const authServer = { internal: 'http://e2e-auth-server:2286', - external: 'http://127.0.0.1:2286', + external: process.env.PLAYWRIGHT_AUTH_SERVER_URL ?? 'http://127.0.0.1:2286', }; const mobileOverrideRedirectUri = 'https://photos.immich.app/oauth/mobile-redirect'; diff --git a/e2e/src/specs/server/api/shared-link.e2e-spec.ts b/e2e/src/specs/server/api/shared-link.e2e-spec.ts index 00c455d6cb..496c9c4848 100644 --- a/e2e/src/specs/server/api/shared-link.e2e-spec.ts +++ b/e2e/src/specs/server/api/shared-link.e2e-spec.ts @@ -106,7 +106,7 @@ describe('/shared-links', () => { const resp = await request(shareUrl).get(`/${linkWithAssets.key}`); expect(resp.status).toBe(200); expect(resp.header['content-type']).toContain('text/html'); - expect(resp.text).toContain(` runQueueCommandLegacy({ name, queueCommandDto }, { headers: asBearerAuth(accessToken) }), - setAuthCookies: async (context: BrowserContext, accessToken: string, domain = playwrightHost) => + setAuthCookies: async (context: BrowserContext, accessToken: string, domain = playwrightHost, url?: string) => { + const origin = url ? { url } : { domain, path: '/' }; await context.addCookies([ { name: 'immich_access_token', value: accessToken, - domain, - path: '/', + ...origin, expires: 2_058_028_213, httpOnly: true, secure: false, @@ -537,8 +537,7 @@ export const utils = { { name: 'immich_auth_type', value: 'password', - domain, - path: '/', + ...origin, expires: 2_058_028_213, httpOnly: true, secure: false, @@ -547,14 +546,14 @@ export const utils = { { name: 'immich_is_authenticated', value: 'true', - domain, - path: '/', + ...origin, expires: 2_058_028_213, httpOnly: false, secure: false, sameSite: 'Lax', }, - ]), + ]); + }, setMaintenanceAuthCookie: async (context: BrowserContext, token: string, domain = '127.0.0.1') => await context.addCookies([