@diegosouzacdv/jev-browser-mcp 0.6.0 → 0.6.2
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 +176 -66
- package/config/ui-testing.json +20 -3
- package/docs/jev-browser-mcp.md +176 -66
- package/mcp_servers/jev-browser-npm/src/accessibility.mjs +18 -9
- package/mcp_servers/jev-browser-npm/src/config.mjs +109 -52
- package/mcp_servers/jev-browser-npm/src/flow.mjs +1181 -315
- package/mcp_servers/jev-browser-npm/src/jev-client.mjs +22 -9
- package/mcp_servers/jev-browser-npm/src/server.mjs +109 -30
- package/package.json +1 -1
package/README.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.6.
|
|
20
|
+
"args": ["--yes", "@diegosouzacdv/jev-browser-mcp@0.6.2"],
|
|
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
|
|
35
|
+
npm install @diegosouzacdv/jev-browser-mcp@0.6.2
|
|
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.6.
|
|
43
|
+
npm install --global @diegosouzacdv/jev-browser-mcp@0.6.2
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Depois configure o servidor MCP com `command: "jev-browser-mcp"` e `args: []`.
|
|
@@ -49,7 +49,7 @@ 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 --install-browser`.
|
|
52
|
+
pelo Playwright com `npx --yes @diegosouzacdv/jev-browser-mcp@0.6.2 --install-browser`.
|
|
53
53
|
|
|
54
54
|
O padrão é `computer`: o pacote abre o Chrome/Edge instalado e usa um perfil
|
|
55
55
|
persistente exclusivo em `browser.computer_user_data_dir`. No modo `harness`, a
|
|
@@ -92,7 +92,13 @@ Playwright. O transporte MCP usa `stdio`; toda saída de diagnóstico vai para
|
|
|
92
92
|
O modo `computer` grava cookies no perfil exclusivo configurado, e conteúdo da
|
|
93
93
|
página pode conter instruções maliciosas. O Jev recebe a captura acessível com
|
|
94
94
|
uma instrução para tratar esse conteúdo como dado não confiável; não inclua
|
|
95
|
-
segredos no fluxo, no resultado esperado ou nas descrições dos planos.
|
|
95
|
+
segredos no fluxo, no resultado esperado ou nas descrições dos planos. Antes de
|
|
96
|
+
enviar contexto ao provedor, o cliente mascara valores de campos e padrões
|
|
97
|
+
detectados de CPF/CNPJ, email, telefone, nome de cliente e valores monetários.
|
|
98
|
+
Isso reduz exposição acidental, mas não substitui o cuidado com os dados que o
|
|
99
|
+
harness escolhe incluir no fluxo. Use `local_only: true` quando nenhuma chamada
|
|
100
|
+
externa ao Jev puder ocorrer; esse modo recusa fluxos que precisam escolher
|
|
101
|
+
entre vários planos.
|
|
96
102
|
|
|
97
103
|
Para um fluxo conhecido, o LLM do harness procura o cenário e os critérios de
|
|
98
104
|
aceitação no projeto e chama `jev_browser.run_browser_flow` com planos
|
|
@@ -101,11 +107,17 @@ a página inicial, captura o snapshot acessível e pede ao Jev que escolha um
|
|
|
101
107
|
plano. Em seguida, executa o plano inteiro na mesma sessão e confere o
|
|
102
108
|
resultado esperado na tela.
|
|
103
109
|
|
|
104
|
-
Cada plano pode usar:
|
|
105
|
-
|
|
106
|
-
- `
|
|
107
|
-
|
|
108
|
-
`
|
|
110
|
+
Cada plano pode usar:
|
|
111
|
+
|
|
112
|
+
- `navigate` para mudar de página no meio do fluxo. Com a continuidade ligada,
|
|
113
|
+
um `initial_url` de mesma origem diferente da URL ativa produz erro claro; use
|
|
114
|
+
`navigate` ou `continue_from_current_page: false` para escolher o destino;
|
|
115
|
+
- `click`, `type`, `clear`, `hover`, `select_option`, `press`, `assert_*` e upload com
|
|
116
|
+
papel/nome acessível ou um localizador: `label`, `placeholder`, `title`,
|
|
117
|
+
`text`, `test_id` ou `selector`;
|
|
118
|
+
- `name_match: "exact" | "contains" | "regex"` para controlar a comparação do
|
|
119
|
+
nome acessível; regex rejeita construções com backtracking excessivo. O papel
|
|
120
|
+
`switch` funciona em cliques, verificações e asserções;
|
|
109
121
|
- `near: {"text":"..."}` para localizar o controle logo depois de um texto,
|
|
110
122
|
`within: {"row_containing":"..."}` para limitar por trecho e
|
|
111
123
|
`within: {"row_containing_exact":"..."}` para exigir um elemento com o
|
|
@@ -122,25 +134,34 @@ Cada plano pode usar:
|
|
|
122
134
|
- `selector` com CSS ou XPath como último recurso. O MCP identifica essa escolha
|
|
123
135
|
em `warnings`; não é permitido enviar JavaScript nem coordenadas;
|
|
124
136
|
- `timeout_seconds` opcional em cada etapa, limitado pela configuração central;
|
|
125
|
-
- `type` com `mode: "keys"` para digitar sequencialmente em campos com máscara,
|
|
126
|
-
`blur: true` para desfocar o campo e `sensitive: false` para permitir que o
|
|
127
|
-
valor apareça nas evidências.
|
|
128
|
-
|
|
129
|
-
|
|
137
|
+
- `type` com `mode: "keys"` para digitar sequencialmente em campos com máscara,
|
|
138
|
+
`blur: true` para desfocar o campo e `sensitive: false` para permitir que o
|
|
139
|
+
valor apareça nas evidências. `text_env` lê o valor sensível de uma variável
|
|
140
|
+
de ambiente do processo MCP, sem colocá-lo no plano. Nesse modo, `\n` envia
|
|
141
|
+
Enter e `\t` envia Tab;
|
|
142
|
+
- `wait_for_text`, `wait_for_value`, `wait_for_enabled` e `wait_for_condition`
|
|
143
|
+
(`url`, `network_idle`, `hidden`, `text_hidden` ou `angular_idle`). `wait` recebe
|
|
130
144
|
`ms` para uma pausa curta e limitada. `angular_idle` aguarda requisições
|
|
131
145
|
`$http` e digest do AngularJS. `wait_for_text` aceita `fail_on: {"role":"alert"}` para
|
|
132
146
|
interromper a espera assim que um alerta visível aparecer e incluir seu texto
|
|
133
147
|
no erro. Se o alerta contiver o texto esperado, a etapa passa; caso contrário,
|
|
134
|
-
o alerta interrompe a espera. `
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
148
|
+
o alerta interrompe a espera. `url` aguarda a URL conter `url_contains`.
|
|
149
|
+
`network_idle` aceita esse filtro e aguarda uma janela de silêncio usando
|
|
150
|
+
`ready_stable_ms`; WebSocket, EventSource e polling não relacionado não
|
|
151
|
+
bloqueiam a espera. Se não surgir requisição correspondente, o passo conclui
|
|
152
|
+
após a janela de silêncio;
|
|
153
|
+
- `press` (o alias legado `press_key` também é aceito) com `PageDown`, `PageUp`,
|
|
154
|
+
`Home`, `End`, setas, `Enter`, `Escape`, `Tab`, `Shift+Tab`, `Space`,
|
|
155
|
+
`Backspace` ou `Delete`. `clear` limpa um campo sem exigir texto. Sem alvo,
|
|
156
|
+
`press` envia a tecla ao elemento focado; com alvo, usa o localizador informado;
|
|
139
157
|
- `assert_text`, `assert_value`, `assert_visible`, `assert_hidden` e
|
|
140
158
|
`assert_enabled`; `assert_text`
|
|
141
159
|
pode receber apenas `role` quando a região, como `alert`, não tem nome acessível;
|
|
142
|
-
- `upload_file` para input rotulado, botão que abre o seletor de arquivo ou
|
|
143
|
-
dropzone;
|
|
160
|
+
- `upload_file` para input rotulado, botão que abre o seletor de arquivo ou
|
|
161
|
+
dropzone;
|
|
162
|
+
- `target_page: "popup"` para continuar no popup aberto com `expect_popup: true`;
|
|
163
|
+
locators semânticos também atravessam open Shadow DOM. Shadow DOM fechado não
|
|
164
|
+
é acessível ao Playwright;
|
|
144
165
|
- `audit_accessibility` com axe-core para WCAG 2.1 A/AA;
|
|
145
166
|
- `like_comment` e `unlike_comment`, que localizam uma linha pelo autor e texto,
|
|
146
167
|
não repetem uma reação já no estado pedido e distinguem `Curtir` de
|
|
@@ -148,17 +169,24 @@ Cada plano pode usar:
|
|
|
148
169
|
|
|
149
170
|
As proteções e evidências por etapa usam estes campos:
|
|
150
171
|
|
|
151
|
-
- `confirm_dialog` recebe `expected_text` e `button`.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
172
|
+
- `confirm_dialog` recebe `expected_text` e `button`. Em diálogos HTML, o MCP
|
|
173
|
+
confere o texto antes de localizar e clicar no botão. Também trata diálogos
|
|
174
|
+
nativos `alert`/`confirm`: precisa haver uma etapa `confirm_dialog` logo após
|
|
175
|
+
o clique que os abre, o texto deve corresponder e um diálogo inesperado é
|
|
176
|
+
fechado sem aceitar;
|
|
155
177
|
- `mutating: true` marca etapas que gravam dados ou disparam efeitos externos.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
178
|
+
O MCP também classifica botões conhecidos como `Salvar`, `Emitir`, `Cancelar`
|
|
179
|
+
ou `Sim` pelo nome e pelo controle resolvido, inclusive quando o plano usa um
|
|
180
|
+
seletor CSS. `options.dry_run: true` executa até a primeira etapa mutável e
|
|
181
|
+
para antes dela; retorna `dry_run_stopped_before_step` e um
|
|
182
|
+
`confirmation_token` temporário, de uso único e vinculado ao fluxo e à página.
|
|
183
|
+
Reenvie a mesma chamada com `options.confirmation_token` para autorizar essa
|
|
184
|
+
etapa. O MCP pausa novamente antes de cada outra etapa mutável. Sem `dry_run`,
|
|
185
|
+
o primeiro pedido de ação mutável também retorna `status: "confirmation_required"`
|
|
186
|
+
e token; nenhuma etapa mutável roda sem essa autorização. O token expira após
|
|
187
|
+
dez minutos por padrão;
|
|
160
188
|
- `duration_ms` aparece em cada etapa concluída ou falha. `mutating_steps`
|
|
161
|
-
lista
|
|
189
|
+
lista etapas mutáveis que foram executadas ou falharam;
|
|
162
190
|
- `screenshot: true` salva uma captura depois da etapa e inclui seu caminho na
|
|
163
191
|
evidência da etapa;
|
|
164
192
|
- `options.report_path` grava um resumo `.md` ou JUnit `.xml`. O caminho deve
|
|
@@ -198,11 +226,12 @@ com `within: {"row_containing_exact":"{pedido}"}`, e use uma etapa
|
|
|
198
226
|
`{"action":"extract","role":"cell","name":"{pedido}","within":{"row_containing_exact":"{pedido}"},"as":"documento"}`.
|
|
199
227
|
A etapa seguinte pode localizar o mesmo documento com `name: "{documento}"`.
|
|
200
228
|
|
|
201
|
-
Em `wait_for_condition` com `condition: "hidden"`, use qualquer um desses
|
|
202
|
-
localizadores, `near` ou `within`; `text_hidden` recebe o texto direto. Para
|
|
203
|
-
aguardar o fim de uma chamada específica, use `condition: "network_idle"` com
|
|
204
|
-
`url_contains
|
|
205
|
-
|
|
229
|
+
Em `wait_for_condition` com `condition: "hidden"`, use qualquer um desses
|
|
230
|
+
localizadores, `near` ou `within`; `text_hidden` recebe o texto direto. Para
|
|
231
|
+
aguardar o fim de uma chamada específica, use `condition: "network_idle"` com
|
|
232
|
+
`url_contains`. O filtro considera somente a atividade correspondente e termina
|
|
233
|
+
após a janela configurada sem atividade; também termina caso nenhuma requisição
|
|
234
|
+
correspondente apareça. Para validar status e corpo, prefira `assert_network`.
|
|
206
235
|
|
|
207
236
|
Quando vários controles têm o mesmo papel e nome, `within` limita a busca a um
|
|
208
237
|
container acessível único, como uma linha, card ou diálogo. `index` escolhe uma
|
|
@@ -210,6 +239,17 @@ ocorrência zero-based dentro desse escopo; sem `index`, o MCP exige exatamente
|
|
|
210
239
|
um alvo. Para uma página com rótulo `for` quebrado, `label` também procura o
|
|
211
240
|
controle próximo ao texto visível do rótulo.
|
|
212
241
|
|
|
242
|
+
`within` pode combinar um container e uma linha. Use, por exemplo,
|
|
243
|
+
`{"role":"cell","name":"Documento A","within":{"role":"table","row_containing_word":"1528721"}}`.
|
|
244
|
+
`row_containing_word` usa limites de palavra para não confundir `1528721` com
|
|
245
|
+
`15287210`; `row_containing_exact` continua disponível para texto de célula
|
|
246
|
+
exato. `check` e `uncheck` alteram checkboxes, e `select_option` aceita rótulo
|
|
247
|
+
exato (`option`), valor (`value`) ou rótulo parcial único (`label_contains`).
|
|
248
|
+
`navigate_menu` percorre uma lista de rótulos exatos e abre `#open_btn` quando o
|
|
249
|
+
primeiro item ainda está oculto. Se vários itens visíveis tiverem o mesmo
|
|
250
|
+
rótulo, seleciona a última ocorrência, útil quando o submenu recém-aberto
|
|
251
|
+
repete o nome da categoria pai.
|
|
252
|
+
|
|
213
253
|
```json
|
|
214
254
|
{
|
|
215
255
|
"action": "click",
|
|
@@ -387,15 +427,17 @@ validadores.
|
|
|
387
427
|
|
|
388
428
|
`browser.mode` aceita `harness` ou `computer`; o padrão é `computer`:
|
|
389
429
|
|
|
390
|
-
- `harness` usa Chrome headless e contexto isolado, adequado a execuções do
|
|
391
|
-
harness e CI
|
|
430
|
+
- `harness` usa Chrome headless e contexto isolado, adequado a execuções do
|
|
431
|
+
harness e CI. O processo MCP conserva browser, contexto e página entre
|
|
432
|
+
chamadas; cookies, local storage e estado da página permanecem enquanto o
|
|
433
|
+
processo estiver ativo. Encerre o processo para descartar o contexto isolado.
|
|
392
434
|
- `computer` abre o Chrome ou Edge instalado em modo visível e usa o diretório
|
|
393
435
|
persistente `browser.computer_user_data_dir`, separado por navegador. Não
|
|
394
436
|
reutiliza o perfil pessoal já aberto. Faça login uma vez nesse perfil; os
|
|
395
437
|
cookies permanecem nele entre chamadas.
|
|
396
438
|
|
|
397
|
-
`browser.max_flow_steps` limita
|
|
398
|
-
`browser.max_text_entry_chars` limita cada valor digitado. O resultado contém
|
|
439
|
+
`browser.max_flow_steps` limita os passos de cada plano candidato; os planos
|
|
440
|
+
não são somados. `browser.max_text_entry_chars` limita cada valor digitado. O resultado contém
|
|
399
441
|
`status`, o plano escolhido, as ações executadas, a última captura acessível e
|
|
400
442
|
se o critério esperado apareceu. Quando existem asserções explícitas, `status`
|
|
401
443
|
também pode ser `passed` com todas elas satisfeitas; `assertions_passed` registra
|
|
@@ -429,11 +471,16 @@ limita quantas descrições de violações axe entram no resultado; a contagem t
|
|
|
429
471
|
continua informada mesmo quando a lista é truncada.
|
|
430
472
|
|
|
431
473
|
O `run_browser_flow` aceita `options` com `fast_path`, `snapshot_scope`,
|
|
432
|
-
`block_trackers`, `
|
|
433
|
-
`
|
|
434
|
-
`
|
|
435
|
-
`
|
|
436
|
-
`
|
|
474
|
+
`block_trackers`, `block_fonts`, `local_only`, `busy_selectors`,
|
|
475
|
+
`auto_angular_idle`, `login_url_contains`, `login_text`, `capture_console_errors`,
|
|
476
|
+
`capture_network_errors`, `capture_network_error_bodies`, `ready_timeout_seconds`,
|
|
477
|
+
`ready_network_idle`, `ready_stable_ms`, `ready_text`, `continue_from_current_page`,
|
|
478
|
+
`reuse_page`, `step_timeout_seconds`, `max_flow_steps`, `return_snapshot`,
|
|
479
|
+
`screenshot_on_failure`, `screenshot_on_success`, `trace_on_failure`,
|
|
480
|
+
`trace_on_success`, `record_video`, `snapshot_include_hidden`, `stop_on_expected`,
|
|
481
|
+
`dry_run`, `confirmation_token`, `report_path`, `permissions`, `fake_media`,
|
|
482
|
+
`viewport`, `mobile`, `device_scale_factor`, `locale`, `timezone_id`,
|
|
483
|
+
`color_scheme`, `geolocation` e `allow_mutations`. Sem override,
|
|
437
484
|
os padrões são lidos de `jev_browser_mcp` em
|
|
438
485
|
`config/ui-testing.json`: um plano candidato pula a chamada Decisions;
|
|
439
486
|
captura de console e screenshot de falha ficam ligadas; trace, rede e bloqueio
|
|
@@ -445,16 +492,33 @@ chamadas na mesma origem, não repete `page.goto` e consulta um snapshot atual
|
|
|
445
492
|
sem esperar novamente por `load`/`networkidle`. As etapas continuam aguardando
|
|
446
493
|
seus próprios alvos e condições. `reuse_page` segue como alias legado; defina
|
|
447
494
|
`continue_from_current_page: false` para iniciar cada chamada em `initial_url`.
|
|
448
|
-
Se a página atual e `initial_url` tiverem origens diferentes, o MCP navega para
|
|
449
|
-
`initial_url`.
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
`
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
`
|
|
495
|
+
Se a página atual e `initial_url` tiverem origens diferentes, o MCP navega para
|
|
496
|
+
`initial_url`. Se forem da mesma origem mas URLs completas diferentes, o MCP
|
|
497
|
+
recusa continuar silenciosamente e pede uma etapa `navigate` ou
|
|
498
|
+
`continue_from_current_page: false`. `snapshot_scope` aceita `body`, `main` ou
|
|
499
|
+
`dialog`; se `main` não existir, o snapshot usa `body`.
|
|
500
|
+
|
|
501
|
+
`block_trackers: true` bloqueia analytics/trackers e os tipos de recurso
|
|
502
|
+
configurados, mas preserva `media` quando há permissão de microfone ou
|
|
503
|
+
`fake_media`. Fontes ficam habilitadas por padrão para preservar ícones e
|
|
504
|
+
glyphs; `block_fonts: true` bloqueia fontes separadamente. `busy_selectors`
|
|
505
|
+
complementa `aria-busy="true"` ao aguardar overlays; elementos ocultos ou fora
|
|
506
|
+
da tela com esse atributo não seguram a prontidão da página.
|
|
507
|
+
`auto_angular_idle` aguarda AngularJS depois de cliques e digitação quando a
|
|
508
|
+
página expõe o injector. `login_url_contains` e `login_text` substituem a
|
|
509
|
+
detecção padrão de autenticação. `local_only: true` recusa qualquer etapa que
|
|
510
|
+
precisaria chamar o provedor Jev; use exatamente um plano com `fast_path: true`.
|
|
511
|
+
`allow_mutations: true` pula a confirmação humana somente para URLs em
|
|
512
|
+
`localhost`, `127.0.0.1` ou `::1`; use esse modo apenas em ambientes locais
|
|
513
|
+
controlados.
|
|
514
|
+
`step_timeout_seconds` define o timeout padrão por etapa e cada etapa pode
|
|
515
|
+
substituí-lo com `timeout_seconds`. `max_flow_steps` reduz o limite por chamada,
|
|
516
|
+
sem superar o teto da configuração. `return_snapshot` aceita `full`, `diff` ou
|
|
517
|
+
`none`; `diff` retorna linhas acessíveis novas desde o snapshot inicial.
|
|
518
|
+
|
|
519
|
+
Com `capture_console_errors` e `capture_network_errors`, o retorno traz
|
|
520
|
+
`console_errors` e `network_failures`, limitados em quantidade e tamanho.
|
|
521
|
+
Mensagens de erro idênticas do console são agrupadas em uma entrada com `count`.
|
|
458
522
|
Respostas HTTP 4xx/5xx e requisições que falham são listadas; query strings,
|
|
459
523
|
fragmentos, valores de formulário e nomes de arquivo são removidos ou
|
|
460
524
|
sanitizados. `capture_network_error_bodies: true` lê somente respostas JSON
|
|
@@ -470,9 +534,49 @@ compartilhe os arquivos somente se o teste permitir.
|
|
|
470
534
|
|
|
471
535
|
Screenshots por etapa usam `screenshot: true` no próprio passo; o MCP os grava
|
|
472
536
|
depois que a ação termina. `options.report_path` pode apontar para `.md` ou
|
|
473
|
-
JUnit `.xml` dentro da raiz de artefatos. O relatório inclui a versão, tempos,
|
|
474
|
-
localizadores resolvidos, respostas verificadas por `assert_network`, falhas de
|
|
475
|
-
rede e caminhos dos screenshots, para anexar a um PR ou card.
|
|
537
|
+
JUnit `.xml` dentro da raiz de artefatos. O relatório inclui a versão, tempos,
|
|
538
|
+
localizadores resolvidos, respostas verificadas por `assert_network`, falhas de
|
|
539
|
+
rede e caminhos dos screenshots, para anexar a um PR ou card.
|
|
540
|
+
|
|
541
|
+
`screenshot_on_success` grava a captura final em fluxos aprovados;
|
|
542
|
+
`trace_on_success` salva trace também em sucesso e `record_video` grava vídeo
|
|
543
|
+
WebM. Fluxos que digitam texto sensível suprimem screenshots, traces e vídeos
|
|
544
|
+
para não registrar credenciais. `performance_metrics` inclui métricas do
|
|
545
|
+
navegador quando disponíveis. `jev_browser_mcp.browser.max_tool_response_bytes`
|
|
546
|
+
impõe um teto global de bytes na resposta JSON da ferramenta; se necessário,
|
|
547
|
+
evidências volumosas são reduzidas e marcadas com `output_truncated: true`.
|
|
548
|
+
|
|
549
|
+
Para testar microfone, conceda permissão no escopo da chamada:
|
|
550
|
+
|
|
551
|
+
```json
|
|
552
|
+
{
|
|
553
|
+
"options": {
|
|
554
|
+
"permissions": ["microphone"],
|
|
555
|
+
"fake_media": "fixtures/resposta-aluno.wav",
|
|
556
|
+
"block_trackers": true
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
`fake_media` exige um WAV RIFF válido dentro de `JEV_BROWSER_UPLOAD_ROOT` e
|
|
562
|
+
respeita os mesmos limites de upload. O MCP adiciona as opções de dispositivo
|
|
563
|
+
falso do Chromium e concede permissão ao contexto. Sem esse arquivo, a
|
|
564
|
+
permissão de microfone usa o dispositivo autorizado pelo browser; no modo
|
|
565
|
+
`computer`, o sistema operacional ainda pode pedir acesso ao dispositivo.
|
|
566
|
+
|
|
567
|
+
As opções de emulação aceitam `viewport: {"width": 390, "height": 844}`,
|
|
568
|
+
`mobile: true`, `device_scale_factor`, `locale`, `timezone_id`,
|
|
569
|
+
`color_scheme: "dark"` e `geolocation: {"latitude": -23.55, "longitude": -46.63}`.
|
|
570
|
+
Informar geolocalização concede também a permissão `geolocation`.
|
|
571
|
+
|
|
572
|
+
`audit_accessibility` aceita `scope` com seletor CSS e `fail_on_impact` com
|
|
573
|
+
`minor`, `moderate`, `serious` ou `critical`. O padrão é `minor`; violações
|
|
574
|
+
abaixo do impacto escolhido continuam no relatório, mas não bloqueiam o passo.
|
|
575
|
+
`violations_count` e `blocking_violations_count` separam total e bloqueadoras.
|
|
576
|
+
|
|
577
|
+
Os cliques aguardam `DOMContentLoaded` quando acionam navegação completa e
|
|
578
|
+
tratam a destruição do contexto durante a troca de documento como navegação em
|
|
579
|
+
andamento, sem repetir o clique.
|
|
476
580
|
|
|
477
581
|
Se o Chrome/Edge não iniciar porque o perfil persistente já está aberto, o erro
|
|
478
582
|
identifica o PID que o mantém ocupado quando o sistema consegue associar o
|
|
@@ -482,7 +586,10 @@ Chrome/Edge; em outros sistemas, usa o `SingletonLock` do Chromium. Configure
|
|
|
482
586
|
Resultados MCP incluem `server_version`; erros também começam com a versão do
|
|
483
587
|
servidor para facilitar a comparação entre instalações. A ferramenta
|
|
484
588
|
`browser_health` informa se a sessão está ativa e tenta reconectar um browser
|
|
485
|
-
que encerrou desde a chamada anterior.
|
|
589
|
+
que encerrou desde a chamada anterior. Passe `{"restart":true}` para fechar e
|
|
590
|
+
reiniciar somente o navegador administrado por este processo MCP. Um fluxo pode
|
|
591
|
+
ser repetido automaticamente uma vez após `BROWSER_DISCONNECTED` quando nenhuma
|
|
592
|
+
etapa mutável foi executada.
|
|
486
593
|
|
|
487
594
|
`harness_browser` e `computer_browser` aceitam `chrome` ou `msedge`.
|
|
488
595
|
`computer_user_data_dir` deve ficar fora do repositório e conter `{browser}`;
|
|
@@ -526,18 +633,21 @@ sob demanda podem excedê-la. O MCP devolve `total_ms`, `browser_session_ms`,
|
|
|
526
633
|
para localizar o custo. O teto observado em um fluxo sintético local anterior
|
|
527
634
|
foi 6,411 s; isso não mede o Instagram nem garante o mesmo tempo em outros sites.
|
|
528
635
|
|
|
529
|
-
O snapshot inicial, o fluxo, o resultado esperado e as descrições dos planos
|
|
530
|
-
são enviados ao endpoint Decisions quando há mais de uma opção.
|
|
531
|
-
|
|
532
|
-
|
|
636
|
+
O snapshot inicial, o fluxo, o resultado esperado e as descrições dos planos
|
|
637
|
+
são enviados ao endpoint Decisions quando há mais de uma opção. Antes do envio,
|
|
638
|
+
valores dos controles são substituídos e hrefs têm query string e fragmento
|
|
639
|
+
removidos; padrões de PII também são mascarados. Com fast-path, um plano não
|
|
640
|
+
gera chamada remota. Os passos, valores digitados, valores esperados pelas
|
|
641
|
+
asserções, caminhos e conteúdo dos arquivos não são enviados.
|
|
533
642
|
Não inclua segredos em `flow`, `expected_outcome` ou nas descrições. A resposta
|
|
534
643
|
retorna o plano escolhido quando houver decisão, custo/confiança do provedor
|
|
535
644
|
quando disponíveis e o snapshot final sanitizado. O fluxo passa quando o texto
|
|
536
645
|
esperado aparece no snapshot ou quando todas as asserções declaradas passam.
|
|
537
646
|
|
|
538
|
-
`network_idle` é uma espera limitada e opcional
|
|
539
|
-
|
|
540
|
-
|
|
647
|
+
`network_idle` é uma espera limitada e opcional. Polling e conexões contínuas
|
|
648
|
+
não relacionadas a `url_contains` não bloqueiam o modo filtrado; prefira
|
|
649
|
+
`wait_for_text` ou `assert_network` quando houver sinal de interface ou uma
|
|
650
|
+
resposta HTTP específica.
|
|
541
651
|
|
|
542
652
|
Consulte a [introdução do Jev](https://docs.typesafe.ai/introduction) e o
|
|
543
653
|
[tutorial da API Decisions no OpenRouter](https://openrouter.ai/docs/guides/community/jev-tutorial)
|
package/config/ui-testing.json
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"jev_browser_mcp": {
|
|
24
24
|
"browser": {
|
|
25
25
|
"max_action_timeout_seconds": 8,
|
|
26
|
+
"mutation_confirmation_ttl_seconds": 600,
|
|
26
27
|
"ready_timeout_seconds_default": 15,
|
|
27
28
|
"max_ready_timeout_seconds": 60,
|
|
28
29
|
"ready_network_idle_default": true,
|
|
@@ -37,7 +38,14 @@
|
|
|
37
38
|
"visibility_poll_interval_ms_default": 50,
|
|
38
39
|
"capture_network_error_bodies_default": false,
|
|
39
40
|
"max_network_error_body_bytes": 65536,
|
|
40
|
-
"max_network_error_message_chars": 300,
|
|
41
|
+
"max_network_error_message_chars": 300,
|
|
42
|
+
"max_network_history_events": 4096,
|
|
43
|
+
"max_tool_response_bytes": 131072,
|
|
44
|
+
"max_viewport_width": 3840,
|
|
45
|
+
"max_viewport_height": 2160,
|
|
46
|
+
"accessibility_fail_on_impact_default": "minor",
|
|
47
|
+
"record_video_width": 1280,
|
|
48
|
+
"record_video_height": 720,
|
|
41
49
|
"max_upload_files": 5,
|
|
42
50
|
"max_upload_path_chars": 4096,
|
|
43
51
|
"max_upload_file_bytes": 10485760,
|
|
@@ -52,10 +60,19 @@
|
|
|
52
60
|
"max_frame_snapshots": 5,
|
|
53
61
|
"fast_path_single_plan_default": true,
|
|
54
62
|
"screenshot_on_failure_default": true,
|
|
55
|
-
"trace_on_failure_default": false,
|
|
63
|
+
"trace_on_failure_default": false,
|
|
64
|
+
"trace_on_success_default": false,
|
|
56
65
|
"capture_console_errors_default": true,
|
|
57
66
|
"capture_network_errors_default": false,
|
|
58
67
|
"block_trackers_default": false,
|
|
68
|
+
"block_fonts_default": false,
|
|
69
|
+
"local_only_default": false,
|
|
70
|
+
"auto_angular_idle_default": false,
|
|
71
|
+
"return_snapshot_default": "full",
|
|
72
|
+
"busy_selectors_default": [],
|
|
73
|
+
"login_url_contains_default": ["/auth"],
|
|
74
|
+
"login_text_default": [],
|
|
75
|
+
"max_busy_selectors": 8,
|
|
59
76
|
"snapshot_scope_default": "body",
|
|
60
77
|
"tracker_host_suffixes": [
|
|
61
78
|
"google-analytics.com",
|
|
@@ -64,7 +81,7 @@
|
|
|
64
81
|
"fonts.googleapis.com",
|
|
65
82
|
"fonts.gstatic.com"
|
|
66
83
|
],
|
|
67
|
-
"blocked_resource_types": ["
|
|
84
|
+
"blocked_resource_types": ["media"]
|
|
68
85
|
},
|
|
69
86
|
"jev": {
|
|
70
87
|
"max_diagnostic_items": 50,
|