> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codeant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Frontend QA Agent

> Configure authenticated, pull-request-scoped browser testing for GitHub preview deployments

## Overview

Frontend QA opens a deployed pull request preview in a real browser, restores or creates a test-user session, and exercises the UI behavior changed by that pull request. Each run can produce scoped findings, screenshots, and a browser recording.

```mermaid theme={"system"}
flowchart LR
    A[GitHub deployment succeeds] --> B[CodeAnt matches the repository, environment, and preview host]
    B --> C[CodeAnt restores the configured test session]
    C --> D[Checks are planned from the PR description and changed code]
    D --> E[Browser actions run against the preview]
    E --> F[Findings, screenshots, and recording]
```

<Note>
  Frontend QA is available for selected GitHub customers. You need CodeAnt administrator access. If **Settings → Code Review → QA Agent** is not visible, contact [support@codeant.ai](mailto:support@codeant.ai).
</Note>

## Prerequisites

Before configuring a repository, confirm that:

* The GitHub repository is connected to CodeAnt AI.
* Pull requests receive a successful GitHub [`deployment_status`](https://docs.github.com/en/webhooks/webhook-events-and-payloads#deployment_status) event from the preview provider.
* The event identifies an open pull request commit and includes an `environment_url` or `target_url`, or GitHub exposes the URL through the deployment or commit status APIs.
* The preview is publicly reachable over HTTPS from CodeAnt AI.
* You have a dedicated, least-privilege test account with non-production data.
* You know whether the application stores authentication in cookies, `localStorage`, IndexedDB, or a combination of these.

<Warning>
  Do not use a production administrator account. Browser recordings and screenshots can contain data visible to the configured test user.
</Warning>

## Configure a repository

Open [app.codeant.ai](https://app.codeant.ai), select your organization, and go to **Settings → Code Review → QA Agent**.

### 1. Select the repository

Choose the repository that owns the frontend preview. Settings are repository-scoped; configuring one repository does not automatically configure another.

### 2. Configure the preview

<Tabs>
  <Tab title="Dynamic preview">
    Select **Dynamic (CI / Vercel)** when every pull request gets a different preview hostname. This is the current settings-page label; the option supports Amplify, Netlify, and other CI preview providers in addition to Vercel.

    In **Trusted preview host**, enter an app-specific hostname pattern—not a regular expression and not a full URL.

    | Provider    | Example                           |
    | ----------- | --------------------------------- |
    | AWS Amplify | `*.example-app-id.amplifyapp.com` |
    | Vercel      | `project-git-*-team.vercel.app`   |
    | Netlify     | `*--site-name.netlify.app`        |

    A hostname without `*` trusts that exact hostname and its subdomains. For example, `example-app-id.amplifyapp.com` also accepts `pr-42.example-app-id.amplifyapp.com`.

    The pattern must follow these rules:

    * Hostname only—do not include `https://`, a port, path, query string, or fragment.
    * `*` can appear inside a hostname label, but `**` is not supported.
    * The final two labels cannot contain `*`; patterns such as `*.amplifyapp.com` are intentionally rejected because they are not app-specific.
  </Tab>

  <Tab title="Static preview">
    Select **Static URL** when QA should always run against one stable environment, such as:

    ```text theme={"system"}
    https://staging.example.com
    ```

    Use a publicly reachable HTTPS URL. The GitHub deployment environment is still required because the successful deployment event controls when automatic QA begins.
  </Tab>
</Tabs>

### 3. Add trusted subresource origins

The preview origin is allowed automatically. If the frontend loads APIs, fonts, images, or other subresources from additional origins, add each origin on a separate line under **Additional trusted subresource origins**:

```text theme={"system"}
https://api.example.com
https://cdn.example.com
```

Only add origins the signed-in preview genuinely needs. Each entry must be an exact, publicly reachable HTTPS origin. Paths, query strings, and wildcards are not supported. You can add up to 20 origins.

<Warning>
  This setting grants the browser network access to an origin; it does not make that origin a valid preview or login destination. Trusted origins may receive requests and data from the signed-in browser.
</Warning>

### 4. Set the deployment environment

In **GitHub deployment environment**, enter the environment name reported by the successful GitHub deployment event. Common values are `Preview`, `Staging`, and `Production`.

Use the exact value shown in GitHub. A run starts only when:

* the QA Agent is enabled;
* the deployment state is `success`;
* the deployment environment matches this setting;
* the commit belongs to an open pull request; and
* the resolved URL matches the trusted preview host.

#### If `deployment_status` is not being sent

First, check whether the preview provider creates GitHub deployments for the pull request head SHA:

```bash theme={"system"}
gh api "repos/OWNER/REPOSITORY/deployments?sha=PR_HEAD_SHA"
gh api "repos/OWNER/REPOSITORY/deployments/DEPLOYMENT_ID/statuses"
```

The second response must contain a status whose `state` is `success`, whose `environment` exactly matches **GitHub deployment environment**, and whose `environment_url` or `target_url` is the ready preview URL.

If deployment happens in GitHub Actions, add an environment and URL to the existing deployment job. GitHub then creates the deployment and its status automatically:

```yaml theme={"system"}
jobs:
  deploy-preview:
    permissions:
      contents: read
      deployments: write
    environment:
      name: Preview
      url: ${{ steps.deploy.outputs.preview_url }}
    steps:
      - id: deploy
        # Run your existing preview deployment here.
        # This step must expose the ready URL as the preview_url output.
```

If the provider deploys outside GitHub Actions and does not publish a deployment status, add this step to a workflow **after the preview is ready**. Replace the dummy URL with the URL returned by your deployment step:

```yaml theme={"system"}
permissions:
  contents: read
  deployments: write

steps:
  - name: Publish preview deployment status
    uses: actions/github-script@v7
    env:
      PREVIEW_URL: https://pr-${{ github.event.pull_request.number }}.example-app-id.amplifyapp.com
      PREVIEW_ENVIRONMENT: Preview
    with:
      script: |
        const { data: deployment } = await github.rest.repos.createDeployment({
          ...context.repo,
          ref: context.payload.pull_request.head.sha,
          environment: process.env.PREVIEW_ENVIRONMENT,
          auto_merge: false,
          required_contexts: [],
          transient_environment: true,
          production_environment: false,
        });

        await github.rest.repos.createDeploymentStatus({
          ...context.repo,
          deployment_id: deployment.id,
          state: "success",
          environment: process.env.PREVIEW_ENVIRONMENT,
          environment_url: process.env.PREVIEW_URL,
          description: "Pull request preview is ready",
          auto_inactive: false,
        });
```

GitHub requires `Deployments: write` for the workflow that creates the status. The installed CodeAnt GitHub App must have at least `Deployments: read` and be subscribed to `deployment_status`. If GitHub shows the successful deployment status but CodeAnt does not start a run, contact [support@codeant.ai](mailto:support@codeant.ai) with the repository, pull request, deployment environment, and GitHub delivery ID. See GitHub's [deployment REST API](https://docs.github.com/en/rest/deployments/deployments) and [deployment status API](https://docs.github.com/en/rest/deployments/statuses) for the underlying event model.

### 5. Choose an authentication mode

<Tabs>
  <Tab title="Saved session">
    Use **Saved session** for SSO, MFA, OAuth, or any login that a person should complete once and CodeAnt should replay later.

    1. In **Authentication source URL**, enter the stable login page for the application being tested, for example `https://app.example.com/login`.
    2. Click **Connect browser session**.
    3. Click **Open secure browser** and complete every login step in the isolated browser.
    4. Confirm that the application shows a signed-in state.
    5. Click **I'm logged in — save session**.

    The secure browser expires after 15 minutes. CodeAnt encrypts the captured cookies and site storage and refreshes the saved state after successful QA runs.

    <Warning>
      The authentication source is your application—not the CodeAnt dashboard. Do not enter `https://app.codeant.ai`. CodeAnt dashboard cookies cannot authenticate a separate customer preview.
    </Warning>

    For dynamic previews, CodeAnt can copy source-origin `localStorage` and IndexedDB data to a validated preview origin. Cookies are never rewritten; a cookie is retained only when its domain is already valid for the preview hostname.

    <Warning>
      Pull-request code runs on the preview origin and can read any bearer token or reusable credential copied into that origin's `localStorage` or IndexedDB. Origin filtering does not protect those values from same-origin JavaScript. Use a disposable, least-privilege QA account with non-production data, rotate it regularly, and prefer programmatic login or short-lived preview-scoped credentials when testing untrusted pull requests.
    </Warning>

    For example, cookies captured on `app.example.com` cannot authenticate `pr-42.app-id.amplifyapp.com`. For a cookie-only application on unrelated domains, use a same-origin programmatic login, a customer-owned preview domain with compatible cookie scope, or configure the identity provider to support the preview callback.
  </Tab>

  <Tab title="Programmatic login">
    Use **Programmatic login** when the preview exposes a test-only endpoint that creates the browser session directly.

    The endpoint must be relative to, or use the same origin as, the resolved preview URL. It must return a successful response and establish authentication by setting cookies for that preview.

    Example settings:

    | Field          | Example                                               |
    | -------------- | ----------------------------------------------------- |
    | Login endpoint | `/api/qa/session`                                     |
    | Method         | `POST`                                                |
    | Headers JSON   | `{"X-QA-Key":"${QA_KEY}"}`                            |
    | Request JSON   | `{"email":"${QA_EMAIL}","password":"${QA_PASSWORD}"}` |

    Add the referenced values under **QA runtime variables**:

    ```dotenv theme={"system"}
    QA_KEY=replace-with-a-dedicated-test-key
    QA_EMAIL=qa-bot@example.com
    QA_PASSWORD=replace-with-the-test-account-password
    ```

    Programmatic headers and request data must be JSON objects. The supported methods are `POST` and `PUT`. Redirects are not followed, so the endpoint should establish the session directly.
  </Tab>

  <Tab title="Credentials">
    Use **Credentials** for a conventional username/password form that the QA browser can operate.

    * Enter the dedicated test account's username or email and password.
    * Add concise **Login instructions**, for example: `Open /login, enter the email and password, click Sign in, and wait for /dashboard.`
    * Keep the instructions limited to the real login flow; do not include secrets in this text field.

    Credentials are encrypted at rest and never displayed again. Leave both fields blank when editing other settings to keep the stored credentials unchanged.
  </Tab>
</Tabs>

### 6. Add runtime variables

**QA runtime variables** are optional encrypted `KEY=value` entries. Use one entry per line:

```dotenv theme={"system"}
QA_EMAIL=qa-bot@example.com
QA_PASSWORD=replace-with-the-test-account-password
QA_KEY=replace-with-a-dedicated-test-key
```

Variable names must start with a letter or underscore and contain only letters, numbers, and underscores. Reference a value as `${NAME}` in programmatic login JSON. Runtime variables can also be used in supported preview templates.

These values belong to the QA worker. They do **not** add or change environment variables in the deployed preview. When a **stored** badge is shown, leaving this field blank preserves the existing encrypted values; enter the complete replacement set when rotating them.

### 7. Enable and save

Turn on **Enable QA agent**, then click **Save**. A successful save confirms that required URLs and trusted origins are public and valid.

## Complete AWS Amplify example

The following example configures dynamic previews such as `https://pr-42.example-app-id.amplifyapp.com`. All domains and repository names below are dummy values:

| Setting                                | Example value                                             |
| -------------------------------------- | --------------------------------------------------------- |
| Repository                             | `acme/web-app`                                            |
| Enable QA agent                        | On                                                        |
| Preview URL                            | Dynamic (CI / Vercel)—the same option is used for Amplify |
| Trusted preview host                   | `*.example-app-id.amplifyapp.com`                         |
| Additional trusted subresource origins | `https://api.acme.example`                                |
| GitHub deployment environment          | `Preview`                                                 |
| Authentication mode                    | Saved session                                             |
| Authentication source URL              | `https://app.acme.example/login`                          |
| QA runtime variables                   | Leave blank unless the login recipe references variables  |

After saving, connect the secure browser and sign in at `https://app.acme.example/login`. If the application stores its session only in cookies scoped to `acme.example`, those cookies cannot be copied to `amplifyapp.com`; use programmatic login or a compatible custom preview domain instead.

## Validate the setup

Use **Run now** before relying on automatic triggers:

1. Enter an open pull request number that has a deployed preview.
2. Click **Run QA now**.
3. Confirm that the result shows the expected preview URL and a successful login.
4. Review findings, screenshots, and the browser recording.

Providing a PR number enables diff-driven checks. Running without a PR number is useful for validating preview resolution and authentication, but it does not provide changed-code scope for UI checks.

For the best validation, use a pull request with one small, observable UI change and describe the expected behavior in the PR description. Frontend QA reports only failures related to the pull request description and changed code; unrelated or pre-existing issues are discarded.

## Settings reference

| Setting                                | Required               | Accepted value                                                        |
| -------------------------------------- | ---------------------- | --------------------------------------------------------------------- |
| Repository                             | Yes                    | One connected GitHub repository                                       |
| Enable QA agent                        | Yes for automatic runs | On or off                                                             |
| Preview source                         | Yes                    | Static URL or Dynamic (CI / Vercel)                                   |
| Static URL                             | For static previews    | Public HTTPS URL                                                      |
| Trusted preview host                   | For dynamic previews   | App-specific hostname or constrained `*` pattern                      |
| Additional trusted subresource origins | No                     | Up to 20 exact public HTTPS origins, one per line                     |
| GitHub deployment environment          | Yes                    | Environment reported by GitHub, such as `Preview`                     |
| Login instructions                     | Credentials mode       | Plain-language login steps; no secrets                                |
| Authentication mode                    | Yes                    | Credentials, Programmatic login, or Saved session                     |
| Username and password                  | Credentials mode       | Dedicated test-account credentials                                    |
| Login endpoint                         | Programmatic mode      | Relative or same-origin endpoint                                      |
| Method                                 | Programmatic mode      | `POST` or `PUT`                                                       |
| Headers JSON                           | Programmatic mode      | JSON object                                                           |
| Request JSON                           | Programmatic mode      | JSON object                                                           |
| Authentication source URL              | Saved-session mode     | Exact, public HTTPS application login URL; no wildcard                |
| Playwright saved session               | Saved-session mode     | Secure-browser capture or a storage-state JSON file smaller than 2 MB |
| QA runtime variables                   | No                     | `KEY=value`, one per line                                             |
| PR number under Run now                | No                     | Open PR number; required for diff-driven checks                       |

## Authentication-source and preview-host rules

The two settings serve different purposes:

* **Authentication source URL** is the stable page where a person signs in once.
* **Trusted preview host** constrains which deployment URLs CodeAnt may test.

They do not need to be the same hostname, but the captured authentication data must be reusable on the preview:

| Authentication storage                           | Different dynamic preview host                                                |
| ------------------------------------------------ | ----------------------------------------------------------------------------- |
| `localStorage` or IndexedDB                      | Can be copied from the configured source origin to a validated preview origin |
| Cookie valid for the preview domain              | Retained and replayed                                                         |
| Cookie valid only for an unrelated source domain | Cannot be rewritten; use another authentication strategy                      |

## Troubleshooting

<AccordionGroup>
  <Accordion title="The QA Agent settings page is missing">
    Confirm that you are using GitHub, have CodeAnt administrator access, and that Frontend QA is enabled for your organization. Contact [support@codeant.ai](mailto:support@codeant.ai) if the page is still unavailable.
  </Accordion>

  <Accordion title="A successful deployment did not start QA">
    Confirm that the QA Agent is enabled, the GitHub deployment status is `success`, the environment matches **GitHub deployment environment**, and the deployed commit belongs to an open pull request. The GitHub event must reach CodeAnt AI before the run can be queued.
  </Accordion>

  <Accordion title="CodeAnt could not resolve the preview URL">
    Verify that the deployment publishes an `environment_url` or `target_url` and that its hostname matches **Trusted preview host**. Enter a hostname pattern only—not a URL or regular expression.
  </Accordion>

  <Accordion title="No reusable authentication data was found">
    Make sure **Authentication source URL** points to the customer application and that you completed login before saving. Dynamic previews require source-origin web storage or cookies already valid for the trusted preview host. A cookie scoped only to an unrelated production domain cannot be copied to an Amplify, Vercel, or Netlify domain.
  </Accordion>

  <Accordion title="The preview loads but authentication fails">
    Reconnect the saved session if it expired. For cross-domain cookie authentication, use programmatic login, a compatible custom preview domain, or an identity-provider callback that supports the preview URL. CodeAnt never rewrites cookie domains.
  </Accordion>

  <Accordion title="The preview API or assets are blocked">
    Add each required API, CDN, font, or asset origin to **Additional trusted subresource origins**. Use exact HTTPS origins without paths or wildcards.
  </Accordion>

  <Accordion title="Programmatic login fails">
    Use a relative or same-origin endpoint, valid JSON objects for headers and request data, and a `POST` or `PUT` method. Confirm that the endpoint returns a successful response and directly creates a browser session without relying on a redirect.
  </Accordion>

  <Accordion title="The run completes with no findings">
    This can be correct. Frontend QA reports only observable failures supported by the pull request description and changed code. Validate with an open PR containing a small testable UI change and provide its PR number under **Run now**.
  </Accordion>
</AccordionGroup>

## Security notes

* Credentials, saved browser state, programmatic login recipes, and runtime variables are encrypted at rest.
* Stored secret values are not returned to the settings page; a **stored** badge indicates that encrypted data exists.
* Saved browser state is filtered to approved origins before use.
* Dynamic preview URLs must match the configured app-specific hostname pattern.
* Cloned repository context is limited to changed frontend files, and QA findings are kept only when they are grounded in the pull request description and code changes.
