{
  "config": {
    "argv": [
      "/usr/bin/node",
      "/home3/uatservers/public_html/cron.studyineurope.xyz/node_modules/.bin/playwright",
      "test",
      "--project=api"
    ],
    "configFile": "/home3/uatservers/public_html/cron.studyineurope.xyz/playwright.config.ts",
    "rootDir": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests",
    "failOnFlakyTests": false,
    "forbidOnly": true,
    "fullyParallel": false,
    "globalSetup": null,
    "globalTeardown": null,
    "globalTimeout": 0,
    "grep": {},
    "grepInvert": null,
    "maxFailures": 0,
    "metadata": {
      "actualWorkers": 1
    },
    "preserveOutput": "always",
    "projects": [
      {
        "outputDir": "/home3/uatservers/public_html/cron.studyineurope.xyz/test-results",
        "repeatEach": 1,
        "retries": 1,
        "metadata": {
          "actualWorkers": 1
        },
        "id": "api",
        "name": "api",
        "testDir": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api",
        "testIgnore": [],
        "testMatch": [
          "**/*.@(spec|test).?(c|m)[jt]s?(x)"
        ],
        "timeout": 60000
      }
    ],
    "quiet": false,
    "reporter": [
      [
        "list",
        null
      ],
      [
        "json",
        {
          "outputFile": "test-results/results.json"
        }
      ]
    ],
    "reportSlowTests": {
      "max": 5,
      "threshold": 300000
    },
    "shard": null,
    "tags": [],
    "updateSnapshots": "missing",
    "updateSourceMethod": "patch",
    "version": "1.63.0",
    "workers": 1,
    "webServer": null
  },
  "suites": [
    {
      "title": "api/race-api.spec.ts",
      "file": "api/race-api.spec.ts",
      "column": 0,
      "line": 0,
      "specs": [],
      "suites": [
        {
          "title": "RACE API - Chat Completion Health Check",
          "file": "api/race-api.spec.ts",
          "line": 59,
          "column": 6,
          "specs": [
            {
              "title": "responds with a valid assistant message within the latency limit",
              "ok": false,
              "tags": [],
              "tests": [
                {
                  "timeout": 60000,
                  "annotations": [],
                  "expectedStatus": "passed",
                  "projectId": "api",
                  "projectName": "api",
                  "results": [
                    {
                      "workerIndex": 0,
                      "parallelIndex": 0,
                      "status": "failed",
                      "duration": 240,
                      "error": {
                        "message": "Error: Expected HTTP 200 but got 401\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m200\u001b[39m\nReceived: \u001b[31m401\u001b[39m",
                        "stack": "Error: Expected HTTP 200 but got 401\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m200\u001b[39m\nReceived: \u001b[31m401\u001b[39m\n    at /home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts:105:13",
                        "location": {
                          "file": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts",
                          "column": 13,
                          "line": 105
                        },
                        "snippet": "  103 |       await attachContext(testInfo, result);\n  104 |       console.log(`[RACE API] FAIL - status=${result.status ?? -1} durationMs=${result.durationMs ?? -1}`);\n> 105 |       throw new Error(error instanceof Error ? redact(error.message) : String(error));\n      |             ^\n  106 |     }\n  107 |   });\n  108 |"
                      },
                      "errors": [
                        {
                          "location": {
                            "file": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts",
                            "column": 13,
                            "line": 105
                          },
                          "message": "Error: Expected HTTP 200 but got 401\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m200\u001b[39m\nReceived: \u001b[31m401\u001b[39m\n\n  103 |       await attachContext(testInfo, result);\n  104 |       console.log(`[RACE API] FAIL - status=${result.status ?? -1} durationMs=${result.durationMs ?? -1}`);\n> 105 |       throw new Error(error instanceof Error ? redact(error.message) : String(error));\n      |             ^\n  106 |     }\n  107 |   });\n  108 |\n    at /home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts:105:13"
                        }
                      ],
                      "stdout": [
                        {
                          "text": "[RACE API] status=401 durationMs=231\n"
                        },
                        {
                          "text": "[RACE API] FAIL - status=401 durationMs=231\n"
                        }
                      ],
                      "stderr": [],
                      "retry": 0,
                      "startTime": "2026-10-01T13:00:03.116Z",
                      "annotations": [],
                      "attachments": [
                        {
                          "name": "race-api-context",
                          "contentType": "application/json",
                          "body": "ewogICJ1cmwiOiAiaHR0cHM6Ly9yYWNlYWkuc3R1ZHlpbmV1cm9wZS54eXovdjEvY2hhdC9jb21wbGV0aW9ucyIsCiAgIm1vZGVsIjogImdwdC1vc3MtMTIwYiIsCiAgInN0YXR1cyI6IDQwMSwKICAiZHVyYXRpb25NcyI6IDIzMQp9"
                        },
                        {
                          "name": "race-api-response-body",
                          "contentType": "text/plain",
                          "body": "eyJkZXRhaWwiOiJpbnZhbGlkIEFQSSBrZXkifQ=="
                        },
                        {
                          "name": "error-context",
                          "contentType": "text/markdown",
                          "path": "/home3/uatservers/public_html/cron.studyineurope.xyz/test-results/race-api-RACE-API---Chat-C-b0ca3-ge-within-the-latency-limit-api/error-context.md"
                        },
                        {
                          "name": "error-context",
                          "contentType": "text/markdown",
                          "path": "/home3/uatservers/public_html/cron.studyineurope.xyz/test-results/race-api-RACE-API---Chat-C-b0ca3-ge-within-the-latency-limit-api/error-context.md"
                        }
                      ],
                      "errorLocation": {
                        "file": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts",
                        "column": 13,
                        "line": 105
                      }
                    },
                    {
                      "workerIndex": 1,
                      "parallelIndex": 0,
                      "status": "failed",
                      "duration": 248,
                      "error": {
                        "message": "Error: Expected HTTP 200 but got 401\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m200\u001b[39m\nReceived: \u001b[31m401\u001b[39m",
                        "stack": "Error: Expected HTTP 200 but got 401\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m200\u001b[39m\nReceived: \u001b[31m401\u001b[39m\n    at /home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts:105:13",
                        "location": {
                          "file": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts",
                          "column": 13,
                          "line": 105
                        },
                        "snippet": "  103 |       await attachContext(testInfo, result);\n  104 |       console.log(`[RACE API] FAIL - status=${result.status ?? -1} durationMs=${result.durationMs ?? -1}`);\n> 105 |       throw new Error(error instanceof Error ? redact(error.message) : String(error));\n      |             ^\n  106 |     }\n  107 |   });\n  108 |"
                      },
                      "errors": [
                        {
                          "location": {
                            "file": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts",
                            "column": 13,
                            "line": 105
                          },
                          "message": "Error: Expected HTTP 200 but got 401\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m200\u001b[39m\nReceived: \u001b[31m401\u001b[39m\n\n  103 |       await attachContext(testInfo, result);\n  104 |       console.log(`[RACE API] FAIL - status=${result.status ?? -1} durationMs=${result.durationMs ?? -1}`);\n> 105 |       throw new Error(error instanceof Error ? redact(error.message) : String(error));\n      |             ^\n  106 |     }\n  107 |   });\n  108 |\n    at /home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts:105:13"
                        }
                      ],
                      "stdout": [
                        {
                          "text": "[RACE API] status=401 durationMs=239\n"
                        },
                        {
                          "text": "[RACE API] FAIL - status=401 durationMs=239\n"
                        }
                      ],
                      "stderr": [],
                      "retry": 1,
                      "startTime": "2026-10-01T13:00:04.088Z",
                      "annotations": [],
                      "attachments": [
                        {
                          "name": "race-api-context",
                          "contentType": "application/json",
                          "body": "ewogICJ1cmwiOiAiaHR0cHM6Ly9yYWNlYWkuc3R1ZHlpbmV1cm9wZS54eXovdjEvY2hhdC9jb21wbGV0aW9ucyIsCiAgIm1vZGVsIjogImdwdC1vc3MtMTIwYiIsCiAgInN0YXR1cyI6IDQwMSwKICAiZHVyYXRpb25NcyI6IDIzOQp9"
                        },
                        {
                          "name": "race-api-response-body",
                          "contentType": "text/plain",
                          "body": "eyJkZXRhaWwiOiJpbnZhbGlkIEFQSSBrZXkifQ=="
                        },
                        {
                          "name": "error-context",
                          "contentType": "text/markdown",
                          "path": "/home3/uatservers/public_html/cron.studyineurope.xyz/test-results/race-api-RACE-API---Chat-C-b0ca3-ge-within-the-latency-limit-api-retry1/error-context.md"
                        },
                        {
                          "name": "error-context",
                          "contentType": "text/markdown",
                          "path": "/home3/uatservers/public_html/cron.studyineurope.xyz/test-results/race-api-RACE-API---Chat-C-b0ca3-ge-within-the-latency-limit-api-retry1/error-context.md"
                        }
                      ],
                      "errorLocation": {
                        "file": "/home3/uatservers/public_html/cron.studyineurope.xyz/tests/api/race-api.spec.ts",
                        "column": 13,
                        "line": 105
                      }
                    }
                  ],
                  "status": "unexpected"
                }
              ],
              "id": "2039e73aa07be346586d-935b73f9504cb3457f30",
              "file": "api/race-api.spec.ts",
              "line": 72,
              "column": 7
            },
            {
              "title": "rejects an invalid API key with 401/403",
              "ok": true,
              "tags": [],
              "tests": [
                {
                  "timeout": 60000,
                  "annotations": [],
                  "expectedStatus": "passed",
                  "projectId": "api",
                  "projectName": "api",
                  "results": [
                    {
                      "workerIndex": 2,
                      "parallelIndex": 0,
                      "status": "passed",
                      "duration": 175,
                      "errors": [],
                      "stdout": [
                        {
                          "text": "[RACE API] negative test status=401\n"
                        }
                      ],
                      "stderr": [],
                      "retry": 0,
                      "startTime": "2026-10-01T13:00:05.050Z",
                      "annotations": [],
                      "attachments": []
                    }
                  ],
                  "status": "expected"
                }
              ],
              "id": "2039e73aa07be346586d-94ff73ef22d7910d8902",
              "file": "api/race-api.spec.ts",
              "line": 109,
              "column": 7
            }
          ]
        }
      ]
    }
  ],
  "errors": [],
  "stats": {
    "startTime": "2026-10-01T13:00:02.525Z",
    "duration": 2850.03,
    "expected": 1,
    "skipped": 0,
    "unexpected": 1,
    "flaky": 0
  }
}