@diegosouzacdv/jev-browser-mcp 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +385 -138
- package/config/ui-testing.json +12 -4
- package/docs/jev-browser-mcp.md +385 -138
- package/mcp_servers/jev-browser-npm/src/accessibility.mjs +18 -9
- package/mcp_servers/jev-browser-npm/src/config.mjs +55 -19
- package/mcp_servers/jev-browser-npm/src/flow.mjs +1610 -339
- package/mcp_servers/jev-browser-npm/src/server.mjs +250 -49
- package/package.json +1 -1
package/docs/jev-browser-mcp.md
CHANGED
|
@@ -17,7 +17,7 @@ versão em produção, use o número explícito no argumento do pacote:
|
|
|
17
17
|
"mcpServers": {
|
|
18
18
|
"jev-browser": {
|
|
19
19
|
"command": "npx",
|
|
20
|
-
"args": ["--yes", "@diegosouzacdv/jev-browser-mcp@0.
|
|
20
|
+
"args": ["--yes", "@diegosouzacdv/jev-browser-mcp@0.7.0"],
|
|
21
21
|
"env": {
|
|
22
22
|
"OPENROUTER_API_KEY": "${OPENROUTER_API_KEY}",
|
|
23
23
|
"JEV_BROWSER_MODE": "computer"
|
|
@@ -32,7 +32,7 @@ um secret manager ou pelo ambiente do processo; não grave a chave no arquivo
|
|
|
32
32
|
de configuração. Para instalar no projeto Node do próprio harness:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
|
-
npm install @diegosouzacdv/jev-browser-mcp@0.
|
|
35
|
+
npm install @diegosouzacdv/jev-browser-mcp@0.7.0
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Se o harness executa o MCP repetidamente nesta máquina, instale uma versão
|
|
@@ -40,7 +40,7 @@ fixa globalmente para evitar a resolução e o download feitos pelo `npx` em cad
|
|
|
40
40
|
inicialização:
|
|
41
41
|
|
|
42
42
|
```sh
|
|
43
|
-
npm install --global @diegosouzacdv/jev-browser-mcp@0.
|
|
43
|
+
npm install --global @diegosouzacdv/jev-browser-mcp@0.7.0
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Depois configure o servidor MCP com `command: "jev-browser-mcp"` e `args: []`.
|
|
@@ -49,14 +49,23 @@ Para atualizar, rode `npm install --global
|
|
|
49
49
|
|
|
50
50
|
O padrão `computer` exige Chrome ou Edge instalado. Se optar por `harness`,
|
|
51
51
|
configure `JEV_BROWSER_MODE=harness` antes de instalar o navegador gerenciado
|
|
52
|
-
pelo Playwright com `npx --yes @diegosouzacdv/jev-browser-mcp@0.
|
|
53
|
-
|
|
54
|
-
O padrão é `computer`: o pacote abre o Chrome/Edge instalado e usa um perfil
|
|
55
|
-
persistente exclusivo em `browser.computer_user_data_dir`.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
pelo Playwright com `npx --yes @diegosouzacdv/jev-browser-mcp@0.7.0 --install-browser`.
|
|
53
|
+
|
|
54
|
+
O padrão é `computer`: o pacote abre o Chrome/Edge instalado e usa um perfil
|
|
55
|
+
persistente exclusivo por processo MCP em `browser.computer_user_data_dir`. O
|
|
56
|
+
template aceita `{browser}` e `{session}`; por padrão, `{session}` é `pid-<PID>`.
|
|
57
|
+
Use um `JEV_BROWSER_SESSION_ID` único por instância para manter um nome estável
|
|
58
|
+
entre reinicializações. Um
|
|
59
|
+
`JEV_BROWSER_PROFILE` explícito também recebe o sufixo da sessão, a menos que o
|
|
60
|
+
caminho contenha `{session}`. Assim, processos MCP independentes não disputam o
|
|
61
|
+
mesmo perfil. Clientes conectados ao mesmo processo MCP compartilham a sessão;
|
|
62
|
+
para isolamento entre harnesses, execute uma instância por sessão. No modo
|
|
63
|
+
`harness`, a instalação baixa uma vez o Chrome/Edge que o Playwright controlará.
|
|
64
|
+
Personalize as escolhas com `JEV_BROWSER_MODE`, `JEV_BROWSER_CHANNEL` e
|
|
65
|
+
`JEV_BROWSER_PROFILE`. Sem um ID estável, o perfil é específico do processo e
|
|
66
|
+
uma reinicialização começa outra sessão. O browser permanece aquecido enquanto
|
|
67
|
+
o processo MCP estiver ativo e fecha quando o harness encerra o processo.
|
|
68
|
+
`JEV_PROVIDER_URL`
|
|
60
69
|
e `JEV_MODEL` podem substituir os valores centrais; a credencial continua no
|
|
61
70
|
nome de variável declarado em `jev.credential_env`.
|
|
62
71
|
|
|
@@ -76,8 +85,12 @@ publicada.
|
|
|
76
85
|
|
|
77
86
|
### Contrato do pacote
|
|
78
87
|
|
|
79
|
-
O executável oferece `browser_health`, `choose_next_action`
|
|
80
|
-
sessão do browser por processo e reutiliza
|
|
88
|
+
O executável oferece `browser_health`, `describe_actions`, `choose_next_action`
|
|
89
|
+
e `run_browser_flow`, mantém uma sessão do browser por processo e reutiliza
|
|
90
|
+
essa sessão entre chamadas. `browser_health` informa versão, sessão e
|
|
91
|
+
capacidades; `describe_actions` publica o schema atual das ações, opções,
|
|
92
|
+
aliases e placeholders. Consulte essas ferramentas antes de construir um plano
|
|
93
|
+
para evitar nomes de campos desatualizados. O plano
|
|
81
94
|
passado ao Jev continua declarativo: clique, preenchimento, seleção nativa,
|
|
82
95
|
hover, espera, teclas aprovadas, asserções por elemento, upload restrito a uma
|
|
83
96
|
raiz local configurada e reações idempotentes a um comentário único. Também
|
|
@@ -107,11 +120,22 @@ a página inicial, captura o snapshot acessível e pede ao Jev que escolha um
|
|
|
107
120
|
plano. Em seguida, executa o plano inteiro na mesma sessão e confere o
|
|
108
121
|
resultado esperado na tela.
|
|
109
122
|
|
|
110
|
-
Cada plano pode usar:
|
|
111
|
-
|
|
112
|
-
- `
|
|
113
|
-
|
|
114
|
-
`
|
|
123
|
+
Cada plano pode usar:
|
|
124
|
+
|
|
125
|
+
- `navigate` para mudar de página no meio do fluxo. Com a continuidade ligada,
|
|
126
|
+
um `initial_url` de mesma origem diferente da URL ativa produz erro claro; use
|
|
127
|
+
`navigate` ou `continue_from_current_page: false` para escolher o destino;
|
|
128
|
+
- `click`, `check`, `uncheck`, `type`, `clear`, `hover`, `select_option`,
|
|
129
|
+
`press` e `assert_*` aceitam papel/nome acessível ou localizadores como
|
|
130
|
+
`label`, `placeholder`, `title`, `text`, `test_id` e `selector`;
|
|
131
|
+
- `screenshot` e `clear_storage` atuam na página/contexto atual; `upload_file`
|
|
132
|
+
recebe o arquivo e o alvo de upload. Os limites e formatos estão descritos nas
|
|
133
|
+
seções de evidências e upload;
|
|
134
|
+
- `navigate_menu` para percorrer uma sequência de rótulos de menu; veja a seção
|
|
135
|
+
de navegação de menus para o formato e as opções;
|
|
136
|
+
- `name_match: "exact" | "contains" | "regex"` para controlar a comparação do
|
|
137
|
+
nome acessível; regex rejeita construções com backtracking excessivo. O papel
|
|
138
|
+
`switch` funciona em cliques, verificações e asserções;
|
|
115
139
|
- `near: {"text":"..."}` para localizar o controle logo depois de um texto,
|
|
116
140
|
`within: {"row_containing":"..."}` para limitar por trecho e
|
|
117
141
|
`within: {"row_containing_exact":"..."}` para exigir um elemento com o
|
|
@@ -125,28 +149,64 @@ Cada plano pode usar:
|
|
|
125
149
|
espaços/glyphs de uso privado, como ícones Font Awesome; controles
|
|
126
150
|
desabilitados não aparecem no diagnóstico, mas continuam contando para que o
|
|
127
151
|
índice aponte ao controle correto;
|
|
128
|
-
- `selector` com CSS ou XPath como último recurso. O MCP identifica essa escolha
|
|
129
|
-
em `warnings`; não é permitido enviar JavaScript nem coordenadas;
|
|
152
|
+
- `selector` com CSS ou XPath como último recurso. O MCP identifica essa escolha
|
|
153
|
+
em `warnings`; não é permitido enviar JavaScript nem coordenadas;
|
|
154
|
+
- quando `click` falha porque o alvo está fora da viewport ou não está visível,
|
|
155
|
+
o MCP tenta rolar o alvo até a tela; se isso não bastar, tenta focar o controle
|
|
156
|
+
e enviar `Enter`, sem repetir cegamente o clique;
|
|
130
157
|
- `timeout_seconds` opcional em cada etapa, limitado pela configuração central;
|
|
131
|
-
- `type` com `mode: "keys"` para digitar sequencialmente em campos com máscara,
|
|
132
|
-
`blur: true` para desfocar o campo e `sensitive: false` para permitir que o
|
|
133
|
-
valor apareça nas evidências.
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
- `type` com `mode: "keys"` para digitar sequencialmente em campos com máscara,
|
|
159
|
+
`blur: true` para desfocar o campo e `sensitive: false` para permitir que o
|
|
160
|
+
valor apareça nas evidências. `text_env` lê o valor sensível de uma variável
|
|
161
|
+
de ambiente do processo MCP, sem colocá-lo no plano. Nesse modo, `\n` envia
|
|
162
|
+
Enter e `\t` envia Tab;
|
|
163
|
+
- `wait_for_text`, `wait_for_value`, `wait_for_enabled` e `wait_for_condition`
|
|
164
|
+
(`url`, `network_idle`, `hidden` ou `angular_idle`). `wait` recebe
|
|
136
165
|
`ms` para uma pausa curta e limitada. `angular_idle` aguarda requisições
|
|
137
166
|
`$http` e digest do AngularJS. `wait_for_text` aceita `fail_on: {"role":"alert"}` para
|
|
138
167
|
interromper a espera assim que um alerta visível aparecer e incluir seu texto
|
|
139
168
|
no erro. Se o alerta contiver o texto esperado, a etapa passa; caso contrário,
|
|
140
|
-
o alerta interrompe a espera. `
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
169
|
+
o alerta interrompe a espera. `url` aguarda a URL conter `url_contains`.
|
|
170
|
+
`network_idle` aceita esse filtro e aguarda uma janela de silêncio usando
|
|
171
|
+
`ready_stable_ms`; WebSocket, EventSource e polling não relacionado não
|
|
172
|
+
bloqueiam a espera. Se não surgir requisição correspondente, o passo conclui
|
|
173
|
+
após a janela de silêncio;
|
|
174
|
+
- `assert_network` valida resposta HTTP observada (inclusive sucesso 2xx ou erro
|
|
175
|
+
esperado); `wait_for_request` aguarda uma resposta usando `*` como curinga na
|
|
176
|
+
URL e filtros opcionais de método/status; `assert_ws` confere texto, pares
|
|
177
|
+
JSON esperados ou código de fechamento de WebSocket;
|
|
178
|
+
- `evaluate` lê somente caminhos de propriedades como `navigator.mediaDevices`,
|
|
179
|
+
`document.readyState` ou `location.pathname`. Não aceita código, chamadas de
|
|
180
|
+
função, armazenamento local ou propriedades de credenciais. Strings e números
|
|
181
|
+
voltam diretamente; objetos e arrays retornam somente tipo, chaves e tamanho,
|
|
182
|
+
sem despejar seus valores;
|
|
183
|
+
- `new_tab`, `switch_tab` e `new_context` abrem/selecionam abas e criam contexto
|
|
184
|
+
separado dentro do fluxo; `target_page: "popup"` mantém popups abertos para
|
|
185
|
+
passos posteriores;
|
|
186
|
+
- `if_visible` em um clique torna a ação condicional e
|
|
187
|
+
`when: {"visible":"..."}` em cada plano limita as opções do Jev às que
|
|
188
|
+
correspondem à tela atual;
|
|
189
|
+
- `fill` é alias de `type`, `press_key` de `press`, `duration_ms` de `wait.ms` e
|
|
190
|
+
`value` de campos de texto. `timeout_ms` funciona por etapa. Placeholders usam
|
|
191
|
+
`{nome}`; referências desconhecidas e `{{nome}}` são recusadas antes da
|
|
192
|
+
navegação;
|
|
193
|
+
- `press` (o alias legado `press_key` também é aceito) com `PageDown`, `PageUp`,
|
|
194
|
+
`Home`, `End`, setas, `Enter`, `Escape`, `Tab`, `Shift+Tab`, `Space`,
|
|
195
|
+
`Backspace` ou `Delete`. `clear` limpa um campo sem exigir texto. Sem alvo,
|
|
196
|
+
`press` envia a tecla ao elemento focado; com alvo, usa o localizador informado;
|
|
197
|
+
- `screenshot` grava uma imagem local; `full_page: true` inclui a página inteira.
|
|
198
|
+
Também é possível pedir uma captura após qualquer etapa com `screenshot: true`;
|
|
199
|
+
- `clear_storage` limpa cookies, local/session storage, IndexedDB, Cache Storage
|
|
200
|
+
e service workers do contexto atual. Como opção de fluxo,
|
|
201
|
+
`options.clear_storage: true` também recarrega a página antes do snapshot inicial;
|
|
145
202
|
- `assert_text`, `assert_value`, `assert_visible`, `assert_hidden` e
|
|
146
203
|
`assert_enabled`; `assert_text`
|
|
147
204
|
pode receber apenas `role` quando a região, como `alert`, não tem nome acessível;
|
|
148
|
-
- `upload_file` para input rotulado, botão que abre o seletor de arquivo ou
|
|
149
|
-
dropzone;
|
|
205
|
+
- `upload_file` para input rotulado, botão que abre o seletor de arquivo ou
|
|
206
|
+
dropzone;
|
|
207
|
+
- `target_page: "popup"` para continuar no popup aberto com `expect_popup: true`;
|
|
208
|
+
locators semânticos também atravessam open Shadow DOM. Shadow DOM fechado não
|
|
209
|
+
é acessível ao Playwright;
|
|
150
210
|
- `audit_accessibility` com axe-core para WCAG 2.1 A/AA;
|
|
151
211
|
- `like_comment` e `unlike_comment`, que localizam uma linha pelo autor e texto,
|
|
152
212
|
não repetem uma reação já no estado pedido e distinguem `Curtir` de
|
|
@@ -154,19 +214,25 @@ Cada plano pode usar:
|
|
|
154
214
|
|
|
155
215
|
As proteções e evidências por etapa usam estes campos:
|
|
156
216
|
|
|
157
|
-
- `confirm_dialog` recebe `expected_text` e `button`. Em diálogos HTML, o MCP
|
|
158
|
-
confere o texto antes de localizar e clicar no botão. Também trata diálogos
|
|
159
|
-
nativos `alert`/`confirm`: precisa haver uma etapa `confirm_dialog` logo após
|
|
160
|
-
o clique que os abre, o texto deve corresponder e um diálogo inesperado é
|
|
161
|
-
fechado sem aceitar;
|
|
162
|
-
- `
|
|
217
|
+
- `confirm_dialog` recebe `expected_text` e `button`. Em diálogos HTML, o MCP
|
|
218
|
+
confere o texto antes de localizar e clicar no botão. Também trata diálogos
|
|
219
|
+
nativos `alert`/`confirm`: precisa haver uma etapa `confirm_dialog` logo após
|
|
220
|
+
o clique que os abre, o texto deve corresponder e um diálogo inesperado é
|
|
221
|
+
fechado sem aceitar;
|
|
222
|
+
- `confirm_modal` combina o clique no gatilho, a conferência do texto e o clique
|
|
223
|
+
afirmativo em uma única etapa protegida. Também aceita os aliases
|
|
224
|
+
`trigger`/`confirm`, por exemplo
|
|
225
|
+
`{"action":"confirm_modal","trigger":"Salvar","expected_text":"Confirma a alteração?","confirm":"OK"}`;
|
|
226
|
+
- `mutating: true` marca etapas que gravam dados ou disparam efeitos externos.
|
|
163
227
|
O MCP também classifica botões conhecidos como `Salvar`, `Emitir`, `Cancelar`
|
|
164
228
|
ou `Sim` pelo nome e pelo controle resolvido, inclusive quando o plano usa um
|
|
165
229
|
seletor CSS. `options.dry_run: true` executa até a primeira etapa mutável e
|
|
166
230
|
para antes dela; retorna `dry_run_stopped_before_step` e um
|
|
167
|
-
`confirmation_token` temporário, de uso único e vinculado ao fluxo e à página.
|
|
168
|
-
Reenvie a mesma chamada com `options.confirmation_token` para
|
|
169
|
-
|
|
231
|
+
`confirmation_token` temporário, de uso único e vinculado ao fluxo e à página.
|
|
232
|
+
Reenvie a mesma chamada com `options.confirmation_token` para retomar no passo
|
|
233
|
+
pausado sem repetir os passos anteriores; o MCP confere a rota e o alvo da
|
|
234
|
+
mutação antes de executá-la. Ele pausa novamente antes de cada outra etapa
|
|
235
|
+
mutável. Sem `dry_run`,
|
|
170
236
|
o primeiro pedido de ação mutável também retorna `status: "confirmation_required"`
|
|
171
237
|
e token; nenhuma etapa mutável roda sem essa autorização. O token expira após
|
|
172
238
|
dez minutos por padrão;
|
|
@@ -202,20 +268,37 @@ incluindo respostas 2xx ou erros esperados como 404. Exemplo:
|
|
|
202
268
|
}
|
|
203
269
|
```
|
|
204
270
|
|
|
205
|
-
Essa asserção aparece na evidência como `response_status`, separado do campo
|
|
206
|
-
`status` da etapa (`passed` ou `failed`). `message_contains` lê somente resposta
|
|
207
|
-
da mesma origem e respeita o limite configurado para captura de corpos.
|
|
271
|
+
Essa asserção aparece na evidência como `response_status`, separado do campo
|
|
272
|
+
`status` da etapa (`passed` ou `failed`). `message_contains` lê somente resposta
|
|
273
|
+
da mesma origem e respeita o limite configurado para captura de corpos.
|
|
274
|
+
`assert_network`, `wait_for_request` e `expected_outcome.request` consultam o
|
|
275
|
+
histórico limitado de respostas depois do marcador da etapa ou do início do
|
|
276
|
+
fluxo. O limite vem de `jev_browser_mcp.browser.max_network_history_events` e
|
|
277
|
+
está em 4096 eventos nesta configuração; assim, chamadas anteriores ao marcador
|
|
278
|
+
não satisfazem a asserção.
|
|
279
|
+
|
|
280
|
+
Para aguardar a API antes de abrir a interface, passe
|
|
281
|
+
`options.wait_for_http: {"url":"http://localhost:8000/health","timeout_ms":30000}`.
|
|
282
|
+
Também aceita apenas a URL como string ou `{ "url": "...", "timeout_seconds": 30 }`.
|
|
283
|
+
O probe faz GET e tenta novamente até o limite; qualquer resposta abaixo de 500
|
|
284
|
+
indica que o servidor respondeu (inclusive 4xx), enquanto 5xx e erros de conexão
|
|
285
|
+
são repetidos. Ao expirar, `reason` inclui a última causa. Por segurança, a URL
|
|
286
|
+
precisa ser loopback ou usar o mesmo host de `initial_url`; isso permite, por
|
|
287
|
+
exemplo, Vite em `localhost:5173` e API em `localhost:8000`.
|
|
208
288
|
|
|
209
289
|
Exemplo de parâmetro e extração: passe `params: {"pedido":"1528721"}`, filtre
|
|
210
290
|
com `within: {"row_containing_exact":"{pedido}"}`, e use uma etapa
|
|
211
291
|
`{"action":"extract","role":"cell","name":"{pedido}","within":{"row_containing_exact":"{pedido}"},"as":"documento"}`.
|
|
212
292
|
A etapa seguinte pode localizar o mesmo documento com `name: "{documento}"`.
|
|
213
293
|
|
|
214
|
-
Em `wait_for_condition` com `condition: "hidden"`, use qualquer um desses
|
|
215
|
-
localizadores, `near` ou `within`;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
294
|
+
Em `wait_for_condition` com `condition: "hidden"`, use qualquer um desses
|
|
295
|
+
localizadores, `near` ou `within`; para esperar texto desaparecer, use
|
|
296
|
+
`{"condition":"hidden","text":"Carregando..."}`. Para esperar que texto suma
|
|
297
|
+
antes do primeiro passo, use `options.ready: {"hidden_text":"Carregando..."}`.
|
|
298
|
+
Para aguardar o fim de uma chamada específica, use `condition: "network_idle"` com
|
|
299
|
+
`url_contains`. O filtro considera somente a atividade correspondente e termina
|
|
300
|
+
após a janela configurada sem atividade; também termina caso nenhuma requisição
|
|
301
|
+
correspondente apareça. Para validar status e corpo, prefira `assert_network`.
|
|
219
302
|
|
|
220
303
|
Quando vários controles têm o mesmo papel e nome, `within` limita a busca a um
|
|
221
304
|
container acessível único, como uma linha, card ou diálogo. `index` escolhe uma
|
|
@@ -223,7 +306,7 @@ ocorrência zero-based dentro desse escopo; sem `index`, o MCP exige exatamente
|
|
|
223
306
|
um alvo. Para uma página com rótulo `for` quebrado, `label` também procura o
|
|
224
307
|
controle próximo ao texto visível do rótulo.
|
|
225
308
|
|
|
226
|
-
`within` pode combinar um container e uma linha. Use, por exemplo,
|
|
309
|
+
`within` pode combinar um container e uma linha. Use, por exemplo,
|
|
227
310
|
`{"role":"cell","name":"Documento A","within":{"role":"table","row_containing_word":"1528721"}}`.
|
|
228
311
|
`row_containing_word` usa limites de palavra para não confundir `1528721` com
|
|
229
312
|
`15287210`; `row_containing_exact` continua disponível para texto de célula
|
|
@@ -258,13 +341,14 @@ Exemplos para controles legados sem nome acessível:
|
|
|
258
341
|
{"action":"click","selector":"#save-document"}
|
|
259
342
|
```
|
|
260
343
|
|
|
261
|
-
|
|
262
|
-
`
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
344
|
+
Por padrão, controles sem nome não são devolvidos em listas separadas. Defina
|
|
345
|
+
`options.include_unnamed_controls: true` para receber
|
|
346
|
+
`unnamed_controls_initial` e `unnamed_controls_final`, cada uma com papel,
|
|
347
|
+
índice Playwright por papel, rótulo mais próximo e um trecho HTML sanitizado.
|
|
348
|
+
Nomes vazios ou compostos apenas por espaços e glyphs da área Unicode de uso
|
|
349
|
+
privado (como ícones Font Awesome) entram nessa lista e podem ser selecionados
|
|
350
|
+
com `name: ""` e o mesmo índice. O alias redundante `unnamed_controls` foi
|
|
351
|
+
removido. O placeholder conta como nome acessível.
|
|
268
352
|
O snapshot também resume campos de formulário com `id`, `name`, valor, estado
|
|
269
353
|
desabilitado, rótulo e índice zero-based entre campos de mesmo nome. Valores
|
|
270
354
|
sensíveis, como senha, token e cartão, são ocultados. `snapshot_include_hidden`
|
|
@@ -275,10 +359,14 @@ Em uma etapa `type`, `text` contém o valor a digitar; use `target_text` para
|
|
|
275
359
|
localizar pelo texto visível próximo ao campo. Esse localizador exige `role`
|
|
276
360
|
`textbox`, `searchbox` ou `combobox`.
|
|
277
361
|
|
|
278
|
-
Por padrão, o MCP executa todos os passos antes de avaliar
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
362
|
+
Por padrão, o MCP executa todos os passos antes de avaliar os critérios.
|
|
363
|
+
`expected_outcome` aceita texto descritivo ou uma asserção estruturada, por
|
|
364
|
+
exemplo `{"text":"Tecnologia atualizada com sucesso."}` ou
|
|
365
|
+
`{"request":"PUT */api/tecnologia","status":200}`. A forma estruturada pode
|
|
366
|
+
incluir `message_contains` e reprova se a resposta correspondente não for
|
|
367
|
+
observada. Valores dentro de campos não contam como texto visível.
|
|
368
|
+
`stop_on_expected: true` habilita parada antecipada quando o texto esperado
|
|
369
|
+
aparece fora dos campos; mantenha `false` para fluxos com várias etapas.
|
|
282
370
|
|
|
283
371
|
Os erros de validação apontam o campo inválido e os campos aceitos. Os limites
|
|
284
372
|
de `timeout_seconds` informam o máximo configurado, em vez de exigir tentativa
|
|
@@ -314,11 +402,13 @@ verificar:
|
|
|
314
402
|
{"action":"audit_accessibility","standard":"wcag2aa"}
|
|
315
403
|
```
|
|
316
404
|
|
|
317
|
-
O MCP usa `@axe-core/playwright` com as tags WCAG 2.0 e 2.1 A/AA. O retorno
|
|
318
|
-
resume as violações por regra, impacto e quantidade de nós, sem copiar HTML ou
|
|
319
|
-
trechos da página.
|
|
320
|
-
|
|
321
|
-
|
|
405
|
+
O MCP usa `@axe-core/playwright` com as tags WCAG 2.0 e 2.1 A/AA. O retorno
|
|
406
|
+
resume as violações por regra, impacto e quantidade de nós, sem copiar HTML ou
|
|
407
|
+
trechos da página. A etapa falha quando encontra violações no impacto definido
|
|
408
|
+
por `fail_on_impact`; o padrão é `minor`, e níveis abaixo do limite são relatados
|
|
409
|
+
sem bloquear o fluxo. A auditoria automática encontra problemas comuns, mas não
|
|
410
|
+
comprova conformidade WCAG completa; combine-a com revisão manual e testes com
|
|
411
|
+
usuários assistivos.
|
|
322
412
|
|
|
323
413
|
Para ações em iframe, acrescente `"frame": "payment-iframe"`; o valor precisa
|
|
324
414
|
corresponder ao atributo `name` ou `title` do iframe. O snapshot inclui o
|
|
@@ -411,27 +501,67 @@ validadores.
|
|
|
411
501
|
|
|
412
502
|
`browser.mode` aceita `harness` ou `computer`; o padrão é `computer`:
|
|
413
503
|
|
|
414
|
-
- `harness` usa Chrome headless e contexto isolado, adequado a execuções do
|
|
415
|
-
harness e CI
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
504
|
+
- `harness` usa Chrome headless e contexto isolado, adequado a execuções do
|
|
505
|
+
harness e CI. O processo MCP conserva browser, contexto e página entre
|
|
506
|
+
chamadas; cookies, local storage e estado da página permanecem enquanto o
|
|
507
|
+
processo estiver ativo. Encerre o processo para descartar o contexto isolado.
|
|
508
|
+
- `computer` abre o Chrome ou Edge instalado em modo visível e usa o diretório
|
|
509
|
+
persistente `browser.computer_user_data_dir`, separado por navegador e por
|
|
510
|
+
processo MCP. Não
|
|
511
|
+
reutiliza o perfil pessoal já aberto. Faça login uma vez nesse perfil; os
|
|
512
|
+
cookies permanecem nele entre chamadas.
|
|
513
|
+
|
|
514
|
+
`fresh_context: true` abre um contexto descartável, sem cookies nem storage do
|
|
515
|
+
perfil persistente; requer `initial_url` e fecha esse contexto ao terminar. Use
|
|
516
|
+
`clear_storage: true` para limpar cookies, local/session storage, IndexedDB,
|
|
517
|
+
Cache Storage e service workers antes de recarregar a página atual. Para salvar
|
|
518
|
+
e reutilizar o estado de autenticação de uma conta de teste, use um nome simples
|
|
519
|
+
em `storage_state`:
|
|
520
|
+
|
|
521
|
+
```json
|
|
522
|
+
{"options":{"storage_state":"aluno-a"}}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
O estado fica em `storage-state/<nome>.json` dentro da pasta de artefatos, com
|
|
526
|
+
permissões restritas no sistema operacional; não use uma conta real nem
|
|
527
|
+
compartilhe esse arquivo. `storage_state` não pode ser combinado com
|
|
528
|
+
`fresh_context` ou `clear_storage`.
|
|
529
|
+
|
|
530
|
+
`browser.max_flow_steps` limita os passos de cada plano candidato; os planos
|
|
531
|
+
não são somados. `browser.max_text_entry_chars` limita cada valor digitado. O
|
|
532
|
+
resultado contém `status`, o plano escolhido, as ações executadas, a última
|
|
533
|
+
captura acessível e se o texto descritivo esperado apareceu. `expected_outcome`
|
|
534
|
+
como string é descrição, não uma asserção: `expected_outcome_visible` é
|
|
535
|
+
informado separadamente, e um plano concluído pode passar mesmo se a frase não
|
|
536
|
+
estiver visível. Use `{ "text": "..." }` ou
|
|
537
|
+
`{ "request": "...", "status": 200 }` para exigir uma condição; as
|
|
538
|
+
verificações ficam em `expected_outcome_checks`, e uma condição não satisfeita
|
|
539
|
+
reprova o fluxo. As asserções `assert_*`, auditorias de acessibilidade e
|
|
540
|
+
downloads também aparecem em campos próprios do resultado.
|
|
541
|
+
|
|
542
|
+
Os status do fluxo incluem `passed`, `failed`, `incomplete`, `environment_error`,
|
|
543
|
+
`dry_run` e `confirmation_required`. O fluxo fica `passed` se não houve falha ou
|
|
544
|
+
pausa de mutação e o texto esperado apareceu, uma asserção/auditoria/download
|
|
545
|
+
passou ou todas as etapas do plano foram executadas. `incomplete` é devolvido
|
|
546
|
+
quando nenhuma dessas condições se aplica; confiança do Jev, sozinha, não
|
|
547
|
+
comprova o resultado. `environment_error` identifica falha de
|
|
548
|
+
navegação, autenticação ou sessão do browser; `navigation_error` contém o código
|
|
549
|
+
detectado, como `ERR_CONNECTION_REFUSED`, `AUTHENTICATION_REQUIRED` ou
|
|
550
|
+
`BROWSER_DISCONNECTED`, e `reason` orienta a recuperação. Se uma navegação falhar
|
|
551
|
+
e a chamada seguinte tentar reutilizar a página, o MCP informa que a navegação
|
|
552
|
+
anterior não carregou; reinicie a navegação com
|
|
553
|
+
`continue_from_current_page: false` (ou o alias `reuse_page: false`). Uma sessão
|
|
554
|
+
desconectada pode ser reaberta por `browser_health`; o fluxo só é repetido
|
|
555
|
+
automaticamente uma vez se nenhuma etapa mutável tiver sido executada.
|
|
556
|
+
|
|
557
|
+
`current_url` é devolvido para diagnóstico sem query string nem fragmento; IDs
|
|
558
|
+
longos no caminho também podem ser redigidos. `timings_ms.ready_ms` mede a espera
|
|
559
|
+
da SPA; `warnings` registra capturas vazias durante transições; e `failed_step`
|
|
560
|
+
identifica índice, ação, localizador, timeout e erro resumido quando uma etapa
|
|
561
|
+
falha. Cada etapa executada também registra a composição do localizador usado
|
|
562
|
+
e, quando disponível, `resolved_target` com tag, `id`, papel, nome acessível,
|
|
563
|
+
`title` casado e `href` sanitizado do elemento resolvido. Etapas `type` só
|
|
564
|
+
incluem o valor final do campo quando `sensitive: false`.
|
|
435
565
|
|
|
436
566
|
Com `capture_network_error_bodies: true`, respostas JSON de erro da mesma
|
|
437
567
|
origem são capturadas mesmo quando usam transferência chunked e não enviam
|
|
@@ -455,42 +585,70 @@ continua informada mesmo quando a lista é truncada.
|
|
|
455
585
|
O `run_browser_flow` aceita `options` com `fast_path`, `snapshot_scope`,
|
|
456
586
|
`block_trackers`, `block_fonts`, `local_only`, `busy_selectors`,
|
|
457
587
|
`auto_angular_idle`, `login_url_contains`, `login_text`, `capture_console_errors`,
|
|
458
|
-
`capture_network_errors`, `capture_network_error_bodies`, `ready_timeout_seconds`,
|
|
459
|
-
`ready_network_idle`, `ready_stable_ms`, `ready_text`, `continue_from_current_page`,
|
|
460
|
-
`reuse_page`, `step_timeout_seconds`, `max_flow_steps`, `return_snapshot`,
|
|
461
|
-
`screenshot_on_failure`, `
|
|
462
|
-
`
|
|
463
|
-
|
|
464
|
-
`
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
588
|
+
`capture_network_errors`, `capture_network_error_bodies`, `ready_timeout_seconds`,
|
|
589
|
+
`ready_network_idle`, `ready_stable_ms`, `ready_text`, `ready`, `continue_from_current_page`,
|
|
590
|
+
`reuse_page`, `reuse_page_match`, `step_timeout_seconds`, `max_flow_steps`, `return_snapshot`,
|
|
591
|
+
`screenshot_on_failure`, `screenshot_on_success`, `trace_on_failure`,
|
|
592
|
+
`trace_on_success`, `record_video`, `snapshot_include_hidden`, `include_unnamed_controls`, `stop_on_expected`,
|
|
593
|
+
`dry_run`, `confirmation_token`, `report_path`, `permissions`, `fake_media`,
|
|
594
|
+
`viewport`, `mobile`, `device_scale_factor`, `locale`, `timezone_id`,
|
|
595
|
+
`color_scheme`, `geolocation`, `console_levels`, `fresh_context`,
|
|
596
|
+
`clear_storage`, `storage_state`, `wait_for_http` e `allow_mutations`. Sem override,
|
|
597
|
+
os padrões são lidos de `jev_browser_mcp` em
|
|
598
|
+
`config/ui-testing.json`: um plano candidato pula a chamada Decisions;
|
|
599
|
+
captura de console e screenshot de falha ficam ligadas; trace, rede e bloqueio
|
|
600
|
+
de recursos ficam desligados; o plano roda até o fim e campos ocultos não são
|
|
601
|
+
acrescentados ao snapshot. `return_snapshot: "diff"` é o padrão, e as listas de
|
|
602
|
+
controles sem nome só aparecem com `include_unnamed_controls: true`. O browser
|
|
603
|
+
espera a SPA renderizar uma captura acessível estável na navegação inicial.
|
|
604
|
+
Depois, a continuidade fica ligada por
|
|
469
605
|
padrão: `continue_from_current_page: true` mantém a página e seu estado entre
|
|
470
606
|
chamadas na mesma origem, não repete `page.goto` e consulta um snapshot atual
|
|
471
607
|
sem esperar novamente por `load`/`networkidle`. As etapas continuam aguardando
|
|
472
608
|
seus próprios alvos e condições. `reuse_page` segue como alias legado; defina
|
|
473
609
|
`continue_from_current_page: false` para iniciar cada chamada em `initial_url`.
|
|
474
|
-
Se a página atual e `initial_url` tiverem origens diferentes, o MCP navega para
|
|
475
|
-
`initial_url`.
|
|
476
|
-
|
|
477
|
-
`
|
|
478
|
-
|
|
479
|
-
`
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
610
|
+
Se a página atual e `initial_url` tiverem origens diferentes, o MCP navega para
|
|
611
|
+
`initial_url`. URLs da mesma origem são comparadas após normalizar e ordenar a
|
|
612
|
+
query string. Se a rota normalizada diferir, o MCP pede uma etapa `navigate` ou
|
|
613
|
+
`continue_from_current_page: false`. `reuse_page_match: "path"` ignora a query;
|
|
614
|
+
um plano cuja primeira etapa seja `navigate` pode trocar a rota explicitamente.
|
|
615
|
+
`snapshot_scope` aceita `body`, `main` ou
|
|
616
|
+
`dialog`; se `main` não existir, o snapshot usa `body`.
|
|
617
|
+
|
|
618
|
+
`block_trackers: true` bloqueia analytics/trackers e os tipos de recurso
|
|
619
|
+
configurados, mas preserva `media` quando há permissão de microfone ou
|
|
620
|
+
`fake_media`. Fontes ficam habilitadas por padrão para preservar ícones e
|
|
621
|
+
glyphs; `block_fonts: true` bloqueia fontes separadamente. `busy_selectors`
|
|
622
|
+
complementa `aria-busy="true"` ao aguardar overlays; elementos ocultos ou fora
|
|
623
|
+
da tela com esse atributo não seguram a prontidão da página.
|
|
483
624
|
`auto_angular_idle` aguarda AngularJS depois de cliques e digitação quando a
|
|
484
625
|
página expõe o injector. `login_url_contains` e `login_text` substituem a
|
|
485
626
|
detecção padrão de autenticação. `local_only: true` recusa qualquer etapa que
|
|
486
|
-
precisaria chamar o provedor Jev; use exatamente um plano com `fast_path: true`.
|
|
487
|
-
`
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
`
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
`
|
|
627
|
+
precisaria chamar o provedor Jev; use exatamente um plano com `fast_path: true`.
|
|
628
|
+
`allow_mutations: true` pula a confirmação humana somente para URLs em
|
|
629
|
+
`localhost`, `127.0.0.1` ou `::1`; use esse modo apenas em ambientes locais
|
|
630
|
+
controlados.
|
|
631
|
+
`step_timeout_seconds` define o timeout padrão por etapa e cada etapa pode
|
|
632
|
+
substituí-lo com `timeout_seconds`. `max_flow_steps` reduz o limite por chamada,
|
|
633
|
+
sem superar o teto da configuração. `return_snapshot` aceita `diff`, `full` ou
|
|
634
|
+
`none`; `diff` retorna linhas acessíveis novas desde o snapshot inicial.
|
|
635
|
+
|
|
636
|
+
`options.ready` aguarda condições da aplicação antes do primeiro snapshot e da
|
|
637
|
+
seleção do plano. Aceita `"network_idle"`,
|
|
638
|
+
`{"hidden_text":"Aguarde."}` e `{"selector":"#cdTecnologia","has_value":true}`;
|
|
639
|
+
uma lista combina condições, e todas precisam passar. `has_value` aceita
|
|
640
|
+
`true` (valor não vazio), `false` (vazio) ou o valor textual exato.
|
|
641
|
+
`ready_text` também pode exigir uma frase no snapshot inicial;
|
|
642
|
+
`ready_network_idle: true` solicita uma espera best-effort por `networkidle`.
|
|
643
|
+
`ready_timeout_seconds` limita a espera de inicialização e `ready_stable_ms`
|
|
644
|
+
define a janela usada para considerar o snapshot estável.
|
|
645
|
+
|
|
646
|
+
`console_levels` aceita `log`, `info`, `debug`, `warn` e `error`. Com
|
|
647
|
+
`console_levels: ["log","warn","error"]` e `capture_network_errors`, o retorno
|
|
648
|
+
traz mensagens do console agrupadas por texto e nível (`console_messages` com
|
|
649
|
+
`count`), além de `console_errors` para compatibilidade. `network_failures`
|
|
650
|
+
contém eventos limitados em quantidade e tamanho. Mensagens idênticas do console
|
|
651
|
+
são agrupadas em uma entrada com `count`.
|
|
494
652
|
Respostas HTTP 4xx/5xx e requisições que falham são listadas; query strings,
|
|
495
653
|
fragmentos, valores de formulário e nomes de arquivo são removidos ou
|
|
496
654
|
sanitizados. `capture_network_error_bodies: true` lê somente respostas JSON
|
|
@@ -506,15 +664,59 @@ compartilhe os arquivos somente se o teste permitir.
|
|
|
506
664
|
|
|
507
665
|
Screenshots por etapa usam `screenshot: true` no próprio passo; o MCP os grava
|
|
508
666
|
depois que a ação termina. `options.report_path` pode apontar para `.md` ou
|
|
509
|
-
JUnit `.xml` dentro da raiz de artefatos. O relatório inclui a versão, tempos,
|
|
510
|
-
localizadores resolvidos, respostas verificadas por `assert_network`, falhas de
|
|
511
|
-
rede e caminhos dos screenshots, para anexar a um PR ou card.
|
|
667
|
+
JUnit `.xml` dentro da raiz de artefatos. O relatório inclui a versão, tempos,
|
|
668
|
+
localizadores resolvidos, respostas verificadas por `assert_network`, falhas de
|
|
669
|
+
rede e caminhos dos screenshots, para anexar a um PR ou card.
|
|
670
|
+
|
|
671
|
+
`screenshot_on_success` grava a captura final em fluxos aprovados;
|
|
672
|
+
`trace_on_success` salva trace também em sucesso e `record_video` grava vídeo
|
|
673
|
+
WebM. Fluxos que digitam texto sensível suprimem screenshots, traces e vídeos
|
|
674
|
+
para não registrar credenciais. `performance_metrics` inclui métricas do
|
|
675
|
+
navegador quando disponíveis. `jev_browser_mcp.browser.max_tool_response_bytes`
|
|
676
|
+
impõe um teto global de bytes na resposta JSON da ferramenta; se necessário,
|
|
677
|
+
evidências volumosas são reduzidas e marcadas com `output_truncated: true`.
|
|
678
|
+
|
|
679
|
+
Para testar microfone, conceda permissão no escopo da chamada:
|
|
680
|
+
|
|
681
|
+
```json
|
|
682
|
+
{
|
|
683
|
+
"options": {
|
|
684
|
+
"permissions": ["microphone"],
|
|
685
|
+
"fake_media": {"audio":"fixtures/resposta-aluno.wav"},
|
|
686
|
+
"block_trackers": true
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
`fake_media` aceita tanto o caminho WAV direto quanto o objeto
|
|
692
|
+
`{"audio":"caminho.wav"}`. Exige um WAV RIFF válido dentro de
|
|
693
|
+
`JEV_BROWSER_UPLOAD_ROOT` e respeita os mesmos limites de upload. Ao informar
|
|
694
|
+
`fake_media`, o MCP concede automaticamente a permissão `microphone`, adiciona
|
|
695
|
+
as opções de dispositivo falso do Chromium e usa o arquivo como entrada de
|
|
696
|
+
áudio. Sem esse arquivo, a
|
|
697
|
+
permissão de microfone usa o dispositivo autorizado pelo browser; no modo
|
|
698
|
+
`computer`, o sistema operacional ainda pode pedir acesso ao dispositivo.
|
|
699
|
+
|
|
700
|
+
As opções de emulação aceitam `viewport: {"width": 390, "height": 844}`,
|
|
701
|
+
`mobile: true`, `device_scale_factor`, `locale`, `timezone_id`,
|
|
702
|
+
`color_scheme: "dark"` e `geolocation: {"latitude": -23.55, "longitude": -46.63}`.
|
|
703
|
+
Informar geolocalização concede também a permissão `geolocation`.
|
|
704
|
+
|
|
705
|
+
`audit_accessibility` aceita `scope` com seletor CSS e `fail_on_impact` com
|
|
706
|
+
`minor`, `moderate`, `serious` ou `critical`. O padrão é `minor`; violações
|
|
707
|
+
abaixo do impacto escolhido continuam no relatório, mas não bloqueiam o passo.
|
|
708
|
+
`violations_count` e `blocking_violations_count` separam total e bloqueadoras.
|
|
709
|
+
|
|
710
|
+
Os cliques aguardam `DOMContentLoaded` quando acionam navegação completa e
|
|
711
|
+
tratam a destruição do contexto durante a troca de documento como navegação em
|
|
712
|
+
andamento, sem repetir o clique.
|
|
512
713
|
|
|
513
714
|
Se o Chrome/Edge não iniciar porque o perfil persistente já está aberto, o erro
|
|
514
715
|
identifica o PID que o mantém ocupado quando o sistema consegue associar o
|
|
515
|
-
perfil ao processo. Em Windows, o MCP consulta a linha de comando dos processos
|
|
516
|
-
Chrome/Edge; em outros sistemas, usa o `SingletonLock` do Chromium.
|
|
517
|
-
|
|
716
|
+
perfil ao processo. Em Windows, o MCP consulta a linha de comando dos processos
|
|
717
|
+
Chrome/Edge; em outros sistemas, usa o `SingletonLock` do Chromium. O caminho
|
|
718
|
+
padrão já separa processos por PID; configure `JEV_BROWSER_PROFILE` para mudar
|
|
719
|
+
a raiz e `JEV_BROWSER_SESSION_ID` para nomear a instância.
|
|
518
720
|
Resultados MCP incluem `server_version`; erros também começam com a versão do
|
|
519
721
|
servidor para facilitar a comparação entre instalações. A ferramenta
|
|
520
722
|
`browser_health` informa se a sessão está ativa e tenta reconectar um browser
|
|
@@ -523,11 +725,50 @@ reiniciar somente o navegador administrado por este processo MCP. Um fluxo pode
|
|
|
523
725
|
ser repetido automaticamente uma vez após `BROWSER_DISCONNECTED` quando nenhuma
|
|
524
726
|
etapa mutável foi executada.
|
|
525
727
|
|
|
526
|
-
`harness_browser` e `computer_browser` aceitam `chrome` ou `msedge`.
|
|
527
|
-
`computer_user_data_dir` deve ficar fora do repositório e conter `{browser}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
728
|
+
`harness_browser` e `computer_browser` aceitam `chrome` ou `msedge`.
|
|
729
|
+
`computer_user_data_dir` deve ficar fora do repositório e conter `{browser}` e
|
|
730
|
+
`{session}`;
|
|
731
|
+
o diretório persistente armazena dados de login e é resolvido sob a pasta home
|
|
732
|
+
do usuário quando começa com `~`. O Playwright MCP fica desabilitado até
|
|
733
|
+
`ORQUESTRADOR_MCP_PLAYWRIGHT_ENABLED=1` ser configurado no ambiente do harness.
|
|
734
|
+
|
|
735
|
+
## Preparar smoke autenticado local
|
|
736
|
+
|
|
737
|
+
O MCP não cria a identidade nem os dados do sistema testado. Para um smoke de
|
|
738
|
+
administração, suba a API e a UI locais, use um banco descartável com dados
|
|
739
|
+
fictícios e uma identidade OIDC de teste que tenha explicitamente a claim
|
|
740
|
+
`administrator`. Mantenha as regras de autorização de produção iguais; um token
|
|
741
|
+
de operador legado não deve ser promovido para admin só para fazer o smoke.
|
|
742
|
+
|
|
743
|
+
Faça o preflight nesta ordem:
|
|
744
|
+
|
|
745
|
+
1. `browser_health` confirma a versão, o perfil/sessão e a conexão do navegador.
|
|
746
|
+
Se o perfil estiver ocupado, use outro `JEV_BROWSER_SESSION_ID` ou
|
|
747
|
+
`JEV_BROWSER_PROFILE`; não encerre o Chrome do operador.
|
|
748
|
+
2. `options.wait_for_http` aguarda a API local responder antes de abrir a UI.
|
|
749
|
+
Informe a URL da interface em `initial_url` e a rota de health da API no
|
|
750
|
+
probe.
|
|
751
|
+
3. `run_browser_flow` confirma que a tela administrativa esperada está visível
|
|
752
|
+
e que a identidade abriu com papel administrativo. Se aparecer a tela de
|
|
753
|
+
login, configure a conta de teste ou o provedor OIDC local; não copie o token
|
|
754
|
+
para `flow`, `params` ou logs. Use `text_env` para campos secretos.
|
|
755
|
+
4. Valide primeiro uma prévia read-only com `assert_*`, `assert_network` e
|
|
756
|
+
captura de evidência. Para um fluxo que poderia gravar dados, use
|
|
757
|
+
`dry_run: true`; ele para antes da primeira etapa marcada como mutável.
|
|
758
|
+
5. Só execute o passo de gravação em dados fictícios, depois de conferir o texto
|
|
759
|
+
do diálogo com `confirm_modal`/`confirm_dialog` e autorizar o token de
|
|
760
|
+
confirmação. Reinicializações de serviços e consultas diretas ao banco ficam
|
|
761
|
+
fora do smoke de tela.
|
|
762
|
+
|
|
763
|
+
Esse preflight é um roteiro composto por `browser_health`, `wait_for_http` e
|
|
764
|
+
asserções da própria aplicação; não há uma ferramenta genérica que valide a
|
|
765
|
+
claim OIDC `administrator`. A checagem do papel precisa usar um sinal visível ou
|
|
766
|
+
uma asserção específica do sistema consumidor.
|
|
767
|
+
|
|
768
|
+
Um `expected_outcome` descreve o objetivo; o resultado `passed` vem das
|
|
769
|
+
asserções explícitas ou da conclusão do plano. Verifique
|
|
770
|
+
`expected_outcome_visible` separadamente quando a frase global fizer parte do
|
|
771
|
+
critério do teste.
|
|
531
772
|
|
|
532
773
|
Defina o valor secreto na variável indicada por `jev.credential_env`, usando o
|
|
533
774
|
secret manager ou ambiente do processo que inicia o harness. Não grave a chave
|
|
@@ -565,18 +806,24 @@ sob demanda podem excedê-la. O MCP devolve `total_ms`, `browser_session_ms`,
|
|
|
565
806
|
para localizar o custo. O teto observado em um fluxo sintético local anterior
|
|
566
807
|
foi 6,411 s; isso não mede o Instagram nem garante o mesmo tempo em outros sites.
|
|
567
808
|
|
|
568
|
-
O snapshot inicial, o fluxo, o resultado esperado e as descrições dos planos
|
|
569
|
-
são enviados ao endpoint Decisions quando há mais de uma opção.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
809
|
+
O snapshot inicial, o fluxo, o resultado esperado e as descrições dos planos
|
|
810
|
+
são enviados ao endpoint Decisions quando há mais de uma opção. Antes do envio,
|
|
811
|
+
valores dos controles são substituídos e hrefs têm query string e fragmento
|
|
812
|
+
removidos; padrões de PII também são mascarados. Com fast-path, um plano não
|
|
813
|
+
gera chamada remota. Os passos, valores digitados, valores esperados pelas
|
|
814
|
+
asserções, caminhos e conteúdo dos arquivos não são enviados.
|
|
815
|
+
Não inclua segredos em `flow`, `expected_outcome` ou nas descrições. A resposta
|
|
816
|
+
retorna o plano escolhido quando houver decisão, custo/confiança do provedor
|
|
817
|
+
quando disponíveis e o snapshot final sanitizado. Um `expected_outcome` em
|
|
818
|
+
texto simples é descritivo: `expected_outcome_visible` indica separadamente se
|
|
819
|
+
a frase apareceu, e completar o plano pode resultar em `passed` mesmo que ela
|
|
820
|
+
não apareça. Use a forma estruturada para tornar texto ou resposta de rede uma
|
|
821
|
+
condição obrigatória; se ela não passar, o fluxo falha.
|
|
822
|
+
|
|
823
|
+
`network_idle` é uma espera limitada e opcional. Polling e conexões contínuas
|
|
824
|
+
não relacionadas a `url_contains` não bloqueiam o modo filtrado; prefira
|
|
825
|
+
`wait_for_text` ou `assert_network` quando houver sinal de interface ou uma
|
|
826
|
+
resposta HTTP específica.
|
|
580
827
|
|
|
581
828
|
Consulte a [introdução do Jev](https://docs.typesafe.ai/introduction) e o
|
|
582
829
|
[tutorial da API Decisions no OpenRouter](https://openrouter.ai/docs/guides/community/jev-tutorial)
|