Criação da bateria de testes automatizados, correção da pagina de gerar romaneio e plano da criação do modulo cliente
This commit is contained in:
195
README.md
195
README.md
@@ -3513,3 +3513,198 @@ Dockerfile # tira a linha de precompile mort
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><strong>🆕 Atualização 28/08/2026 — PLANO: Módulo do Cliente (aprovado, NÃO implementado)</strong></summary>
|
||||
|
||||
> ⚠️ **Isto é um plano de implementação, não uma feature entregue.** Foi escrito
|
||||
> como ordem de serviço para ser executado em fases (inclusive por modelos
|
||||
> menores), com o levantamento do código já feito. Implementar **uma fase por
|
||||
> vez**, na ordem, validando cada uma antes da próxima.
|
||||
|
||||
## O que é o módulo
|
||||
|
||||
Hoje o cliente (Gade Hospitalar) manda uma **planilha** por mês/operação, que
|
||||
alguém sobe no banco como tabela `gade_entregas_*` (fora do sistema). O módulo
|
||||
do cliente substitui esse fluxo: uma área **`/cliente`** com login próprio onde
|
||||
o próprio cliente:
|
||||
|
||||
1. **Cria operações** (ex.: "UBS NORTE — setembro/2026") e lança entregas nelas;
|
||||
2. **Adiciona entregas em operações existentes**;
|
||||
3. Lança **entregas avulsas** (fora de qualquer operação);
|
||||
4. Cadastra **em massa via planilha .xlsx** (o módulo é um espelho da planilha
|
||||
atual — mesmos campos), com conferência antes de gravar;
|
||||
5. Recebe **detecção de duplicidade na hora**: "você tem X apontamentos
|
||||
duplicados" e "a NF Y já está roteirizada / em curso".
|
||||
|
||||
## 🔒 Regras invioláveis (valem para TODAS as fases)
|
||||
|
||||
- `db_reem_simplerout_2026` e as `gade_entregas_*` são **somente leitura**:
|
||||
nunca migration, nunca INSERT/UPDATE/DELETE/DROP nelas. O módulo grava apenas
|
||||
em **tabelas próprias novas**.
|
||||
- Todo nome de tabela externa que entra em SQL passa por `Operacao.sanitizar` +
|
||||
`quote_table_name` (padrão já usado no projeto inteiro).
|
||||
- **NÃO transformar `app/models/operacao.rb` em ActiveRecord.** Ele é um PORO
|
||||
(só métodos de classe) que descobre as tabelas externas pelo catálogo do
|
||||
Postgres e é usado por ~8 services. Os models novos têm outros nomes.
|
||||
- Seguir o CLAUDE.md do projeto: número na tela é contrato; modo de visualização
|
||||
em aba, não tela nova; mobile-first com alvos de 48px; comentário explica o
|
||||
porquê; validar com Docker (`ruby -c` / actionview) antes de entregar.
|
||||
- Ao final de cada fase: listar os `git add` por nome (commit/push são do
|
||||
usuário) e lembrar que o deploy para o teste é manual.
|
||||
|
||||
## 📌 Fatos do código que o implementador precisa saber
|
||||
|
||||
| Assunto | Onde está | O que copiar |
|
||||
|---|---|---|
|
||||
| "Operação" hoje | `app/models/operacao.rb` (PORO) | catálogo/whitelist (`nomes_validos`, `sanitizar`, `label`, `MESES`) — só consumir |
|
||||
| Colunas da planilha do cliente | `app/services/simpli_route/planilha_carga.rb` (`COLUNAS_OP`) | `nota_fiscal`, `nome_completo`, `endereco_sem_complemento`, `complemento`, `supervisao`, `telefones`; geo nas gade é `lat`/`long` |
|
||||
| Esquema variável por mês | `app/services/romaneios/enriquecimento_gade.rb` | detecção de colunas via `conn.columns(tabela)`; só `nota_fiscal` é garantida |
|
||||
| Dedup existente (melhor modelo) | `app/services/romaneios/importador.rb#deduplicar` + `RomaneioLinha.chave_para` + `app/services/romaneios/normalizador.rb` | chave normalizada (NF + título + endereço), primeira ocorrência vence, contagem reportada |
|
||||
| Rastreio (roteirizado/em curso) | `app/models/entrega.rb` (`db_reem_simplerout_2026`, `readonly?=true`) | scopes `da_conta_gade`, `por_nf`; status da visita indica o andamento |
|
||||
| Ler .xlsx | gem `roo` (~2.10, já no Gemfile; usada no romaneio) | |
|
||||
| Gerar .xlsx | gem `caxlsx` (já no Gemfile; usada na planilha SimpliRoute) | |
|
||||
| Papéis/permissões | `app/models/user.rb` (enum `role`), `app/models/permissao.rb`, `app/models/perfil_acesso.rb`, policies em `app/policies/` | `Permissao::TODAS` + `GRUPOS` + `PADRAO_POR_ROLE` (esquecer o PADRAO tira acesso silenciosamente — aviso no próprio model) |
|
||||
| Migration de permissão (modelo) | `db/migrate/20260827000004_add_permissao_romaneio_aos_perfis.rb` | sincronizar perfis existentes |
|
||||
| Rotas | `config/routes.rb` | seguir o padrão `namespace :admin`; atenção ao aviso do Inflector pt-BR no próprio arquivo (singular == plural gera `_index`) |
|
||||
| Notificações (evento novo) | infra em `app/models/notificacao_*` / `app/services/notificacao/` | criar evento "cliente lançou entregas" na Fase 5 |
|
||||
|
||||
**Não existe hoje nenhum conceito de "cliente" no código** (nem model, nem
|
||||
coluna, nem namespace) — a fundação é a Fase 0.
|
||||
|
||||
## Fase 0 — Fundação de acesso (`/cliente` existe e loga)
|
||||
|
||||
1. `User`: adicionar `cliente: 5` ao enum `role`.
|
||||
2. `Permissao`: novas chaves no grupo novo `cliente`:
|
||||
`cliente.ver`, `cliente.operacoes_criar`, `cliente.entregas_lancar`,
|
||||
`cliente.importar_planilha`, `cliente.avulsas` — em `TODAS`, `GRUPOS` e
|
||||
`PADRAO_POR_ROLE` (role `cliente` recebe todas as `cliente.*` e NADA de
|
||||
dashboard/consolidação/admin).
|
||||
3. `HOME_POR_PERMISSAO` / `home_rota`: usuário com `cliente.ver` cai em `/cliente`.
|
||||
4. Rotas: `namespace :cliente` com `root`, `resources :operacoes` (conferir o
|
||||
plural com o Inflector), `resources :entregas`, `resource :importacao`.
|
||||
5. Layout `app/views/layouts/cliente.html.erb`: identidade visual do projeto
|
||||
(dark, laranja `#f97316`), **sem** menus de admin; menu próprio: Operações ·
|
||||
Avulsas · Importar planilha · Sair.
|
||||
6. Policies Pundit novas baseadas em `user.pode?('cliente.…')`; os controllers
|
||||
de `/cliente` herdam de um `Cliente::BaseController` que bloqueia quem não
|
||||
tem `cliente.ver`.
|
||||
7. Migration sincronizando perfis + seeds: perfil "Cliente" e um usuário de
|
||||
teste `cliente@reem.com`.
|
||||
|
||||
**Pronto quando**: login com usuário cliente cai em `/cliente` (vazio, com estado
|
||||
vazio instrutivo), e esse usuário NÃO acessa `/dashboard`, `/consolidacoes` nem
|
||||
`/admin/*` (redireciona para `/sem-acesso`); admin continua acessando tudo.
|
||||
|
||||
## Fase 1 — Modelagem (tabelas próprias)
|
||||
|
||||
1. `ClienteOperacao` (`cliente_operacoes`): `nome`, `mes`, `ano`,
|
||||
`status` (enum: `rascunho` → `enviada` → `roteirizada` → `fechada`),
|
||||
`criado_por_id` (FK users), timestamps. Índice único em
|
||||
`[nome, mes, ano]` (case-insensitive).
|
||||
2. `ClienteEntrega` (`cliente_entregas`): `cliente_operacao_id` (**nulo =
|
||||
avulsa**), campos espelhando a planilha atual — `nota_fiscal`,
|
||||
`nome_completo`, `endereco_sem_complemento`, `complemento`, `supervisao`,
|
||||
`telefones`, `lat`, `long`, `observacoes` — mais `chave_dedup` (string
|
||||
normalizada), `origem` (enum: `manual`/`planilha`), `criado_por_id`,
|
||||
timestamps.
|
||||
3. `chave_dedup`: gerada em callback com a MESMA normalização de
|
||||
`Romaneios::Normalizador` (extrair para um módulo compartilhável se preciso,
|
||||
sem quebrar os chamadores atuais). Índice único parcial em
|
||||
`[cliente_operacao_id, chave_dedup]` — e validação amigável antes do índice.
|
||||
4. Validações: `nota_fiscal` obrigatória; `nome_completo` ou endereço presentes.
|
||||
|
||||
**Pronto quando**: migrations rodam no Docker, models com validações e specs de
|
||||
unicidade; nada de tela ainda.
|
||||
|
||||
## Fase 2 — Telas `/cliente` (cadastro individual intuitivo)
|
||||
|
||||
1. **Lista de operações**: cards (nome, mês/ano, nº de entregas, status, botão
|
||||
"Adicionar entrega"); estado vazio dizendo o que fazer ("Crie sua primeira
|
||||
operação ou importe uma planilha").
|
||||
2. **Criar operação**: form curto (nome + mês/ano), sem jargão técnico.
|
||||
3. **Adicionar entrega**: form mobile-first (alvos 48–56px), campos na ordem da
|
||||
planilha, busca de endereço livre; ao salvar, o painel de duplicidade da
|
||||
Fase 4 responde na mesma tela (inline, não outra página).
|
||||
4. **Entregas avulsas**: mesma tela de lançamento com aba/rótulo "Avulsa
|
||||
(sem operação)" — mesma unidade, rótulo explícito (regra 1 do CLAUDE.md).
|
||||
5. Lista de entregas da operação com edição inline (padrão Stimulus do projeto,
|
||||
ver `romaneio_controller.js`) e remoção com confirmação.
|
||||
|
||||
**Pronto quando**: fluxo completo criar operação → lançar 3 entregas → editar →
|
||||
remover, no desktop e no celular (validar com agent-browser + `set device`).
|
||||
|
||||
## Fase 3 — Importação em massa (.xlsx)
|
||||
|
||||
1. **Modelo para download**: gerar com `caxlsx` uma planilha com o cabeçalho
|
||||
exato dos campos da Fase 1 + 2 linhas de exemplo (o cliente já conhece esse
|
||||
formato — é a planilha que ele manda hoje).
|
||||
2. **Upload**: `roo` lendo .xlsx; mapear cabeçalhos com tolerância (acentos,
|
||||
caixa, espaços — reusar normalização existente).
|
||||
3. **Tela de conferência ANTES de gravar** (nada entra direto): resumo com
|
||||
N válidas · N com erro (motivo por linha) · N duplicadas (painel da Fase 4);
|
||||
o cliente escolhe "Importar só as válidas" ou cancelar.
|
||||
4. Gravação transacional (`insert_all` ou transaction com validação); relatório
|
||||
final na tela com os mesmos números da conferência.
|
||||
5. Limites e mensagens: arquivo até ~5 MB / ~5.000 linhas; erro de formato tem
|
||||
mensagem em português dizendo o que corrigir.
|
||||
|
||||
**Pronto quando**: importar a planilha-modelo preenchida com linhas repetidas de
|
||||
propósito grava só as válidas e reporta as duplicadas com os números certos.
|
||||
|
||||
## Fase 4 — Duplicidade inteligente (`Cliente::DetectorDuplicidade`)
|
||||
|
||||
Serviço único usado pelo form individual (Fase 2) e pela importação (Fase 3).
|
||||
Entrada: coleção de entregas candidatas (+ operação alvo). Saída: para cada
|
||||
candidata, `status_duplicidade` e a evidência. **Quatro camadas, nesta ordem:**
|
||||
|
||||
1. **Dentro do lote**: chave normalizada repetida no próprio arquivo/form —
|
||||
padrão de `Romaneios::Importador#deduplicar` (primeira vence, conta o resto).
|
||||
2. **Contra o módulo**: `ClienteEntrega` já gravada com a mesma `chave_dedup`
|
||||
(na mesma operação ou avulsa do mesmo mês).
|
||||
3. **Contra as `gade_entregas_*` do mesmo mês/ano**: SELECT read-only (tabelas
|
||||
via `Operacao.sanitizar` + `quote_table_name`; só `nota_fiscal` é garantida —
|
||||
detectar colunas via `conn.columns` como no `EnriquecimentoGade`).
|
||||
4. **Contra o rastreio** (`Entrega.da_conta_gade.por_nf`): se a NF já existe no
|
||||
espelho, classificar pelo status da visita — **"já roteirizada"** (planejada)
|
||||
ou **"em curso/entregue"** (checkout feito). Conferir os valores reais de
|
||||
status no espelho antes de fixar o mapeamento.
|
||||
|
||||
Na tela (regra 1 do CLAUDE.md — explicar onde o número aparece):
|
||||
resumo "⚠️ X apontamentos duplicados neste lançamento" + lista expandível
|
||||
inline com a camada que acusou cada um ("já lançada nesta operação",
|
||||
"consta na planilha de agosto", "NF 79093 já roteirizada em 27/08").
|
||||
Duplicata **avisa e bloqueia por padrão**, com opção explícita "lançar mesmo
|
||||
assim" (grava com flag `duplicada_confirmada` para auditoria).
|
||||
|
||||
**Pronto quando**: os 4 cenários têm teste (fixtures/factories) e a tela mostra
|
||||
a contagem e o motivo camada por camada.
|
||||
|
||||
## Fase 5 — Lado admin + integração
|
||||
|
||||
1. **Visão admin**: aba/tela em `/admin` listando lançamentos do cliente por
|
||||
operação/status, com os MESMOS números que o cliente vê (recorte único).
|
||||
2. **Exportação**: baixar as entregas de uma `ClienteOperacao` no formato da
|
||||
planilha de carga do SimpliRoute (referência: `SimpliRoute::PlanilhaCarga`) —
|
||||
é o que fecha o ciclo: o que o cliente lança vira rota.
|
||||
3. **Notificação**: evento novo na infra existente ("Cliente lançou N entregas
|
||||
na operação X") para o grupo do WhatsApp da operação.
|
||||
4. **Auditoria**: registrar criar/editar/excluir/importar do módulo no padrão de
|
||||
auditoria existente (`/admin/auditoria_logs`).
|
||||
5. Transição de status da operação (`enviada` → `roteirizada`) — manual pelo
|
||||
admin nesta fase; automatizar via rastreio fica para depois.
|
||||
|
||||
**Pronto quando**: admin vê, exporta e é notificado; auditoria registra.
|
||||
|
||||
## Fase 6 — Validação e encerramento
|
||||
|
||||
1. Adicionar à `docs/BATERIA-DE-TESTES.md` os casos: login cliente; criar
|
||||
operação; lançar entrega; importar .xlsx com duplicatas propositais e conferir
|
||||
as contagens; bloqueio de acesso do cliente às áreas de admin.
|
||||
2. Rodar a bateria completa (`/bateria-testes`) no ambiente de teste após o
|
||||
deploy manual.
|
||||
3. Atualizar este README (marcar fases entregues) e o perfil "Cliente" nos seeds.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -133,7 +133,12 @@ export default class extends Controller {
|
||||
abrirPreview() {
|
||||
if (!this.hasOverlayTarget) return
|
||||
|
||||
// Classe + atributo: só o atributo `hidden` não basta, porque a utility
|
||||
// `.flex` do Tailwind vence o `[hidden] { display:none }` do preflight —
|
||||
// foi assim que o modal ficou preso na tela do /admin/romaneios/13.
|
||||
this.overlayTarget.hidden = false
|
||||
this.overlayTarget.classList.remove("hidden")
|
||||
this.overlayTarget.classList.add("flex")
|
||||
// Trava o scroll do fundo: rolar a lista atrás de um modal aberto faz o
|
||||
// operador perder o lugar quando fecha.
|
||||
document.body.style.overflow = "hidden"
|
||||
@@ -144,6 +149,8 @@ export default class extends Controller {
|
||||
if (!this.hasOverlayTarget || this.overlayTarget.hidden) return
|
||||
|
||||
this.overlayTarget.hidden = true
|
||||
this.overlayTarget.classList.remove("flex")
|
||||
this.overlayTarget.classList.add("hidden")
|
||||
document.body.style.overflow = ""
|
||||
}
|
||||
|
||||
|
||||
@@ -92,10 +92,17 @@
|
||||
|
||||
<iframe> e não <embed>/<object>: o CSP está em enforcing com
|
||||
`object_src :none`, e sem `frame_src` ele cai em `default_src :self` —
|
||||
o iframe de mesma origem passa, os outros dois não. %>
|
||||
o iframe de mesma origem passa, os outros dois não.
|
||||
|
||||
O fechado/aberto é pela CLASSE `hidden`/`flex`, não só pelo atributo
|
||||
`hidden`: as utilities do Tailwind são aplicadas depois do preflight,
|
||||
então `.flex` vence o `[hidden] { display:none }` — com `flex` fixo no
|
||||
markup o modal nascia aberto, em branco e sem fechar, cobrindo a tela
|
||||
inteira (caso real: /admin/romaneios/13). O controller troca as classes
|
||||
e mantém o atributo sincronizado. %>
|
||||
<div data-romaneio-target="overlay" hidden
|
||||
data-action="click->romaneio#fecharPorFora keydown.esc@window->romaneio#fecharPreview"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center p-3 sm:p-6
|
||||
class="fixed inset-0 z-50 hidden items-center justify-center p-3 sm:p-6
|
||||
bg-black/70 backdrop-blur-sm">
|
||||
<div class="w-full max-w-6xl h-[92vh] flex flex-col gap-3"
|
||||
data-romaneio-target="caixaPreview">
|
||||
|
||||
212
docs/BATERIA-DE-TESTES.md
Normal file
212
docs/BATERIA-DE-TESTES.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# Bateria de testes — Reem Notas (ambiente de teste)
|
||||
|
||||
Roteiro de regressão para ser executado por um agente (inclusive modelos menores)
|
||||
com a skill `agent-browser`. Não é preciso conhecer o projeto: siga os casos na
|
||||
ordem e preencha o relatório do final.
|
||||
|
||||
## Regras de segurança (leia antes de tudo)
|
||||
|
||||
1. **Somente leitura + interações seguras.** É PROIBIDO:
|
||||
- clicar em qualquer botão que abra confirmação (`Tem certeza?`, `Rebuscar o
|
||||
plano?` etc.) — se a confirmação abrir por engano, cancele;
|
||||
- finalizar, arquivar, excluir ou registrar pagamento de consolidação;
|
||||
- criar, editar ou excluir usuários, perfis, contatos, grupos ou eventos;
|
||||
- qualquer envio de WhatsApp/notificação.
|
||||
- Formulários só podem ser preenchidos nos casos em que o roteiro mandar
|
||||
explicitamente (login e campos de busca).
|
||||
2. **Ambiente**: `https://teste.reemtransportes.com.br` (nunca o domínio de
|
||||
produção).
|
||||
3. **Avisos do ambiente de teste** (não são falhas):
|
||||
- Não há pagamentos registrados (`pago_em` vazio) — gráficos e tabelas de
|
||||
pagamento vazios são o esperado;
|
||||
- O deploy é manual: o site pode estar atrás do código do repositório. Se um
|
||||
caso falhar por algo que parece "código novo que não chegou lá", registre
|
||||
como `DEPLOY?` em vez de `FALHOU`.
|
||||
4. Screenshots de evidência vão para o diretório de scratchpad da sessão.
|
||||
|
||||
## Credenciais
|
||||
|
||||
- **Admin (web)**: e-mail `admin@reem.com`, senha `Reem@2026!` — em
|
||||
`https://teste.reemtransportes.com.br/auth/login`, aba "E-mail".
|
||||
- **Motorista**: aba "PIN Motorista" da mesma tela (PIN de 4 dígitos; se nenhum
|
||||
PIN de teste for fornecido na tarefa, marque o caso 8 como `PULADO`).
|
||||
|
||||
## Teste 0 — transversal (rodar em TODA página visitada)
|
||||
|
||||
Depois de abrir cada página do roteiro, sempre rode:
|
||||
|
||||
```bash
|
||||
agent-browser errors # deve vir vazio
|
||||
agent-browser network requests | grep -E " (4[0-9]{2}|5[0-9]{2})$" # deve vir vazio
|
||||
```
|
||||
|
||||
- Qualquer erro de console JS ⇒ FALHOU (anote a mensagem).
|
||||
- Qualquer request com status ≥ 400 ⇒ FALHOU (anote a URL — um asset
|
||||
`*_controller-*.js` com 404 significa Stimulus quebrado na página inteira; foi
|
||||
exatamente assim que o bug do preview do romaneio passou despercebido).
|
||||
- Exceção: chamadas para domínios de terceiros (cloudflareinsights etc.) com
|
||||
falha não reprovam o caso; registre como observação.
|
||||
|
||||
## Roteiro
|
||||
|
||||
### Caso 1 — Login por e-mail
|
||||
|
||||
```bash
|
||||
agent-browser open https://teste.reemtransportes.com.br/auth/login
|
||||
agent-browser snapshot -i # localizar refs de E-mail, Senha e Entrar
|
||||
agent-browser fill @eX "admin@reem.com"
|
||||
agent-browser fill @eY "Reem@2026!"
|
||||
agent-browser press Enter
|
||||
agent-browser wait --load networkidle
|
||||
agent-browser get url
|
||||
```
|
||||
|
||||
**PASSOU se**: a URL final é `/dashboard` (ou a home do perfil) e o Teste 0 passa.
|
||||
Obs.: use `press Enter` — o clique no botão às vezes não navega no primeiro clique.
|
||||
|
||||
### Caso 2 — Dashboards
|
||||
|
||||
```bash
|
||||
agent-browser open https://teste.reemtransportes.com.br/dashboard
|
||||
agent-browser eval "document.querySelectorAll('canvas').length" # gráficos Chart.js
|
||||
agent-browser eval "document.documentElement.scrollWidth <= window.innerWidth" # sem overflow horizontal
|
||||
agent-browser screenshot dashboard.png
|
||||
agent-browser open https://teste.reemtransportes.com.br/dashboard/operacoes
|
||||
# repetir os três comandos acima (operacoes.png)
|
||||
```
|
||||
|
||||
**PASSOU se**: as duas páginas carregam, há pelo menos 1 `canvas` em cada, sem
|
||||
overflow horizontal, Teste 0 limpo.
|
||||
|
||||
**Versão mobile** (obrigatória no dashboard):
|
||||
|
||||
```bash
|
||||
agent-browser set device "iPhone 16"
|
||||
agent-browser open https://teste.reemtransportes.com.br/dashboard
|
||||
agent-browser eval "document.documentElement.scrollWidth <= window.innerWidth"
|
||||
agent-browser screenshot dashboard-mobile.png
|
||||
agent-browser set viewport 1280 800 # voltar ao desktop
|
||||
```
|
||||
|
||||
**PASSOU se**: sem scroll horizontal no mobile (regra do projeto: nada de tabela
|
||||
que exija zoom).
|
||||
|
||||
### Caso 3 — Consolidações (abas e filtros)
|
||||
|
||||
```bash
|
||||
agent-browser open "https://teste.reemtransportes.com.br/consolidacoes?visao=lista"
|
||||
agent-browser snapshot -i | head -40
|
||||
agent-browser open "https://teste.reemtransportes.com.br/consolidacoes?visao=motoristas"
|
||||
agent-browser get url
|
||||
```
|
||||
|
||||
**PASSOU se**: as duas visões abrem sem erro; ao trocar de visão os filtros da URL
|
||||
se mantêm (as visões são abas da MESMA tela, não telas separadas); Teste 0 limpo.
|
||||
|
||||
### Caso 4 — Romaneios (inclui o preview)
|
||||
|
||||
```bash
|
||||
agent-browser open https://teste.reemtransportes.com.br/admin/romaneios
|
||||
agent-browser snapshot -i | head -30 # lista de romaneios
|
||||
# abrir o primeiro romaneio da lista (link do item):
|
||||
agent-browser click @eX
|
||||
agent-browser wait --load networkidle
|
||||
```
|
||||
|
||||
Na tela do romaneio:
|
||||
|
||||
```bash
|
||||
# 4a. O modal de prévia NÃO pode estar visível no carregamento:
|
||||
agent-browser eval "const o=document.querySelector('[data-romaneio-target=overlay]'); o?getComputedStyle(o).display:'sem overlay'"
|
||||
# esperado: "none"
|
||||
|
||||
# 4b. Abrir a prévia:
|
||||
agent-browser snapshot -i | grep -i "prévia" # achar o botão "Ver prévia do PDF"
|
||||
agent-browser click @eY
|
||||
agent-browser eval "const o=document.querySelector('[data-romaneio-target=overlay]'); getComputedStyle(o).display + ' src:' + (document.querySelector('iframe[data-romaneio-target=preview]')?.src||'')"
|
||||
# esperado: "flex src:https://.../pdf?veiculo=..."
|
||||
|
||||
# 4c. Fechar com Esc:
|
||||
agent-browser press Escape
|
||||
agent-browser eval "getComputedStyle(document.querySelector('[data-romaneio-target=overlay]')).display"
|
||||
# esperado: "none"
|
||||
|
||||
# 4d. PDF responde:
|
||||
agent-browser eval "fetch(document.querySelector('a[href*=pdf]').href).then(r=>r.status)"
|
||||
# esperado: 200
|
||||
```
|
||||
|
||||
**PASSOU se**: 4a="none", 4b="flex" com src preenchido, 4c="none", 4d=200,
|
||||
Teste 0 limpo. **NÃO** clicar em "Reimportar plano" (tem confirmação).
|
||||
|
||||
### Caso 5 — Planilha SimpliRoute
|
||||
|
||||
```bash
|
||||
agent-browser open https://teste.reemtransportes.com.br/admin/planilha_simpli_route
|
||||
agent-browser snapshot -i | head -20
|
||||
```
|
||||
|
||||
**PASSOU se**: a tela abre com a lista de operações disponíveis, Teste 0 limpo.
|
||||
(Não é preciso baixar o arquivo.)
|
||||
|
||||
### Caso 6 — Telas de admin
|
||||
|
||||
Abrir cada URL e rodar o Teste 0:
|
||||
|
||||
```
|
||||
/admin/usuarios
|
||||
/admin/perfis
|
||||
/admin/configuracoes
|
||||
/admin/auditoria_logs
|
||||
/admin/edicao_lancamento
|
||||
```
|
||||
|
||||
**PASSOU se**: todas abrem com conteúdo (título + tabela/cards), sem erro.
|
||||
**NÃO** editar nada nessas telas.
|
||||
|
||||
### Caso 7 — Notificações
|
||||
|
||||
Abrir cada URL e rodar o Teste 0:
|
||||
|
||||
```
|
||||
/admin/contatos
|
||||
/admin/grupos
|
||||
/admin/eventos
|
||||
/admin/envios
|
||||
```
|
||||
|
||||
**PASSOU se**: todas abrem, sem erro. **NÃO** disparar envio nem mexer no
|
||||
WhatsApp/sessão.
|
||||
|
||||
### Caso 8 — Login PIN do motorista (mobile)
|
||||
|
||||
Somente se um PIN de teste foi fornecido na tarefa; senão marcar `PULADO`.
|
||||
|
||||
```bash
|
||||
agent-browser set device "iPhone 16"
|
||||
agent-browser open https://teste.reemtransportes.com.br/auth/login
|
||||
# clicar na aba "PIN Motorista", digitar o PIN, entrar
|
||||
```
|
||||
|
||||
**PASSOU se**: cai no dashboard do motorista, valores legíveis sem zoom,
|
||||
Teste 0 limpo. Ao final: `agent-browser set viewport 1280 800`.
|
||||
|
||||
## Relatório final (obrigatório)
|
||||
|
||||
Terminar a execução com uma tabela e a lista de falhas:
|
||||
|
||||
| Caso | Resultado | Evidência |
|
||||
|------|-----------|-----------|
|
||||
| 0 (por página) | PASSOU/FALHOU | página + erro |
|
||||
| 1 Login | PASSOU/FALHOU/DEPLOY?/PULADO | screenshot |
|
||||
| 2 Dashboards | … | … |
|
||||
| 3 Consolidações | … | … |
|
||||
| 4 Romaneios/preview | … | … |
|
||||
| 5 Planilha | … | … |
|
||||
| 6 Admin | … | … |
|
||||
| 7 Notificações | … | … |
|
||||
| 8 PIN motorista | … | … |
|
||||
|
||||
Depois da tabela, listar **somente as falhas**, cada uma com: URL, o que era
|
||||
esperado, o que aconteceu (mensagem de erro/console) e o caminho do screenshot.
|
||||
Se tudo passou, dizer isso em uma linha. Encerrar com `agent-browser close`.
|
||||
Reference in New Issue
Block a user