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

# How tests sync

> How Peeps finds the tests in your repository, files them in folders and tags them, follows your branches, and shows tests that are only in a pull request or only in Peeps.

Peeps keeps a read-only copy of your suite: one test case per test in your repository. You never edit that copy. When a test changes in the repository, Peeps reads the change and updates the test case.

## When Peeps reads your tests

Peeps reads the tests on your [headline branch](/repository/connect#choose-the-headline-branch):

* when you connect the repository
* on every push to your repository's default branch
* when your CI reports the list of tests: a run of the Peeps workflow on your default branch, when that's also your headline branch, or a run in `inventory` mode on the headline branch
* when you change the headline branch
* when Peeps regains access to the repository, for example after the GitHub App is reinstalled
* when you click **Run inventory now** on the **Repository** page, or comment `/peeps inventory` on an issue or pull request

The **Repository** page shows when the list was last read and at which commit, and when your CI last reported a run.

<Note>
  If your headline branch isn't your repository's default branch, a push to the headline branch doesn't re-read its tests on its own. Click **Run inventory now**, comment `/peeps inventory`, or run the workflow in `inventory` mode on that branch, for example `gh workflow run peeps.yml --ref develop -f mode=inventory`. The workflow's run on that push still records its results, but new tests show as **Not on develop** until the tests are re-read.
</Note>

### Read from the repository, or reported by your CI

Peeps gets the list of tests in two ways.

* **Peeps reads the repository itself**, through GitHub or GitLab. This needs nothing from your CI, so a project shows its tests as soon as it's connected. It reads up to 400 test files per scan, and skips any file over 1 MB.
* **Your CI reports the list.** The Peeps workflow asks Playwright or pytest for the tests and sends the list to Peeps. It reads up to 2,000 test files, and sees exactly what your test runner sees, including tests in setup projects and custom file patterns.

When a scan can't read everything, the **Repository** page says **This is not all of your tests**, with how many files it read. Peeps marks nothing missing while the list is incomplete. To fix it, point the test root at the directory your suite lives in, split the repository across several projects, or let your CI report the tests.

## What makes a test

A test is its file and its title, including every `describe` block around it, such as `Checkout › pays by card`. A test that runs in several Playwright projects, such as `chromium` and `firefox`, is one test case with a result for each.

Because the title is part of what identifies a test, **renaming a test makes a new test case**, and the old one is marked missing. Its run history stays with the old case. Moving or renaming a file in a push keeps the test case.

## Folders

Each test case is filed in a folder that matches its file's directory, relative to the test root. With the test root at `e2e`, a test in `e2e/crm/deals/won.spec.ts` is filed in **crm › deals**.

* A test file directly in the test root is left unfiled.
* Folders go five levels deep. A deeper file is filed in the fifth level.
* A folder goes once no test case is left in it. A test whose file was deleted is marked missing and stays in its folder until you archive it. The folder comes back if the directory does.
* These folders follow your repository, so you can't rename, move or delete them, or move a test case out of one.

Your own folders are never changed. If one of your folders already has a directory's name in the same place, the tests from that directory stay unfiled.

## Tags

Playwright tags, such as `@smoke` in a test's `tag` option or in its title or a `describe` title, become the test case's tags. So do pytest markers, except the ones that configure a test rather than describe it, such as `parametrize`, `skip` and `dependency`.

## When a test goes missing

When a test is no longer on the headline branch, its test case is marked missing rather than deleted. Peeps tells you which happened: the file was deleted, or the file is still there and the test isn't in it, which is what a renamed test looks like.

A missing test case keeps its runs and its history, and Peeps doesn't run it. If the test comes back, the same test case picks up where it left off.

## Tracked branches

The headline branch defines which tests exist. Peeps also follows other branches you care about, such as `staging` or `qa`, so it can say which tests are on each, and so fixes and new tests can target them.

The **Tracked branches** card on the **Repository** page lists them, with the reason Peeps follows each:

| Reason | What it means |
| - | - |
| **headline** | It's the headline branch. Peeps always follows it. |
| **protected** | The branch is protected in your repository. |
| **in your Peeps workflow** | The branch is named in the `push` trigger of your Peeps workflow. Patterns such as `release/**` don't count. |
| **runs in the last 30 days** | Your CI reported a run from it in the last 30 days, and it has a common long-lived name, such as `main`, `develop`, `staging`, `qa`, `uat`, `production` or `release/*`. |

A branch stops being followed when the reason goes away, for example when it's deleted. Feature branches aren't followed, though their runs are still recorded.

To change the list, open the menu on a branch:

* **Pin** follows a branch whatever the reasons. You can also click **Add branch** to pin one.
* **Exclude** stops Peeps following it, however many reasons it has. You can't exclude the headline branch.
* **Clear override** goes back to following the reasons.

Click **Refresh** to read the branches again straight away.

### Where each test is

When Peeps follows more than one branch, it shows where each test is:

* A test case's page has a **Branches** card with one line per branch: whether the test is there, and its latest result there.
* In the test case list, a test that isn't on the headline branch yet says which branches it is on, such as **Not on main — on staging, qa**.
* The list's header names the branch it shows. When Peeps follows several, pick another branch there to see the list as that branch has it.

## Tests in a pull request

When a pull request adds a test and its CI run reports to Peeps, Peeps creates the test case straight away, marked **In pull request #N**, with a link to the pull request. Its runs on that pull request are recorded.

* **Merged:** the test reaches the headline branch, and the test case becomes an ordinary one.
* **Closed without merging:** the test case is archived and says the pull request was closed. If the pull request reopens, the test case comes back when its CI run reports the test again.

## Tests only in Peeps

A test case you write in Peeps, rather than in your repository, is marked **Peeps only**. It has no file yet, so nothing can run it. Use [Generate in your repository](/repository/add-a-test) to have Peeps write the test and open a pull request for it.

## Python tests

Peeps reads pytest tests when your repository has a `pytest.ini`, a `conftest.py`, or a `pyproject.toml` with a `[tool.pytest.ini_options]` section. It reads `test_*.py` and `*_test.py` files under the test root without running them.

To keep backend unit tests out of the project, Peeps lists a pytest file only when it uses Playwright: directly, through a `conftest.py`, or through a module it imports, such as your own helpers or page objects. To list every pytest file under the test root, turn on **Include every pytest test under the test root** in the project's settings. Turning it off again doesn't remove tests it already listed.

Tests are named the way pytest names them, with `›` between the parts: `TestContacts › test_add[lead]`.

***

Something not syncing? See [the FAQ](/repository/faq).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.