# Testes salvos

> Fonte: https://astrallab.dev/pt/docs/saved-tests

Um fluxo que um agente testou pode ser guardado como um teste salvo: um script mais alguns detalhes (nome, ticket, ambiente, credenciais que usa, modo de gravação). Qualquer agente pode reproduzi-lo, você pode assisti-lo e o CI pode executá-lo.

## Onde os testes ficam

- Os **testes de projeto** são salvos em `.astral/tests/<id>.astral.js` dentro do seu projeto e versionados com o seu repositório. O id é um slug do nome do teste.
- Os **testes temporários** ficam na pasta de dados do Astral e expiram após alguns dias (7 por padrão).

O agente salva um com `test_save` e pode vinculá-lo a um ticket. Um teste salvo reproduz o script, não o modelo, então uma reprodução não gasta tokens do modelo e executa os mesmos passos todas as vezes.

```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

O `.astral/config.json` do projeto declara os ambientes contra os quais os seus testes rodam e as credenciais que eles podem usar, **por nome**. Os testes navegam com `astral.url('/login')`, de modo que o mesmo teste roda contra local, staging ou produção.

```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" }
    }
  }
}
```

| Chave | O que é |
| --- | --- |
| `envs` | URLs base nomeadas. `protected: true` marca um ambiente como produção. Sem usuário nem senha na URL. |
| `defaultEnv` | O ambiente usado quando nenhum é informado. |
| `collections` | Testes executados em ordem como um grupo, com um resumo de sucesso ou falha e um relatório que liga o de cada teste. |
| `credentials` | Logins nomeados: um usuário, uma senha, uma semente de código de uso único e campos extras. Os segredos são referências, nunca valores. |
| `layout` | Seletores que a verificação de layout ignora e seus limites. |

## Credenciais e o chaveiro

Um segredo em `config.json` é uma referência a onde ele está, nunca o valor. Uma senha em texto simples no arquivo é rejeitada. Uma referência é uma destas:

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

| Referência | Onde está o valor |
| --- | --- |
| `keychain` | O chaveiro do seu sistema. Você o define no Astral; um agente nunca consegue lê-lo de volta. |
| `env` | Uma variável de ambiente cujo nome começa com `ASTRAL_TEST_`. |
| `local` | `.astral/secrets.local.json`, que deve estar no `.gitignore`. Caso contrário, o Astral se recusa a criá-lo e avisa se ele já existir sem estar ignorado. |

- O agente só vê o nome da credencial e o nome de usuário. O `astral.fill` resolve o valor por conta própria e o digita com teclas reais; o agente só fica sabendo que ele foi digitado e mascarado.
- Um segredo só é digitado em um campo sensível (senha, código de uso único, cartão) na própria origem do ambiente, de modo que não pode ser lido de volta nem enviado a outro site. Os relatórios mostram •••••• no lugar dele.
- Um segredo do chaveiro é armazenado junto com as origens dos ambientes naquele momento e só é digitado nelas, mesmo que o `config.json` seja editado depois. Para logins sensíveis, prefira o chaveiro.

## Ambientes protegidos

Em um ambiente marcado como `protected` (produção, por exemplo), só rodam os testes declarados `readOnly`, e só depois que uma pessoa aprova no Astral essa versão exata do teste. Um agente pode pedir `readOnly: true`, mas isso é um pedido, não uma aprovação: você a aprova com **Approve as read-only** no painel Tests, a aprovação é guardada fora do projeto e se perde se o teste for editado. Em uma coleção, os testes não aprovados são ignorados, com o motivo.

## Viewports

Um teste ou uma coleção pode rodar em um ou vários viewports, e o Astral executa cada teste em cada um deles.

| Predefinição | Tamanho (px CSS) | Densidade de pixels | Toque |
| --- | --- | --- | --- |
| `mobile` | 390 × 844 | 3   | sim |
| `tablet` | 820 × 1180 | 2   | sim |
| `desktop` | 1440 × 900 | 1   | não |

Um viewport personalizado tem largura e altura de 200 a 4096 px e, opcionalmente, densidade de pixels, toque, um user agent e um nome. Dentro do Astral, o painel da aba é redimensionado para o viewport durante a execução e depois volta ao seu tamanho; a densidade de pixels, o toque e o user agent não são emulados ali, e a execução avisa isso. O runner headless com Chrome emula todos eles.

## A verificação de layout

A verificação de layout examina a página como ela é renderizada e relata problemas, cada um com uma regra, uma gravidade, um seletor, um retângulo, uma mensagem e uma correção de CSS sugerida.

| Regra | O que ela encontra |
| --- | --- |
| `horizontal-overflow` | A página é mais larga que o viewport; ela indica o elemento que escapa. |
| `overlap` | Texto ou controles visíveis uns sobre os outros. |
| `text-clipped` | Texto cortado por overflow, ou uma palavra longa que transborda da sua caixa. |
| `offscreen` | Um controle fora do viewport horizontal. |
| `tap-target` | Um alvo de toque abaixo de 24 × 24 px é um erro; abaixo de 44 × 44, um aviso. Somente em viewports de toque. |
| `small-text` | Texto abaixo de 12 px em telas de até 600 px de largura. |

Três formas de usá-la:

- A ferramenta [`layout_check`](https://astrallab.dev/pt/docs/tools.md#tool-layout_check): o agente encontra um problema, corrige o CSS e verifica de novo.
- `astral.expect.layout()` como um passo de um teste.
- `layoutCheck: true` em um teste ou coleção, para adicionar uma verificação ao final de cada execução por viewport.

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

Com uma captura de tela, a página é capturada com cada problema destacado. Em um motor que não faz o layout das páginas, a verificação é relatada como ignorada, nunca como aprovada.

## Reprodução com Play

O agente chama `test_open_in_astral` e o Astral abre o seu painel Tests com o teste carregado e em pausa. Você pressiona **Play** para assisti-lo rodar: câmera lenta, pausa, passo a passo e parar. Por padrão, o agente não pode iniciá-lo: o Play também é um controle de segurança. Para demos e revisões que você pediu que ele conduzisse, o agente pode iniciá-lo com `play: true`; isso exige a mesma permissão que `test_run`, funciona apenas para testes salvos em um projeto que você permitiu, e você mantém Pause, Step e Stop.
