# Gespeicherte Tests

> Quelle: https://astrallab.dev/de/docs/saved-tests

Ein Ablauf, den ein Agent getestet hat, lässt sich als gespeicherter Test aufbewahren: ein Skript plus einige Angaben (Name, Ticket, Umgebung, verwendete Zugangsdaten, Aufzeichnungsmodus). Jeder Agent kann ihn wiedergeben, Sie können ihm zusehen, und die CI kann ihn ausführen.

## Wo Tests liegen

- **Projekttests** werden in `.astral/tests/<id>.astral.js` in Ihrem Projekt gespeichert und mit Ihrem Repository versioniert. Die ID ist ein Slug des Testnamens.
- **Temporäre Tests** liegen im Datenordner von Astral und laufen nach einer Anzahl von Tagen ab (standardmäßig 7).

Der Agent speichert einen mit `test_save` und kann ihn mit einem Ticket verknüpfen. Ein gespeicherter Test gibt das Skript wieder, nicht das Modell, sodass eine Wiedergabe keine Modell-Tokens verbraucht und jedes Mal dieselben Schritte ausführt.

```js
return await astral.test('Login', async () => {
  await astral.step('Open the login page', () => astral.navigate({url: astral.url('/login')}));
  await astral.step('Sign in', async () => {
    await astral.fill({locator: {role: 'textbox', name: 'Email'}, credential: 'shop.demo', field: 'username'});
    await astral.fill({locator: {role: 'textbox', name: 'Password', exact: true}, credential: 'shop.demo', field: 'password'});
    await astral.click({locator: {role: 'button', name: 'Sign in'}});
    await astral.expect.url('/account');
  });
}, {record: 'actions'});
```

## .astral/config.json

Die `.astral/config.json` des Projekts deklariert die Umgebungen, gegen die Ihre Tests laufen, und die Zugangsdaten, die sie verwenden dürfen, **per Name**. Tests navigieren mit `astral.url('/login')`, sodass derselbe Test gegen lokal, Staging oder Produktion läuft.

```json
{
  "project": "shop",
  "envs": {
    "local":   { "baseUrl": "http://localhost:3000" },
    "staging": { "baseUrl": "https://staging.example.com" },
    "prod":    { "baseUrl": "https://www.example.com", "protected": true }
  },
  "defaultEnv": "local",
  "collections": {
    "smoke": { "name": "Smoke", "tests": ["login", "checkout"] }
  },
  "credentials": {
    "shop.demo": {
      "username": "demo@example.com",
      "password": { "keychain": "shop.demo.password" }
    }
  }
}
```

| Schlüssel | Was es ist |
| --- | --- |
| `envs` | Benannte Basis-URLs. `protected: true` kennzeichnet eine Umgebung wie die Produktion. Kein Benutzername und kein Passwort in der URL. |
| `defaultEnv` | Die Umgebung, die verwendet wird, wenn keine angegeben ist. |
| `collections` | Tests, die der Reihe nach als eine Gruppe laufen, mit einer Zusammenfassung aus bestanden oder fehlgeschlagen und einem Bericht, der auf den jedes Tests verweist. |
| `credentials` | Benannte Logins: ein Benutzername, ein Passwort, ein Seed für Einmalcodes und zusätzliche Felder. Geheimnisse sind Verweise, niemals Werte. |
| `layout` | Selektoren, die die Layout-Prüfung ignoriert, und ihre Schwellenwerte. |

## Zugangsdaten und der Schlüsselbund

Ein Geheimnis in `config.json` ist ein Verweis darauf, wo es liegt, niemals der Wert. Ein Klartext-Passwort in der Datei wird abgelehnt. Ein Verweis ist einer dieser Arten:

```
{ "keychain": "<id>" }
{ "env": "ASTRAL_TEST_<NAME>" }
{ "local": "<key>" }
```

| Verweis | Wo der Wert liegt |
| --- | --- |
| `keychain` | Ihr System-Schlüsselbund. Sie legen ihn in Astral an; ein Agent kann ihn nie wieder auslesen. |
| `env` | Eine Umgebungsvariable, deren Name mit `ASTRAL_TEST_` beginnt. |
| `local` | `.astral/secrets.local.json`, die in der `.gitignore` stehen muss. Andernfalls weigert sich Astral, sie anzulegen, und warnt, wenn sie bereits existiert, ohne ignoriert zu werden. |

