{
  "config": {
    "configFile": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/playwright.config.ts",
    "rootDir": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real",
    "forbidOnly": false,
    "fullyParallel": false,
    "globalSetup": null,
    "globalTeardown": null,
    "globalTimeout": 0,
    "grep": {},
    "grepInvert": null,
    "maxFailures": 0,
    "metadata": {
      "actualWorkers": 1
    },
    "preserveOutput": "always",
    "projects": [
      {
        "outputDir": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results",
        "repeatEach": 1,
        "retries": 0,
        "metadata": {
          "actualWorkers": 1
        },
        "id": "",
        "name": "",
        "testDir": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real",
        "testIgnore": [],
        "testMatch": [
          "/.*\\.spec\\.ts$/"
        ],
        "timeout": 90000
      }
    ],
    "quiet": false,
    "reporter": [
      [
        "list",
        null
      ],
      [
        "json",
        {
          "outputFile": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/results.json"
        }
      ]
    ],
    "reportSlowTests": {
      "max": 5,
      "threshold": 300000
    },
    "shard": null,
    "tags": [],
    "updateSnapshots": "missing",
    "updateSourceMethod": "patch",
    "version": "1.60.0",
    "workers": 1,
    "webServer": null
  },
  "suites": [
    {
      "title": "00-auth.spec.ts",
      "file": "00-auth.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "real login resolves manager membership and selected-store boundary",
          "ok": true,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 5803,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:07:34.311Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "auth-switcher",
                      "contentType": "application/json",
                      "body": "ewogICJhY3RvciI6ICJtYW5hZ2VyIiwKICAic3RvcmUiOiAiZmE0OWM5MjItYTQ4My0zNGNhLTkxMDYtMmU2NTY4ZDBhOTQ3IiwKICAicGVyc2lzdGVkIjogdHJ1ZQp9"
                    }
                  ]
                }
              ],
              "status": "expected"
            }
          ],
          "id": "4be2244f332125737752-c9fef29bc065cb250ca6",
          "file": "00-auth.spec.ts",
          "line": 3,
          "column": 5
        }
      ]
    },
    {
      "title": "10-schedule-api.spec.ts",
      "file": "10-schedule-api.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "real API enforces stale revisions, tenant child IDs, and DST copy preview/commit",
          "ok": true,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 819,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:07:40.691Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "dst-revision-tenancy",
                      "contentType": "application/json",
                      "body": "ewogICJvcmlnaW5hbCI6IHsKICAgICJpZCI6ICI3YTkwZGFmYy1lZDQ3LTQ4NWUtYjI2YS05MmViZWFjZDJlMmMiLAogICAgInN0b3JlX2lkIjogIjlkMzU1ODRlLTYxYjktMzZhZC1iNmI2LTAwZDc3NDc5NWEzMiIsCiAgICAic3RvcmVfbWVtYmVyc2hpcF9pZCI6ICI4OTdkZjJlNy00MjRhLTNjYjQtOWQ0Zi1jMDk0NDgxZDdhOWEiLAogICAgIm1lbWJlcl9uYW1lIjogIkUyRS0wMWY0ODQ0MDRlY2M0YzRkIFN0YWZmIiwKICAgICJwb3NpdGlvbl9pZCI6IG51bGwsCiAgICAicG9zaXRpb25fbmFtZSI6IG51bGwsCiAgICAic3RhcnRzX2F0IjogIjIwMjYtMDMtMDJUMTc6MDA6MDAuMDAwMDAwWiIsCiAgICAiZW5kc19hdCI6ICIyMDI2LTAzLTAzVDAxOjAwOjAwLjAwMDAwMFoiLAogICAgIm5vdGVzIjogIkUyRS0wMWY0ODQ0MDRlY2M0YzRkIERTVCBzb3VyY2UiLAogICAgInB1Ymxpc2hlZF9hdCI6IG51bGwsCiAgICAicmV2aXNpb24iOiAiMjAyNi0wOS0wNlQxOTowNzo0MC43NDc5MzNaIgogIH0sCiAgInVwZGF0ZWQiOiB7CiAgICAiaWQiOiAiN2E5MGRhZmMtZWQ0Ny00ODVlLWIyNmEtOTJlYmVhY2QyZTJjIiwKICAgICJzdG9yZV9pZCI6ICI5ZDM1NTg0ZS02MWI5LTM2YWQtYjZiNi0wMGQ3NzQ3OTVhMzIiLAogICAgInN0b3JlX21lbWJlcnNoaXBfaWQiOiAiODk3ZGYyZTctNDI0YS0zY2I0LTlkNGYtYzA5NDQ4MWQ3YTlhIiwKICAgICJtZW1iZXJfbmFtZSI6ICJFMkUtMDFmNDg0NDA0ZWNjNGM0ZCBTdGFmZiIsCiAgICAicG9zaXRpb25faWQiOiBudWxsLAogICAgInBvc2l0aW9uX25hbWUiOiBudWxsLAogICAgInN0YXJ0c19hdCI6ICIyMDI2LTAzLTAyVDE3OjAwOjAwLjAwMDAwMFoiLAogICAgImVuZHNfYXQiOiAiMjAyNi0wMy0wM1QwMTowMDowMC4wMDAwMDBaIiwKICAgICJub3RlcyI6ICJFMkUtMDFmNDg0NDA0ZWNjNGM0ZCBlZGl0ZWQiLAogICAgInB1Ymxpc2hlZF9hdCI6IG51bGwsCiAgICAicmV2aXNpb24iOiAiMjAyNi0wOS0wNlQxOTowNzo0MC44Njk3NzhaIgogIH0sCiAgImNvcGllZCI6IHsKICAgICJ3ZWVrX3N0YXJ0IjogIjIwMjYtMDMtMDkiLAogICAgInN0YXJ0c19hdCI6ICIyMDI2LTAzLTA5VDA3OjAwOjAwLjAwMDAwMFoiLAogICAgImVuZHNfYXQiOiAiMjAyNi0wMy0xNlQwNzowMDowMC4wMDAwMDBaIiwKICAgICJ0aW1lem9uZSI6ICJBbWVyaWNhL0xvc19BbmdlbGVzIiwKICAgICJzaGlmdHMiOiBbCiAgICAgIHsKICAgICAgICAiaWQiOiAiYzVhNDU4MDYtYjExOC00Y2U4LThmYTAtMmZhYjZmM2M4YjZhIiwKICAgICAgICAic3RvcmVfaWQiOiAiOWQzNTU4NGUtNjFiOS0zNmFkLWI2YjYtMDBkNzc0Nzk1YTMyIiwKICAgICAgICAic3RvcmVfbWVtYmVyc2hpcF9pZCI6ICI4OTdkZjJlNy00MjRhLTNjYjQtOWQ0Zi1jMDk0NDgxZDdhOWEiLAogICAgICAgICJtZW1iZXJfbmFtZSI6ICJFMkUtMDFmNDg0NDA0ZWNjNGM0ZCBTdGFmZiIsCiAgICAgICAgInBvc2l0aW9uX2lkIjogbnVsbCwKICAgICAgICAicG9zaXRpb25fbmFtZSI6IG51bGwsCiAgICAgICAgInN0YXJ0c19hdCI6ICIyMDI2LTAzLTA5VDE2OjAwOjAwLjAwMDAwMFoiLAogICAgICAgICJlbmRzX2F0IjogIjIwMjYtMDMtMTBUMDA6MDA6MDAuMDAwMDAwWiIsCiAgICAgICAgIm5vdGVzIjogIkUyRS0wMWY0ODQ0MDRlY2M0YzRkIGVkaXRlZCIsCiAgICAgICAgInB1Ymxpc2hlZF9hdCI6IG51bGwsCiAgICAgICAgInJldmlzaW9uIjogIjIwMjYtMDktMDZUMTk6MDc6NDEuMjA1NjE4WiIKICAgICAgfQogICAgXSwKICAgICJwdWJsaWNhdGlvbiI6IG51bGwKICB9LAogICJzcWwiOiBbCiAgICB7CiAgICAgICJpZCI6ICI3YTkwZGFmYy1lZDQ3LTQ4NWUtYjI2YS05MmViZWFjZDJlMmMiLAogICAgICAic3RvcmVfaWQiOiAiOWQzNTU4NGUtNjFiOS0zNmFkLWI2YjYtMDBkNzc0Nzk1YTMyIiwKICAgICAgInN0b3JlX21lbWJlcnNoaXBfaWQiOiAiODk3ZGYyZTctNDI0YS0zY2I0LTlkNGYtYzA5NDQ4MWQ3YTlhIiwKICAgICAgInBvc2l0aW9uX2lkIjogbnVsbCwKICAgICAgInN0YXJ0c19hdCI6ICIyMDI2LTAzLTAyIDE3OjAwOjAwLjAwMDAwMCIsCiAgICAgICJlbmRzX2F0IjogIjIwMjYtMDMtMDMgMDE6MDA6MDAuMDAwMDAwIiwKICAgICAgIm5vdGVzIjogIkUyRS0wMWY0ODQ0MDRlY2M0YzRkIGVkaXRlZCIsCiAgICAgICJwdWJsaXNoZWRfYXQiOiBudWxsLAogICAgICAicHVibGlzaGVkX2J5IjogbnVsbCwKICAgICAgImNyZWF0ZWRfYnkiOiAiNWZhY2NmYWEtYTg5Yy0zZDQzLWJmMjgtMmI4MmRjMjEwMGRlIiwKICAgICAgImNyZWF0ZWRfYXQiOiAiMjAyNi0wOS0wNiAxOTowNzo0MC43NDc5MzMiLAogICAgICAidXBkYXRlZF9hdCI6ICIyMDI2LTA5LTA2IDE5OjA3OjQwLjg2OTc3OCIsCiAgICAgICJkZWxldGVkX2F0IjogbnVsbAogICAgfSwKICAgIHsKICAgICAgImlkIjogImM1YTQ1ODA2LWIxMTgtNGNlOC04ZmEwLTJmYWI2ZjNjOGI2YSIsCiAgICAgICJzdG9yZV9pZCI6ICI5ZDM1NTg0ZS02MWI5LTM2YWQtYjZiNi0wMGQ3NzQ3OTVhMzIiLAogICAgICAic3RvcmVfbWVtYmVyc2hpcF9pZCI6ICI4OTdkZjJlNy00MjRhLTNjYjQtOWQ0Zi1jMDk0NDgxZDdhOWEiLAogICAgICAicG9zaXRpb25faWQiOiBudWxsLAogICAgICAic3RhcnRzX2F0IjogIjIwMjYtMDMtMDkgMTY6MDA6MDAuMDAwMDAwIiwKICAgICAgImVuZHNfYXQiOiAiMjAyNi0wMy0xMCAwMDowMDowMC4wMDAwMDAiLAogICAgICAibm90ZXMiOiAiRTJFLTAxZjQ4NDQwNGVjYzRjNGQgZWRpdGVkIiwKICAgICAgInB1Ymxpc2hlZF9hdCI6IG51bGwsCiAgICAgICJwdWJsaXNoZWRfYnkiOiBudWxsLAogICAgICAiY3JlYXRlZF9ieSI6ICI3MGJhNmI3My01ZTEyLTM0NDItYWNkNS0zYzcwOGUyZGVlN2EiLAogICAgICAiY3JlYXRlZF9hdCI6ICIyMDI2LTA5LTA2IDE5OjA3OjQxLjIwNTYxOCIsCiAgICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMDktMDYgMTk6MDc6NDEuMjA1NjE4IiwKICAgICAgImRlbGV0ZWRfYXQiOiBudWxsCiAgICB9CiAgXQp9"
                    }
                  ]
                }
              ],
              "status": "expected"
            }
          ],
          "id": "c3074283c2bde52fc5f0-fa47491c20bb0435a9a7",
          "file": "10-schedule-api.spec.ts",
          "line": 3,
          "column": 5
        }
      ]
    },
    {
      "title": "20-schedule-browser.spec.ts",
      "file": "20-schedule-browser.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "owner creates assigned/open drafts, publishes, edits, copies and switches tenants using real UI",
          "ok": false,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 0,
                  "parallelIndex": 0,
                  "status": "failed",
                  "duration": 24436,
                  "error": {
                    "message": "TimeoutError: locator.selectOption: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m  - waiting for getByRole('dialog').getByLabel('Employee', { exact: true })\u001b[22m\n",
                    "stack": "TimeoutError: locator.selectOption: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m  - waiting for getByRole('dialog').getByLabel('Employee', { exact: true })\u001b[22m\n\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts:13:58",
                    "location": {
                      "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts",
                      "column": 58,
                      "line": 13
                    },
                    "snippet": "  11 |     await page.getByRole('button', { name: 'Add shift', exact: true }).click();\n  12 |     const dialog = page.getByRole('dialog');\n> 13 |     await dialog.getByLabel('Employee', { exact: true }).selectOption(membership);\n     |                                                          ^\n  14 |     await dialog.getByLabel('Starts (store time)', { exact: true }).fill(`${day}T09:00`);\n  15 |     await dialog.getByLabel('Ends (store time)', { exact: true }).fill(`${day}T17:00`);\n  16 |     await dialog.getByLabel('Notes', { exact: true }).fill(notes);"
                  },
                  "errors": [
                    {
                      "location": {
                        "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts",
                        "column": 58,
                        "line": 13
                      },
                      "message": "TimeoutError: locator.selectOption: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m  - waiting for getByRole('dialog').getByLabel('Employee', { exact: true })\u001b[22m\n\n\n  11 |     await page.getByRole('button', { name: 'Add shift', exact: true }).click();\n  12 |     const dialog = page.getByRole('dialog');\n> 13 |     await dialog.getByLabel('Employee', { exact: true }).selectOption(membership);\n     |                                                          ^\n  14 |     await dialog.getByLabel('Starts (store time)', { exact: true }).fill(`${day}T09:00`);\n  15 |     await dialog.getByLabel('Ends (store time)', { exact: true }).fill(`${day}T17:00`);\n  16 |     await dialog.getByLabel('Notes', { exact: true }).fill(notes);\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts:13:58"
                    }
                  ],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:07:41.517Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "screenshot",
                      "contentType": "image/png",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/20-schedule-browser-owner--dccd3-tches-tenants-using-real-UI/test-failed-1.png"
                    },
                    {
                      "name": "error-context",
                      "contentType": "text/markdown",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/20-schedule-browser-owner--dccd3-tches-tenants-using-real-UI/error-context.md"
                    },
                    {
                      "name": "trace",
                      "contentType": "application/zip",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/20-schedule-browser-owner--dccd3-tches-tenants-using-real-UI/trace.zip"
                    }
                  ],
                  "errorLocation": {
                    "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts",
                    "column": 58,
                    "line": 13
                  }
                }
              ],
              "status": "unexpected"
            }
          ],
          "id": "c6a1cb2133d4d2733fcf-68c4f0b40260b9ce6e19",
          "file": "20-schedule-browser.spec.ts",
          "line": 3,
          "column": 5
        },
        {
          "title": "staff browser excludes drafts, refreshes published own/team view and switches stores",
          "ok": false,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 1,
                  "parallelIndex": 0,
                  "status": "failed",
                  "duration": 22788,
                  "error": {
                    "message": "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeVisible\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('combobox', { name: 'Store', exact: true })\nExpected: visible\nTimeout: 20000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m  - Expect \"toBeVisible\" with timeout 20000ms\u001b[22m\n\u001b[2m  - waiting for getByRole('combobox', { name: 'Store', exact: true })\u001b[22m\n",
                    "stack": "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeVisible\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('combobox', { name: 'Store', exact: true })\nExpected: visible\nTimeout: 20000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m  - Expect \"toBeVisible\" with timeout 20000ms\u001b[22m\n\u001b[2m  - waiting for getByRole('combobox', { name: 'Store', exact: true })\u001b[22m\n\n    at login (/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts:32:26)\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts:63:3",
                    "location": {
                      "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts",
                      "column": 26,
                      "line": 32
                    },
                    "snippet": "   at helpers.ts:32\n\n  30 |   await page.goto(target);\n  31 |   const selector = page.getByRole('combobox', { name: 'Store', exact: true });\n> 32 |   await expect(selector).toBeVisible();\n     |                          ^\n  33 |   await selector.selectOption(fixture.stores[store].id);\n  34 | }\n  35 |"
                  },
                  "errors": [
                    {
                      "location": {
                        "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts",
                        "column": 26,
                        "line": 32
                      },
                      "message": "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeVisible\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('combobox', { name: 'Store', exact: true })\nExpected: visible\nTimeout: 20000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m  - Expect \"toBeVisible\" with timeout 20000ms\u001b[22m\n\u001b[2m  - waiting for getByRole('combobox', { name: 'Store', exact: true })\u001b[22m\n\n\n   at helpers.ts:32\n\n  30 |   await page.goto(target);\n  31 |   const selector = page.getByRole('combobox', { name: 'Store', exact: true });\n> 32 |   await expect(selector).toBeVisible();\n     |                          ^\n  33 |   await selector.selectOption(fixture.stores[store].id);\n  34 | }\n  35 |\n    at login (/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts:32:26)\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/20-schedule-browser.spec.ts:63:3"
                    }
                  ],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:08:06.348Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "screenshot",
                      "contentType": "image/png",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/20-schedule-browser-staff--8e787-am-view-and-switches-stores/test-failed-1.png"
                    },
                    {
                      "name": "error-context",
                      "contentType": "text/markdown",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/20-schedule-browser-staff--8e787-am-view-and-switches-stores/error-context.md"
                    },
                    {
                      "name": "trace",
                      "contentType": "application/zip",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/20-schedule-browser-staff--8e787-am-view-and-switches-stores/trace.zip"
                    }
                  ],
                  "errorLocation": {
                    "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts",
                    "column": 26,
                    "line": 32
                  }
                }
              ],
              "status": "unexpected"
            }
          ],
          "id": "c6a1cb2133d4d2733fcf-5843f1afa85fddc88848",
          "file": "20-schedule-browser.spec.ts",
          "line": 60,
          "column": 5
        }
      ]
    },
    {
      "title": "30-clock-payroll.spec.ts",
      "file": "30-clock-payroll.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "staff clocks and breaks through real buttons with durable idempotent replay",
          "ok": false,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 2,
                  "parallelIndex": 0,
                  "status": "failed",
                  "duration": 22084,
                  "error": {
                    "message": "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeVisible\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('combobox', { name: 'Store', exact: true })\nExpected: visible\nTimeout: 20000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m  - Expect \"toBeVisible\" with timeout 20000ms\u001b[22m\n\u001b[2m  - waiting for getByRole('combobox', { name: 'Store', exact: true })\u001b[22m\n",
                    "stack": "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeVisible\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('combobox', { name: 'Store', exact: true })\nExpected: visible\nTimeout: 20000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m  - Expect \"toBeVisible\" with timeout 20000ms\u001b[22m\n\u001b[2m  - waiting for getByRole('combobox', { name: 'Store', exact: true })\u001b[22m\n\n    at login (/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts:32:26)\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts:25:3",
                    "location": {
                      "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts",
                      "column": 26,
                      "line": 32
                    },
                    "snippet": "   at helpers.ts:32\n\n  30 |   await page.goto(target);\n  31 |   const selector = page.getByRole('combobox', { name: 'Store', exact: true });\n> 32 |   await expect(selector).toBeVisible();\n     |                          ^\n  33 |   await selector.selectOption(fixture.stores[store].id);\n  34 | }\n  35 |"
                  },
                  "errors": [
                    {
                      "location": {
                        "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts",
                        "column": 26,
                        "line": 32
                      },
                      "message": "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeVisible\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('combobox', { name: 'Store', exact: true })\nExpected: visible\nTimeout: 20000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m  - Expect \"toBeVisible\" with timeout 20000ms\u001b[22m\n\u001b[2m  - waiting for getByRole('combobox', { name: 'Store', exact: true })\u001b[22m\n\n\n   at helpers.ts:32\n\n  30 |   await page.goto(target);\n  31 |   const selector = page.getByRole('combobox', { name: 'Store', exact: true });\n> 32 |   await expect(selector).toBeVisible();\n     |                          ^\n  33 |   await selector.selectOption(fixture.stores[store].id);\n  34 | }\n  35 |\n    at login (/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts:32:26)\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts:25:3"
                    }
                  ],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:08:30.038Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "screenshot",
                      "contentType": "image/png",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/30-clock-payroll-staff-clo-d4af5-h-durable-idempotent-replay/test-failed-1.png"
                    },
                    {
                      "name": "error-context",
                      "contentType": "text/markdown",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/30-clock-payroll-staff-clo-d4af5-h-durable-idempotent-replay/error-context.md"
                    },
                    {
                      "name": "trace",
                      "contentType": "application/zip",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/30-clock-payroll-staff-clo-d4af5-h-durable-idempotent-replay/trace.zip"
                    }
                  ],
                  "errorLocation": {
                    "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/helpers.ts",
                    "column": 26,
                    "line": 32
                  }
                }
              ],
              "status": "unexpected"
            }
          ],
          "id": "11458750d704032b6e3f-8431482e12415154e32f",
          "file": "30-clock-payroll.spec.ts",
          "line": 7,
          "column": 5
        },
        {
          "title": "manager correction and approval leads to owner browser CSV download and immutable replay",
          "ok": false,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 3,
                  "parallelIndex": 0,
                  "status": "failed",
                  "duration": 25204,
                  "error": {
                    "message": "TimeoutError: locator.click: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m  - waiting for getByRole('region', { name: 'Timesheet detail' }).getByRole('row').filter({ has: getByRole('cell', { name: 'clock in', exact: true }) }).getByRole('button', { name: 'Edit punch', exact: true })\u001b[22m\n",
                    "stack": "TimeoutError: locator.click: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m  - waiting for getByRole('region', { name: 'Timesheet detail' }).getByRole('row').filter({ has: getByRole('cell', { name: 'clock in', exact: true }) }).getByRole('button', { name: 'Edit punch', exact: true })\u001b[22m\n\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts:74:72",
                    "location": {
                      "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts",
                      "column": 72,
                      "line": 74
                    },
                    "snippet": "  72 |     const detail = manager.getByRole('region', { name: 'Timesheet detail' });\n  73 |     const row = detail.getByRole('row').filter({ has: manager.getByRole('cell', { name: 'clock in', exact: true }) });\n> 74 |     await row.getByRole('button', { name: 'Edit punch', exact: true }).click();\n     |                                                                        ^\n  75 |     const corrected = new Date(new Date(clockIn.punched_at).getTime() - 60 * 60_000);\n  76 |     const parts = new Intl.DateTimeFormat('sv-SE', { timeZone: 'America/Los_Angeles', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(corrected).replace(' ', 'T');\n  77 |     await manager.getByLabel(/Punch time/).fill(parts);"
                  },
                  "errors": [
                    {
                      "location": {
                        "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts",
                        "column": 72,
                        "line": 74
                      },
                      "message": "TimeoutError: locator.click: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m  - waiting for getByRole('region', { name: 'Timesheet detail' }).getByRole('row').filter({ has: getByRole('cell', { name: 'clock in', exact: true }) }).getByRole('button', { name: 'Edit punch', exact: true })\u001b[22m\n\n\n  72 |     const detail = manager.getByRole('region', { name: 'Timesheet detail' });\n  73 |     const row = detail.getByRole('row').filter({ has: manager.getByRole('cell', { name: 'clock in', exact: true }) });\n> 74 |     await row.getByRole('button', { name: 'Edit punch', exact: true }).click();\n     |                                                                        ^\n  75 |     const corrected = new Date(new Date(clockIn.punched_at).getTime() - 60 * 60_000);\n  76 |     const parts = new Intl.DateTimeFormat('sv-SE', { timeZone: 'America/Los_Angeles', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(corrected).replace(' ', 'T');\n  77 |     await manager.getByLabel(/Punch time/).fill(parts);\n    at /Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts:74:72"
                    }
                  ],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:08:52.977Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "screenshot",
                      "contentType": "image/png",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/30-clock-payroll-manager-c-86f06-wnload-and-immutable-replay/test-failed-1.png"
                    },
                    {
                      "name": "error-context",
                      "contentType": "text/markdown",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/30-clock-payroll-manager-c-86f06-wnload-and-immutable-replay/error-context.md"
                    },
                    {
                      "name": "trace",
                      "contentType": "application/zip",
                      "path": "/Users/rvanvuren/Projects/alqove-web/.cache/scheduling-qa/E2E-01f484404ecc4c4d/test-results/30-clock-payroll-manager-c-86f06-wnload-and-immutable-replay/trace.zip"
                    }
                  ],
                  "errorLocation": {
                    "file": "/Users/rvanvuren/Projects/alqove-web/e2e-scheduling-real/30-clock-payroll.spec.ts",
                    "column": 72,
                    "line": 74
                  }
                }
              ],
              "status": "unexpected"
            }
          ],
          "id": "11458750d704032b6e3f-a0bda1f7103d193583ff",
          "file": "30-clock-payroll.spec.ts",
          "line": 53,
          "column": 5
        }
      ]
    },
    {
      "title": "40-guards.spec.ts",
      "file": "40-guards.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [
        {
          "title": "stranded-clock approval/export guards and cross-store punch IDs fail closed",
          "ok": true,
          "tags": [],
          "tests": [
            {
              "timeout": 90000,
              "annotations": [],
              "expectedStatus": "passed",
              "projectId": "",
              "projectName": "",
              "results": [
                {
                  "workerIndex": 4,
                  "parallelIndex": 0,
                  "status": "passed",
                  "duration": 355,
                  "errors": [],
                  "stdout": [],
                  "stderr": [],
                  "retry": 0,
                  "startTime": "2026-09-06T19:09:18.682Z",
                  "annotations": [],
                  "attachments": [
                    {
                      "name": "stranded-guards",
                      "contentType": "application/json",
                      "body": "ewogICJzaGVldCI6IHsKICAgICJpZCI6ICI0MDc0MWJiZS01Zjc3LTRlYzYtYjY3Yy0wOWZlMjExOTExYmIiLAogICAgInN0b3JlX21lbWJlcnNoaXBfaWQiOiAiZjUwZmZlZjMtZGMxYS0zNGQyLWFmM2EtOTNkN2Q5YzEwMjVhIiwKICAgICJtZW1iZXJfbmFtZSI6ICJFMkUtMDFmNDg0NDA0ZWNjNGM0ZCBNYW5hZ2VyIiwKICAgICJ3ZWVrX3N0YXJ0X2RhdGUiOiAiMjAyNi0wNC0wNiIsCiAgICAic2NoZWR1bGVkX21pbnV0ZXMiOiAwLAogICAgInJlZ3VsYXJfbWludXRlcyI6IDAsCiAgICAib3ZlcnRpbWVfbWludXRlcyI6IDAsCiAgICAiZG91YmxldGltZV9taW51dGVzIjogMCwKICAgICJ1bnBhaWRfYnJlYWtfbWludXRlcyI6IDAsCiAgICAic3RhdHVzIjogInBlbmRpbmciLAogICAgImNhbGN1bGF0aW9uX21ldGFkYXRhIjogewogICAgICAic2NoZW1hX3ZlcnNpb24iOiAxLAogICAgICAidGltZXpvbmUiOiAiQW1lcmljYS9Mb3NfQW5nZWxlcyIsCiAgICAgICJzdGFydHNfYXQiOiAiMjAyNi0wNC0wNlQwNzowMDowMCswMDowMCIsCiAgICAgICJlbmRzX2F0IjogIjIwMjYtMDQtMTNUMDc6MDA6MDArMDA6MDAiLAogICAgICAiZGFpbHlfYnJlYWtkb3duIjogW10sCiAgICAgICJzdHJhbmRlZF9jbG9ja19pbnMiOiBbCiAgICAgICAgewogICAgICAgICAgInB1bmNoX2lkIjogIjA0YjM3MzM3LTlhMDYtNGY1YS04MzFmLTI0ZWZlYzFmMDM3MiIsCiAgICAgICAgICAiZGF0ZSI6ICIyMDI2LTA0LTA2IgogICAgICAgIH0KICAgICAgXSwKICAgICAgIm9wZW5fc2Vzc2lvbnMiOiBbCiAgICAgICAgewogICAgICAgICAgInB1bmNoX2lkIjogIjA0YjM3MzM3LTlhMDYtNGY1YS04MzFmLTI0ZWZlYzFmMDM3MiIKICAgICAgICB9CiAgICAgIF0sCiAgICAgICJvdmVyc2l6ZWRfc2Vzc2lvbnMiOiBbXSwKICAgICAgInB1bmNoZXMiOiBbCiAgICAgICAgewogICAgICAgICAgImlkIjogIjA0YjM3MzM3LTlhMDYtNGY1YS04MzFmLTI0ZWZlYzFmMDM3MiIsCiAgICAgICAgICAidHlwZSI6ICJjbG9ja19pbiIsCiAgICAgICAgICAidHMiOiAxNzc1NDkxMjAwLAogICAgICAgICAgImJyZWFrX3R5cGUiOiBudWxsCiAgICAgICAgfQogICAgICBdCiAgICB9CiAgfSwKICAicHVuY2hlcyI6IFsKICAgIHsKICAgICAgImlkIjogIjA0YjM3MzM3LTlhMDYtNGY1YS04MzFmLTI0ZWZlYzFmMDM3MiIsCiAgICAgICJzdG9yZV9pZCI6ICJmYTQ5YzkyMi1hNDgzLTM0Y2EtOTEwNi0yZTY1NjhkMGE5NDciLAogICAgICAic3RvcmVfbWVtYmVyc2hpcF9pZCI6ICJmNTBmZmVmMy1kYzFhLTM0ZDItYWYzYS05M2Q3ZDljMTAyNWEiLAogICAgICAic2hpZnRfaWQiOiBudWxsLAogICAgICAicHVuY2hfdHlwZSI6ICJjbG9ja19pbiIsCiAgICAgICJwdW5jaGVkX2F0IjogIjIwMjYtMDQtMDYgMTY6MDA6MDAiLAogICAgICAiYnJlYWtfdHlwZSI6IG51bGwsCiAgICAgICJub3RlIjogIkUyRS0wMWY0ODQ0MDRlY2M0YzRkIHN0cmFuZGVkIGd1YXJkIiwKICAgICAgInJldmlzaW9uIjogIjdhNWQ5YTRkLWRmNTktNDc2Yi1hYTZjLWMyYTg4ZGE5MzlmZCIsCiAgICAgICJpc19tYW51YWwiOiAxLAogICAgICAiY3JlYXRlZF9ieSI6ICI1ZmFjY2ZhYS1hODljLTNkNDMtYmYyOC0yYjgyZGMyMTAwZGUiLAogICAgICAidXBkYXRlZF9ieSI6IG51bGwsCiAgICAgICJkZWxldGVkX2J5IjogbnVsbCwKICAgICAgImNyZWF0ZWRfYXQiOiAiMjAyNi0wOS0wNiAxOTowOToxOCIsCiAgICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMDktMDYgMTk6MDk6MTgiLAogICAgICAiZGVsZXRlZF9hdCI6IG51bGwKICAgIH0KICBdLAogICJleHBvcnRzIjogW10KfQ=="
                    }
                  ]
                }
              ],
              "status": "expected"
            }
          ],
          "id": "c7397b2a9aa80a519ce2-fb6432fabdc751085763",
          "file": "40-guards.spec.ts",
          "line": 3,
          "column": 5
        }
      ]
    }
  ],
  "errors": [],
  "stats": {
    "startTime": "2026-09-06T19:07:33.641Z",
    "duration": 105420.042,
    "expected": 3,
    "skipped": 0,
    "unexpected": 4,
    "flaky": 0
  }
}