@diegosouzacdv/jev-browser-mcp 0.4.0 → 0.4.1
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 +86 -28
- package/config/ui-testing.json +3 -0
- package/docs/jev-browser-mcp.md +86 -28
- package/mcp_servers/jev-browser-npm/src/config.mjs +6 -0
- package/mcp_servers/jev-browser-npm/src/flow.mjs +737 -308
- package/mcp_servers/jev-browser-npm/src/jev-client.mjs +5 -4
- package/mcp_servers/jev-browser-npm/src/server.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,9 +69,11 @@ sessão do browser por processo e reutiliza essa sessão entre chamadas. O plano
|
|
|
69
69
|
passado ao Jev continua declarativo: clique, preenchimento, seleção nativa,
|
|
70
70
|
hover, espera, teclas aprovadas, asserções por elemento, upload restrito a uma
|
|
71
71
|
raiz local configurada e reações idempotentes a um comentário único. Também
|
|
72
|
-
aceita um nome de iframe para as ações que ocorrem dentro dele. Não aceita
|
|
73
|
-
JavaScript enviado pelo harness
|
|
74
|
-
|
|
72
|
+
aceita um nome de iframe para as ações que ocorrem dentro dele. Não aceita
|
|
73
|
+
JavaScript enviado pelo harness nem coordenadas. Além de papel/nome acessível,
|
|
74
|
+
aceita `label`, `placeholder`, `title`, `text`, `test_id` e `selector`; CSS/XPath
|
|
75
|
+
são o último recurso e geram um aviso no resultado. Ele usa a
|
|
76
|
+
biblioteca Playwright diretamente, sem iniciar um segundo servidor MCP do
|
|
75
77
|
Playwright. O transporte MCP usa `stdio`; toda saída de diagnóstico vai para
|
|
76
78
|
`stderr` para não misturar com JSON-RPC.
|
|
77
79
|
|
|
@@ -87,29 +89,50 @@ a página inicial, captura o snapshot acessível e pede ao Jev que escolha um
|
|
|
87
89
|
plano. Em seguida, executa o plano inteiro na mesma sessão e confere o
|
|
88
90
|
resultado esperado na tela.
|
|
89
91
|
|
|
90
|
-
Cada plano pode usar:
|
|
91
|
-
|
|
92
|
-
- `click`, `type`, `hover
|
|
92
|
+
Cada plano pode usar:
|
|
93
|
+
|
|
94
|
+
- `click`, `type`, `hover`, `select_option`, `press`, `assert_*` e upload com
|
|
95
|
+
papel/nome acessível ou um localizador: `label`, `placeholder`, `title`,
|
|
96
|
+
`text`, `test_id` ou `selector`;
|
|
97
|
+
- `near: {"text":"..."}` para localizar o controle logo depois de um texto,
|
|
98
|
+
e `within: {"row_containing":"..."}` para limitar a ação à linha certa;
|
|
99
|
+
- `within: {"role":"dialog"}` sem `name` para usar o único diálogo visível;
|
|
100
|
+
o MCP ignora diálogos visualmente ocultos, inclusive os que ficaram no DOM
|
|
101
|
+
com `opacity: 0`;
|
|
102
|
+
- `name: ""` com `index` não negativo para controles sem nome. O resultado
|
|
103
|
+
inclui um aviso porque a posição pode mudar entre execuções;
|
|
104
|
+
- `selector` com CSS ou XPath como último recurso. O MCP identifica essa escolha
|
|
105
|
+
em `warnings`; não é permitido enviar JavaScript nem coordenadas;
|
|
93
106
|
- `timeout_seconds` opcional em cada etapa, limitado pela configuração central;
|
|
94
107
|
- `type` com `mode: "keys"` para digitar sequencialmente em campos com máscara,
|
|
95
108
|
`blur: true` para desfocar o campo e `sensitive: false` para permitir que o
|
|
96
|
-
valor apareça nas evidências;
|
|
109
|
+
valor apareça nas evidências. Nesse modo, `\n` envia Enter e `\t` envia Tab;
|
|
97
110
|
- `wait_for_text` e `wait_for_condition` (`network_idle`, `hidden` ou
|
|
98
|
-
`text_hidden`);
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
`text_hidden`); `network_idle` aceita `url_contains` para aguardar só as
|
|
112
|
+
requisições correspondentes;
|
|
113
|
+
- `press` (o alias legado `press_key` também é aceito) com `PageDown`, `PageUp`,
|
|
114
|
+
`Home`, `End`, setas, `Enter`, `Escape`, `Tab` ou `Shift+Tab`. Sem alvo,
|
|
115
|
+
envia a tecla ao elemento focado; com alvo, usa o localizador informado;
|
|
101
116
|
- `assert_text`, `assert_value`, `assert_visible` e `assert_hidden`; `assert_text`
|
|
102
117
|
pode receber apenas `role` quando a região, como `alert`, não tem nome acessível;
|
|
103
118
|
- `upload_file` para input rotulado, botão que abre o seletor de arquivo ou
|
|
104
119
|
dropzone;
|
|
105
120
|
- `audit_accessibility` com axe-core para WCAG 2.1 A/AA;
|
|
106
|
-
- `like_comment` e `unlike_comment`, que localizam uma linha pelo autor e texto,
|
|
107
|
-
não repetem uma reação já no estado pedido e distinguem `Curtir` de
|
|
108
|
-
`Descurtir`.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
- `like_comment` e `unlike_comment`, que localizam uma linha pelo autor e texto,
|
|
122
|
+
não repetem uma reação já no estado pedido e distinguem `Curtir` de
|
|
123
|
+
`Descurtir`.
|
|
124
|
+
|
|
125
|
+
Em `wait_for_condition` com `condition: "hidden"`, use qualquer um desses
|
|
126
|
+
localizadores, `near` ou `within`; `text_hidden` recebe o texto direto. Para
|
|
127
|
+
aguardar o fim de uma chamada específica, use `condition: "network_idle"` com
|
|
128
|
+
`url_contains`; o MCP precisa observar a requisição depois da etapa anterior e
|
|
129
|
+
esperar que ela termine.
|
|
130
|
+
|
|
131
|
+
Quando vários controles têm o mesmo papel e nome, `within` limita a busca a um
|
|
132
|
+
container acessível único, como uma linha, card ou diálogo. `index` escolhe uma
|
|
133
|
+
ocorrência zero-based dentro desse escopo; sem `index`, o MCP exige exatamente
|
|
134
|
+
um alvo. Para uma página com rótulo `for` quebrado, `label` também procura o
|
|
135
|
+
controle próximo ao texto visível do rótulo.
|
|
113
136
|
|
|
114
137
|
```json
|
|
115
138
|
{
|
|
@@ -121,8 +144,40 @@ zero-based dentro desse escopo; sem `index`, o MCP exige exatamente um alvo.
|
|
|
121
144
|
```
|
|
122
145
|
|
|
123
146
|
```json
|
|
124
|
-
{"action":"click","role":"button","name":"Add to cart","index":0}
|
|
125
|
-
```
|
|
147
|
+
{"action":"click","role":"button","name":"Add to cart","index":0}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Exemplos para controles legados sem nome acessível:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{"action":"type","role":"textbox","label":"Vencimento","text":"05/10/2026"}
|
|
154
|
+
{"action":"type","role":"textbox","target_text":"Vencimento","text":"05/10/2026"}
|
|
155
|
+
{"action":"click","role":"link","title":"Editar documento","within":{"row_containing":"1528721"}}
|
|
156
|
+
{"action":"press","key":"Enter","role":"textbox","placeholder":"Busca rápida"}
|
|
157
|
+
{"action":"click","role":"button","name":"","index":0}
|
|
158
|
+
{"action":"click","selector":"#save-document"}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
O reconhecimento retorna `unnamed_controls` com papel, posição, rótulo mais
|
|
162
|
+
próximo e um trecho HTML sanitizado dos controles interativos sem nome. O
|
|
163
|
+
snapshot também resume campos de formulário com `id`, `name`, valor, estado
|
|
164
|
+
desabilitado, rótulo e índice zero-based entre campos de mesmo nome. Valores
|
|
165
|
+
sensíveis, como senha, token e cartão, são ocultados. `snapshot_include_hidden`
|
|
166
|
+
é `false` por padrão; defina `true` somente quando precisar inspecionar campos
|
|
167
|
+
ocultos também.
|
|
168
|
+
|
|
169
|
+
Em uma etapa `type`, `text` contém o valor a digitar; use `target_text` para
|
|
170
|
+
localizar pelo texto visível próximo ao campo. Esse localizador exige `role`
|
|
171
|
+
`textbox`, `searchbox` ou `combobox`.
|
|
172
|
+
|
|
173
|
+
Por padrão, o MCP executa todos os passos antes de avaliar `expected_outcome`.
|
|
174
|
+
Valores dentro de campos não contam como resultado visível. `stop_on_expected:
|
|
175
|
+
true` habilita parada antecipada quando o texto esperado aparece fora dos
|
|
176
|
+
campos; mantenha `false` para fluxos com várias etapas.
|
|
177
|
+
|
|
178
|
+
Os erros de validação apontam o campo inválido e os campos aceitos. Os limites
|
|
179
|
+
de `timeout_seconds` informam o máximo configurado, em vez de exigir tentativa
|
|
180
|
+
e erro.
|
|
126
181
|
|
|
127
182
|
### Captura de downloads
|
|
128
183
|
|
|
@@ -159,12 +214,13 @@ trechos da página. Qualquer violação reprova esse fluxo. A auditoria automát
|
|
|
159
214
|
encontra problemas comuns, mas não comprova conformidade WCAG completa; combine-a
|
|
160
215
|
com revisão manual e testes com usuários assistivos.
|
|
161
216
|
|
|
162
|
-
Para ações em iframe, acrescente `"frame": "payment-iframe"`; o valor precisa
|
|
163
|
-
corresponder ao atributo `name` ou `title` do iframe. O snapshot inclui o
|
|
164
|
-
conteúdo acessível dos iframes nomeados dentro do escopo, limitado pela
|
|
165
|
-
configuração. Se um alvo estiver ausente, o erro inclui até três nomes acessíveis
|
|
166
|
-
próximos quando o snapshot os encontrar.
|
|
167
|
-
|
|
217
|
+
Para ações em iframe, acrescente `"frame": "payment-iframe"`; o valor precisa
|
|
218
|
+
corresponder ao atributo `name` ou `title` do iframe. O snapshot inclui o
|
|
219
|
+
conteúdo acessível dos iframes nomeados dentro do escopo, limitado pela
|
|
220
|
+
configuração. Se um alvo estiver ausente, o erro inclui até três nomes acessíveis
|
|
221
|
+
próximos quando o snapshot os encontrar. CSS/XPath são permitidos somente como
|
|
222
|
+
localizadores explícitos de último recurso e geram aviso. O plano não aceita
|
|
223
|
+
JavaScript enviado pelo harness nem coordenadas.
|
|
168
224
|
|
|
169
225
|
Os aliases `value` → `text` em `type`/`wait_for_text` e `value` → `expected` em
|
|
170
226
|
asserções são aceitos. `comment` também é aceito em planos e passos, mas é
|
|
@@ -285,11 +341,13 @@ continua informada mesmo quando a lista é truncada.
|
|
|
285
341
|
O `run_browser_flow` aceita `options` com `fast_path`, `snapshot_scope`,
|
|
286
342
|
`block_trackers`, `capture_console_errors`, `capture_network_errors`,
|
|
287
343
|
`capture_network_error_bodies`, `ready_timeout_seconds`, `ready_network_idle`,
|
|
288
|
-
`ready_stable_ms`, `ready_text`, `reuse_page`, `screenshot_on_failure
|
|
289
|
-
`trace_on_failure`. Sem override,
|
|
344
|
+
`ready_stable_ms`, `ready_text`, `reuse_page`, `screenshot_on_failure`,
|
|
345
|
+
`trace_on_failure`, `snapshot_include_hidden` e `stop_on_expected`. Sem override,
|
|
346
|
+
os padrões são lidos de `jev_browser_mcp` em
|
|
290
347
|
`config/ui-testing.json`: um plano candidato pula a chamada Decisions;
|
|
291
348
|
captura de console e screenshot de falha ficam ligadas; trace, rede e bloqueio
|
|
292
|
-
de recursos ficam desligados
|
|
349
|
+
de recursos ficam desligados; o plano roda até o fim e campos ocultos não são
|
|
350
|
+
acrescentados ao snapshot. O browser espera a SPA renderizar uma captura
|
|
293
351
|
acessível estável. `ready_text` pode identificar o conteúdo que marca a
|
|
294
352
|
prontidão. `reuse_page: true` pula a navegação somente quando a página e
|
|
295
353
|
`initial_url` têm a mesma origem. `snapshot_scope` aceita `body`, `main` ou
|
package/config/ui-testing.json
CHANGED
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"max_step_timeout_seconds": 60,
|
|
33
33
|
"key_delay_ms_default": 30,
|
|
34
34
|
"reuse_page_default": false,
|
|
35
|
+
"stop_on_expected_default": false,
|
|
36
|
+
"snapshot_include_hidden_default": false,
|
|
37
|
+
"visibility_poll_interval_ms_default": 50,
|
|
35
38
|
"capture_network_error_bodies_default": false,
|
|
36
39
|
"max_network_error_body_bytes": 65536,
|
|
37
40
|
"max_network_error_message_chars": 300,
|
package/docs/jev-browser-mcp.md
CHANGED
|
@@ -69,9 +69,11 @@ sessão do browser por processo e reutiliza essa sessão entre chamadas. O plano
|
|
|
69
69
|
passado ao Jev continua declarativo: clique, preenchimento, seleção nativa,
|
|
70
70
|
hover, espera, teclas aprovadas, asserções por elemento, upload restrito a uma
|
|
71
71
|
raiz local configurada e reações idempotentes a um comentário único. Também
|
|
72
|
-
aceita um nome de iframe para as ações que ocorrem dentro dele. Não aceita
|
|
73
|
-
JavaScript enviado pelo harness
|
|
74
|
-
|
|
72
|
+
aceita um nome de iframe para as ações que ocorrem dentro dele. Não aceita
|
|
73
|
+
JavaScript enviado pelo harness nem coordenadas. Além de papel/nome acessível,
|
|
74
|
+
aceita `label`, `placeholder`, `title`, `text`, `test_id` e `selector`; CSS/XPath
|
|
75
|
+
são o último recurso e geram um aviso no resultado. Ele usa a
|
|
76
|
+
biblioteca Playwright diretamente, sem iniciar um segundo servidor MCP do
|
|
75
77
|
Playwright. O transporte MCP usa `stdio`; toda saída de diagnóstico vai para
|
|
76
78
|
`stderr` para não misturar com JSON-RPC.
|
|
77
79
|
|
|
@@ -87,29 +89,50 @@ a página inicial, captura o snapshot acessível e pede ao Jev que escolha um
|
|
|
87
89
|
plano. Em seguida, executa o plano inteiro na mesma sessão e confere o
|
|
88
90
|
resultado esperado na tela.
|
|
89
91
|
|
|
90
|
-
Cada plano pode usar:
|
|
91
|
-
|
|
92
|
-
- `click`, `type`, `hover
|
|
92
|
+
Cada plano pode usar:
|
|
93
|
+
|
|
94
|
+
- `click`, `type`, `hover`, `select_option`, `press`, `assert_*` e upload com
|
|
95
|
+
papel/nome acessível ou um localizador: `label`, `placeholder`, `title`,
|
|
96
|
+
`text`, `test_id` ou `selector`;
|
|
97
|
+
- `near: {"text":"..."}` para localizar o controle logo depois de um texto,
|
|
98
|
+
e `within: {"row_containing":"..."}` para limitar a ação à linha certa;
|
|
99
|
+
- `within: {"role":"dialog"}` sem `name` para usar o único diálogo visível;
|
|
100
|
+
o MCP ignora diálogos visualmente ocultos, inclusive os que ficaram no DOM
|
|
101
|
+
com `opacity: 0`;
|
|
102
|
+
- `name: ""` com `index` não negativo para controles sem nome. O resultado
|
|
103
|
+
inclui um aviso porque a posição pode mudar entre execuções;
|
|
104
|
+
- `selector` com CSS ou XPath como último recurso. O MCP identifica essa escolha
|
|
105
|
+
em `warnings`; não é permitido enviar JavaScript nem coordenadas;
|
|
93
106
|
- `timeout_seconds` opcional em cada etapa, limitado pela configuração central;
|
|
94
107
|
- `type` com `mode: "keys"` para digitar sequencialmente em campos com máscara,
|
|
95
108
|
`blur: true` para desfocar o campo e `sensitive: false` para permitir que o
|
|
96
|
-
valor apareça nas evidências;
|
|
109
|
+
valor apareça nas evidências. Nesse modo, `\n` envia Enter e `\t` envia Tab;
|
|
97
110
|
- `wait_for_text` e `wait_for_condition` (`network_idle`, `hidden` ou
|
|
98
|
-
`text_hidden`);
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
`text_hidden`); `network_idle` aceita `url_contains` para aguardar só as
|
|
112
|
+
requisições correspondentes;
|
|
113
|
+
- `press` (o alias legado `press_key` também é aceito) com `PageDown`, `PageUp`,
|
|
114
|
+
`Home`, `End`, setas, `Enter`, `Escape`, `Tab` ou `Shift+Tab`. Sem alvo,
|
|
115
|
+
envia a tecla ao elemento focado; com alvo, usa o localizador informado;
|
|
101
116
|
- `assert_text`, `assert_value`, `assert_visible` e `assert_hidden`; `assert_text`
|
|
102
117
|
pode receber apenas `role` quando a região, como `alert`, não tem nome acessível;
|
|
103
118
|
- `upload_file` para input rotulado, botão que abre o seletor de arquivo ou
|
|
104
119
|
dropzone;
|
|
105
120
|
- `audit_accessibility` com axe-core para WCAG 2.1 A/AA;
|
|
106
|
-
- `like_comment` e `unlike_comment`, que localizam uma linha pelo autor e texto,
|
|
107
|
-
não repetem uma reação já no estado pedido e distinguem `Curtir` de
|
|
108
|
-
`Descurtir`.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
- `like_comment` e `unlike_comment`, que localizam uma linha pelo autor e texto,
|
|
122
|
+
não repetem uma reação já no estado pedido e distinguem `Curtir` de
|
|
123
|
+
`Descurtir`.
|
|
124
|
+
|
|
125
|
+
Em `wait_for_condition` com `condition: "hidden"`, use qualquer um desses
|
|
126
|
+
localizadores, `near` ou `within`; `text_hidden` recebe o texto direto. Para
|
|
127
|
+
aguardar o fim de uma chamada específica, use `condition: "network_idle"` com
|
|
128
|
+
`url_contains`; o MCP precisa observar a requisição depois da etapa anterior e
|
|
129
|
+
esperar que ela termine.
|
|
130
|
+
|
|
131
|
+
Quando vários controles têm o mesmo papel e nome, `within` limita a busca a um
|
|
132
|
+
container acessível único, como uma linha, card ou diálogo. `index` escolhe uma
|
|
133
|
+
ocorrência zero-based dentro desse escopo; sem `index`, o MCP exige exatamente
|
|
134
|
+
um alvo. Para uma página com rótulo `for` quebrado, `label` também procura o
|
|
135
|
+
controle próximo ao texto visível do rótulo.
|
|
113
136
|
|
|
114
137
|
```json
|
|
115
138
|
{
|
|
@@ -121,8 +144,40 @@ zero-based dentro desse escopo; sem `index`, o MCP exige exatamente um alvo.
|
|
|
121
144
|
```
|
|
122
145
|
|
|
123
146
|
```json
|
|
124
|
-
{"action":"click","role":"button","name":"Add to cart","index":0}
|
|
125
|
-
```
|
|
147
|
+
{"action":"click","role":"button","name":"Add to cart","index":0}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Exemplos para controles legados sem nome acessível:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{"action":"type","role":"textbox","label":"Vencimento","text":"05/10/2026"}
|
|
154
|
+
{"action":"type","role":"textbox","target_text":"Vencimento","text":"05/10/2026"}
|
|
155
|
+
{"action":"click","role":"link","title":"Editar documento","within":{"row_containing":"1528721"}}
|
|
156
|
+
{"action":"press","key":"Enter","role":"textbox","placeholder":"Busca rápida"}
|
|
157
|
+
{"action":"click","role":"button","name":"","index":0}
|
|
158
|
+
{"action":"click","selector":"#save-document"}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
O reconhecimento retorna `unnamed_controls` com papel, posição, rótulo mais
|
|
162
|
+
próximo e um trecho HTML sanitizado dos controles interativos sem nome. O
|
|
163
|
+
snapshot também resume campos de formulário com `id`, `name`, valor, estado
|
|
164
|
+
desabilitado, rótulo e índice zero-based entre campos de mesmo nome. Valores
|
|
165
|
+
sensíveis, como senha, token e cartão, são ocultados. `snapshot_include_hidden`
|
|
166
|
+
é `false` por padrão; defina `true` somente quando precisar inspecionar campos
|
|
167
|
+
ocultos também.
|
|
168
|
+
|
|
169
|
+
Em uma etapa `type`, `text` contém o valor a digitar; use `target_text` para
|
|
170
|
+
localizar pelo texto visível próximo ao campo. Esse localizador exige `role`
|
|
171
|
+
`textbox`, `searchbox` ou `combobox`.
|
|
172
|
+
|
|
173
|
+
Por padrão, o MCP executa todos os passos antes de avaliar `expected_outcome`.
|
|
174
|
+
Valores dentro de campos não contam como resultado visível. `stop_on_expected:
|
|
175
|
+
true` habilita parada antecipada quando o texto esperado aparece fora dos
|
|
176
|
+
campos; mantenha `false` para fluxos com várias etapas.
|
|
177
|
+
|
|
178
|
+
Os erros de validação apontam o campo inválido e os campos aceitos. Os limites
|
|
179
|
+
de `timeout_seconds` informam o máximo configurado, em vez de exigir tentativa
|
|
180
|
+
e erro.
|
|
126
181
|
|
|
127
182
|
### Captura de downloads
|
|
128
183
|
|
|
@@ -159,12 +214,13 @@ trechos da página. Qualquer violação reprova esse fluxo. A auditoria automát
|
|
|
159
214
|
encontra problemas comuns, mas não comprova conformidade WCAG completa; combine-a
|
|
160
215
|
com revisão manual e testes com usuários assistivos.
|
|
161
216
|
|
|
162
|
-
Para ações em iframe, acrescente `"frame": "payment-iframe"`; o valor precisa
|
|
163
|
-
corresponder ao atributo `name` ou `title` do iframe. O snapshot inclui o
|
|
164
|
-
conteúdo acessível dos iframes nomeados dentro do escopo, limitado pela
|
|
165
|
-
configuração. Se um alvo estiver ausente, o erro inclui até três nomes acessíveis
|
|
166
|
-
próximos quando o snapshot os encontrar.
|
|
167
|
-
|
|
217
|
+
Para ações em iframe, acrescente `"frame": "payment-iframe"`; o valor precisa
|
|
218
|
+
corresponder ao atributo `name` ou `title` do iframe. O snapshot inclui o
|
|
219
|
+
conteúdo acessível dos iframes nomeados dentro do escopo, limitado pela
|
|
220
|
+
configuração. Se um alvo estiver ausente, o erro inclui até três nomes acessíveis
|
|
221
|
+
próximos quando o snapshot os encontrar. CSS/XPath são permitidos somente como
|
|
222
|
+
localizadores explícitos de último recurso e geram aviso. O plano não aceita
|
|
223
|
+
JavaScript enviado pelo harness nem coordenadas.
|
|
168
224
|
|
|
169
225
|
Os aliases `value` → `text` em `type`/`wait_for_text` e `value` → `expected` em
|
|
170
226
|
asserções são aceitos. `comment` também é aceito em planos e passos, mas é
|
|
@@ -285,11 +341,13 @@ continua informada mesmo quando a lista é truncada.
|
|
|
285
341
|
O `run_browser_flow` aceita `options` com `fast_path`, `snapshot_scope`,
|
|
286
342
|
`block_trackers`, `capture_console_errors`, `capture_network_errors`,
|
|
287
343
|
`capture_network_error_bodies`, `ready_timeout_seconds`, `ready_network_idle`,
|
|
288
|
-
`ready_stable_ms`, `ready_text`, `reuse_page`, `screenshot_on_failure
|
|
289
|
-
`trace_on_failure`. Sem override,
|
|
344
|
+
`ready_stable_ms`, `ready_text`, `reuse_page`, `screenshot_on_failure`,
|
|
345
|
+
`trace_on_failure`, `snapshot_include_hidden` e `stop_on_expected`. Sem override,
|
|
346
|
+
os padrões são lidos de `jev_browser_mcp` em
|
|
290
347
|
`config/ui-testing.json`: um plano candidato pula a chamada Decisions;
|
|
291
348
|
captura de console e screenshot de falha ficam ligadas; trace, rede e bloqueio
|
|
292
|
-
de recursos ficam desligados
|
|
349
|
+
de recursos ficam desligados; o plano roda até o fim e campos ocultos não são
|
|
350
|
+
acrescentados ao snapshot. O browser espera a SPA renderizar uma captura
|
|
293
351
|
acessível estável. `ready_text` pode identificar o conteúdo que marca a
|
|
294
352
|
prontidão. `reuse_page: true` pula a navegação somente quando a página e
|
|
295
353
|
`initial_url` têm a mesma origem. `snapshot_scope` aceita `body`, `main` ou
|
|
@@ -27,6 +27,9 @@ const CONFIG_KEYS = {
|
|
|
27
27
|
"max_step_timeout_seconds",
|
|
28
28
|
"key_delay_ms_default",
|
|
29
29
|
"reuse_page_default",
|
|
30
|
+
"stop_on_expected_default",
|
|
31
|
+
"snapshot_include_hidden_default",
|
|
32
|
+
"visibility_poll_interval_ms_default",
|
|
30
33
|
"capture_network_error_bodies_default",
|
|
31
34
|
"max_network_error_body_bytes",
|
|
32
35
|
"max_network_error_message_chars",
|
|
@@ -264,6 +267,7 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
|
|
|
264
267
|
postStepReadyTimeoutMs: postStepReadyTimeoutSeconds * 1000,
|
|
265
268
|
maxStepTimeoutSeconds: positiveNumber(browserOptions.max_step_timeout_seconds, "jev_browser_mcp.browser.max_step_timeout_seconds"),
|
|
266
269
|
keyDelayMs: positiveNumber(browserOptions.key_delay_ms_default, "jev_browser_mcp.browser.key_delay_ms_default", true),
|
|
270
|
+
visibilityPollMs: positiveNumber(browserOptions.visibility_poll_interval_ms_default, "jev_browser_mcp.browser.visibility_poll_interval_ms_default", true),
|
|
267
271
|
maxNetworkErrorBodyBytes: positiveNumber(browserOptions.max_network_error_body_bytes, "jev_browser_mcp.browser.max_network_error_body_bytes", true),
|
|
268
272
|
maxNetworkErrorMessageChars: positiveNumber(browserOptions.max_network_error_message_chars, "jev_browser_mcp.browser.max_network_error_message_chars", true),
|
|
269
273
|
maxUploadFiles: positiveNumber(browserOptions.max_upload_files, "jev_browser_mcp.browser.max_upload_files", true),
|
|
@@ -287,6 +291,8 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
|
|
|
287
291
|
blockTrackers: booleanValue(browserOptions.block_trackers_default, "jev_browser_mcp.browser.block_trackers_default"),
|
|
288
292
|
readyNetworkIdle: booleanValue(browserOptions.ready_network_idle_default, "jev_browser_mcp.browser.ready_network_idle_default"),
|
|
289
293
|
reusePage: booleanValue(browserOptions.reuse_page_default, "jev_browser_mcp.browser.reuse_page_default"),
|
|
294
|
+
stopOnExpected: booleanValue(browserOptions.stop_on_expected_default, "jev_browser_mcp.browser.stop_on_expected_default"),
|
|
295
|
+
snapshotIncludeHidden: booleanValue(browserOptions.snapshot_include_hidden_default, "jev_browser_mcp.browser.snapshot_include_hidden_default"),
|
|
290
296
|
readyTimeoutSeconds: readyTimeoutSecondsDefault,
|
|
291
297
|
readyStableMs: readyStableMsDefault,
|
|
292
298
|
snapshotScope,
|