- Der Agent sieht nur den Namen der Zugangsdaten und den Benutzernamen. `astral.fill` löst den Wert selbst auf und tippt ihn mit echten Tastenanschlägen; der Agent erfährt nur, dass er getippt und maskiert wurde.
- Ein Geheimnis wird nur in ein sensibles Feld (Passwort, Einmalcode, Karte) auf dem eigenen Origin der Umgebung getippt, sodass es weder zurückgelesen noch an eine andere Website gesendet werden kann. Berichte zeigen stattdessen ••••••.
- Ein Schlüsselbund-Geheimnis wird zusammen mit den Origins der Umgebungen zu diesem Zeitpunkt gespeichert und nur dort getippt, selbst wenn `config.json` später bearbeitet wird. Für sensible Logins ist der Schlüsselbund vorzuziehen.

## Geschützte Umgebungen

In einer als `protected` markierten Umgebung (etwa Produktion) laufen nur Tests, die als `readOnly` deklariert sind, und zwar erst, nachdem eine Person genau diese Version des Tests in Astral genehmigt hat. Ein Agent kann `readOnly: true` anfordern, aber das ist eine Anfrage, keine Genehmigung: Sie genehmigen sie mit **Approve as read-only** im Panel Tests, die Genehmigung wird außerhalb des Projekts gespeichert und geht verloren, wenn der Test bearbeitet wird. In einer Collection werden nicht genehmigte Tests mit Angabe des Grundes übersprungen.

## Viewports

Ein Test oder eine Collection kann in einem oder mehreren Viewports laufen, und Astral führt jeden Test in jedem davon aus.

| Voreinstellung | Größe (CSS-px) | Pixeldichte | Touch |
| --- | --- | --- | --- |
| `mobile` | 390 × 844 | 3   | ja  |
| `tablet` | 820 × 1180 | 2   | ja  |
| `desktop` | 1440 × 900 | 1   | nein |

Ein benutzerdefinierter Viewport hat eine Breite und eine Höhe von 200 bis 4096 px und optional eine Pixeldichte, Touch, einen User-Agent und einen Namen. In Astral wird das Panel des Tabs für den Lauf auf den Viewport angepasst und danach auf seine eigene Größe zurückgesetzt; Pixeldichte, Touch und User-Agent werden dort nicht emuliert, und der Lauf weist darauf hin. Der Headless-Runner mit Chrome emuliert sie alle.

## Die Layout-Prüfung

Die Layout-Prüfung betrachtet die Seite so, wie sie gerendert wird, und meldet Befunde, jeweils mit Regel, Schweregrad, Selektor, Rechteck, Meldung und einem vorgeschlagenen CSS-Fix.

| Regel | Was sie findet |
| --- | --- |
| `horizontal-overflow` | Die Seite ist breiter als der Viewport; sie nennt das Element, das herausragt. |
| `overlap` | Sichtbarer Text oder Bedienelemente, die einander überdecken. |
| `text-clipped` | Durch Overflow abgeschnittener Text oder ein langes Wort, das aus seinem Kasten herausläuft. |
| `offscreen` | Ein Bedienelement außerhalb des horizontalen Viewports. |
| `tap-target` | Ein Touch-Ziel unter 24 × 24 px ist ein Fehler; unter 44 × 44 eine Warnung. Nur bei Touch-Viewports. |
| `small-text` | Text unter 12 px auf Bildschirmen bis 600 px Breite. |

Drei Arten, sie zu nutzen:

- Das Tool [`layout_check`](https://astrallab.dev/de/docs/tools.md#tool-layout_check): Der Agent findet ein Problem, behebt das CSS und prüft erneut.
- `astral.expect.layout()` als Schritt eines Tests.
- `layoutCheck: true` bei einem Test oder einer Collection, um am Ende jedes Viewport-Laufs eine Prüfung hinzuzufügen.

```json
{
  "collections": {
    "rwd": { "name": "Responsive", "tests": ["home", "checkout"], "viewports": ["mobile", "tablet", "desktop"], "layoutCheck": true }
  },
  "layout": { "ignore": [".chat-widget", "#cookie-banner"] }
}
```

Mit einem Screenshot wird die Seite mit umrandeten Befunden erfasst. Bei einer Engine, die Seiten nicht layoutet, wird die Prüfung als übersprungen gemeldet, nie als bestanden.

## Wiedergabe mit Play

Der Agent ruft `test_open_in_astral` auf, und Astral öffnet sein Panel Tests mit dem geladenen und pausierten Test. Mit **Play** sehen Sie ihm beim Laufen zu: Zeitlupe, Pause, Einzelschritt und Stopp. Standardmäßig kann der Agent ihn nicht starten: Play ist auch eine Sicherheitskontrolle. Für Demos und Reviews, die Sie ihn leiten ließen, kann der Agent ihn mit `play: true` starten; das erfordert dieselbe Berechtigung wie `test_run`, funktioniert nur für Tests, die in einem von Ihnen erlaubten Projekt gespeichert sind, und Sie behalten Pause, Step und Stop.
