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

# Overnight and scheduled test runs

> Run your checks every night, or on a schedule while Mobster runs, and hear when one fails.

Two ways to run checks with no one at the keyboard: `mobster test nightly` writes a LaunchAgent that runs whether or not Mobster is open, and `.mobster/schedule.yaml` runs checks while Mobster runs.

## Run your checks every night

From your project folder, schedule your saved checks on a simulator:

```sh theme={"theme":"css-variables"}
mobster test nightly on --at 02:00 --sim "iPhone 17 Pro"
```

It prints the schedule and the report path, `.mobster/nightly/<date>/morning.md`. Keep this Mac on power and signed in. `mobster test nightly off` removes the schedule.

To include every plugged-in iPhone, add `--device all` after you [set up those phones for checks](https://docs.mobster.dev/testing/devices.md#run-checks-on-your-iphone).

* `nightly on` writes a LaunchAgent for your user, `~/Library/LaunchAgents/dev.mobster.nightly.<project>.plist`, so the run reaches your simulators and plugged-in iPhones and opens no window. A Mac asleep at that time runs it when it wakes.
* Each night is `mobster test --video` with the flags you gave `nightly on` (`--sim`, `--device`, `--tag`, `--parallel`, `--retries`, `--keyless`), into `.mobster/nightly/<date>/`: the HTML report, `junit.xml` and `morning.md`.
* `morning.md` starts with the verdict, then lists each check that failed or was flaky, with why and the command that runs it again. A notification says the verdict, and a night that didn't pass posts to `MOBSTER_ALERT_WEBHOOK_URL` (Slack, Discord, ntfy or JSON) when you set one.
* `nightly status` says when it runs and last night's verdict, `nightly run` runs one night now, and `nightly off` removes the agent.

## Run checks on a schedule

While Mobster runs (Mobster for Mac, or `mobster serve`), it runs checks on a schedule and tells you when one doesn't pass, so a backend or a build that broke overnight shows up without a CI job. Name the schedules in `.mobster/schedule.yaml`:

```yaml theme={"theme":"css-variables"}
timezone: America/Los_Angeles
schedules:
  - name: smoke
    every: 1h
    tags: [smoke]
    sim: iPhone 17 Pro
  - name: nightly-full
    cron: "0 3 * * *"
```

or put one line in a check file, which makes that check a schedule of its own on its own simulator:

```yaml theme={"theme":"css-variables"}
schedule: every 30m
```

`every` takes minutes, hours or days (`30m`, `1h`, `1d`), from 5 minutes to 7 days. `cron` takes five fields, at least 5 minutes apart. `tags` or `checks` pick the checks. Without them the schedule runs every check. A repository file never names a real iPhone.

While Mobster for Mac is open, it runs schedules for every project you add in the app and every folder where you run `mobster test`. Your schedules skip times when your Mac is asleep or Mobster is closed, and those runs are recorded as skipped. Your project's schedules are under **Schedules** on its page ([Projects](https://docs.mobster.dev/projects.md#a-projects-page)).

```sh theme={"theme":"css-variables"}
mobster test schedule list
```

```text theme={"theme":"css-variables"}
smoke                    every 1h       next Sun 14:05  on iPhone 17 Pro  last ran passed
check feed               every 30m      next Sun 13:35  on each check's simulator  last skipped (Another scheduled run is going, so this one was skipped, not queued.)
```

## Change a schedule

* **Turn one off on this Mac.** The switch in a project's Schedules section, or `mobster test schedule off smoke` and `mobster test schedule on smoke`, turn a schedule off on this Mac only. `.mobster/schedule.yaml` stays as it is. An off schedule never runs, and turned on again, it waits for its next time. `mobster test schedule list` shows it as `off on this Mac`. If Mobster can't read which ones are off, no schedule runs until you switch one.
* **Attach an iPhone.** `mobster test schedule device smoke "Test iPhone"` attaches an iPhone to a schedule on this Mac, outside the repository, and `none` takes it off. Removing a schedule takes its iPhone off, and a schedule you add from Mobster never inherits one. Only a running Mobster uses it, and only if no task or other command holds the phone.
* **Run one now.** `mobster test schedule run-now smoke` runs it in this command, on the schedule's simulator, or the `--sim` or `--device` you give. It never uses the attached phone.
* **Edit it in the app.** Open **Schedules** on your project page. With no schedule yet, turn on **Run every night** to add `Nightly` at `0 2 * * *` in your Mac's time zone. **Change schedule** sets a schedule's days and time, and its time zone when it is the only schedule in the file. **Remove schedule** asks you to confirm. **Run now** runs its checks now. Saving or removing a schedule drops the comments in `.mobster/schedule.yaml`, and the app warns you first. Edit schedules set in check files in those files.

## Know what a scheduled run does

* **Results.** A scheduled suite is a normal suite: its reports are in `.mobster/test-results/`, and each result joins the [history](https://docs.mobster.dev/testing/flaky.md#find-your-flaky-checks). `list --json` includes the last 20 runs of each schedule.
* **Skips.** Mobster runs one scheduled suite at a time and never queues. It records a run as skipped, with the reason, when another scheduled suite is going, a task or another Mobster process holds the phone, Mobster for Mac is signed out for a run on a phone, the project can't plan the run, or Mobster wasn't running at that time.
* **Failures.** A scheduled suite that doesn't pass posts to the Slack rule in `.mobster/notifications.yaml` ([Tell Slack how a suite ended](https://docs.mobster.dev/testing/share.md#tell-slack-how-a-suite-ended)). With no rule, you get a notification on this Mac.
* **Shutdown.** Mobster cancels an active scheduled suite and waits for it before it releases the phone.

## Manage schedules over the API

| Route | What it does |
| - | - |
| `GET /api/tests/schedules` | Lists them, with the file's `timezone`, `timezoneSet` (whether the file sets it) and `commented` (whether saving drops comments) |
| `POST /api/tests/schedules/run-now` | `{project, schedule}` starts one, or answers 409 with the reason when another is going |
| `POST /api/tests/schedules/device` | Attaches a phone |
| `POST /api/tests/schedules/switch` | `{project, schedule, on}` turns one off or on |
| `POST /api/tests/schedules/set` | `{project, name, when, timezone?}` adds a schedule to `.mobster/schedule.yaml`, or replaces the one with that name and keeps its `checks`, `tags` and `sim`. `when` is an interval such as `every 1h` or a five-field cron |
| `POST /api/tests/schedules/remove` | `{project, schedule}` removes one |

`set` and `remove` answer with your project's listing, or `400 bad_request` for input that can't load, `409 schedule_file_problem` when the file has a problem (it stays unchanged), `409 schedule_in_check` for a schedule set in a check file, `404 schedule_not_found`, or `403 unwritable`. `project` is a folder where you run `mobster test` or a project you added in the app. When Mobster for Mac sets up a private app session, these writes need its session proof.


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