@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.
@@ -16,23 +16,31 @@ const CONFIG_KEYS = {
16
16
  "max_flow_steps",
17
17
  "max_text_entry_chars",
18
18
  ],
19
- nodeBrowser: [
20
- "max_action_timeout_seconds",
21
- "ready_timeout_seconds_default",
22
- "max_ready_timeout_seconds",
23
- "ready_network_idle_default",
24
- "ready_stable_ms_default",
25
- "max_ready_stable_ms",
26
- "post_step_ready_timeout_seconds_default",
27
- "max_step_timeout_seconds",
28
- "key_delay_ms_default",
29
- "reuse_page_default",
30
- "stop_on_expected_default",
31
- "snapshot_include_hidden_default",
32
- "visibility_poll_interval_ms_default",
33
- "capture_network_error_bodies_default",
19
+ nodeBrowser: [
20
+ "max_action_timeout_seconds",
21
+ "mutation_confirmation_ttl_seconds",
22
+ "ready_timeout_seconds_default",
23
+ "max_ready_timeout_seconds",
24
+ "ready_network_idle_default",
25
+ "ready_stable_ms_default",
26
+ "max_ready_stable_ms",
27
+ "post_step_ready_timeout_seconds_default",
28
+ "max_step_timeout_seconds",
29
+ "key_delay_ms_default",
30
+ "reuse_page_default",
31
+ "stop_on_expected_default",
32
+ "snapshot_include_hidden_default",
33
+ "visibility_poll_interval_ms_default",
34
+ "capture_network_error_bodies_default",
34
35
  "max_network_error_body_bytes",
35
36
  "max_network_error_message_chars",
37
+ "max_network_history_events",
38
+ "max_tool_response_bytes",
39
+ "max_viewport_width",
40
+ "max_viewport_height",
41
+ "accessibility_fail_on_impact_default",
42
+ "record_video_width",
43
+ "record_video_height",
36
44
  "max_upload_files",
37
45
  "max_upload_path_chars",
38
46
  "max_upload_file_bytes",
@@ -47,10 +55,19 @@ const CONFIG_KEYS = {
47
55
  "max_frame_snapshots",
48
56
  "fast_path_single_plan_default",
49
57
  "screenshot_on_failure_default",
50
- "trace_on_failure_default",
58
+ "trace_on_failure_default",
59
+ "trace_on_success_default",
51
60
  "capture_console_errors_default",
52
61
  "capture_network_errors_default",
53
62
  "block_trackers_default",
63
+ "block_fonts_default",
64
+ "local_only_default",
65
+ "auto_angular_idle_default",
66
+ "return_snapshot_default",
67
+ "busy_selectors_default",
68
+ "login_url_contains_default",
69
+ "login_text_default",
70
+ "max_busy_selectors",
54
71
  "snapshot_scope_default",
55
72
  "tracker_host_suffixes",
56
73
  "blocked_resource_types",
@@ -221,7 +238,7 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
221
238
  const uploadRoot = configuredUploadRoot
222
239
  ? configuredDirectory(configuredUploadRoot, `environment ${uploadRootEnv}`)
223
240
  : null;
224
- const snapshotScope = browserOptions.snapshot_scope_default;
241
+ const snapshotScope = browserOptions.snapshot_scope_default;
225
242
  if (!new Set(["body", "main", "dialog"]).has(snapshotScope)) {
226
243
  throw new JevBrowserError("config/ui-testing.json jev_browser_mcp.browser.snapshot_scope_default must be body, main, or dialog");
227
244
  }
@@ -230,28 +247,49 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
230
247
  "jev_browser_mcp.browser.tracker_host_suffixes",
231
248
  (host) => /^[a-z0-9.-]+$/i.test(host) && !host.startsWith(".") && !host.endsWith("."),
232
249
  );
233
- const blockedResourceTypes = stringList(
250
+ const blockedResourceTypes = stringList(
234
251
  browserOptions.blocked_resource_types,
235
252
  "jev_browser_mcp.browser.blocked_resource_types",
236
253
  (type) => new Set(["font", "media", "image"]).has(type),
237
- );
238
- const maxReadyTimeoutSeconds = positiveNumber(browserOptions.max_ready_timeout_seconds, "jev_browser_mcp.browser.max_ready_timeout_seconds");
239
- const readyTimeoutSecondsDefault = positiveNumber(browserOptions.ready_timeout_seconds_default, "jev_browser_mcp.browser.ready_timeout_seconds_default");
240
- const maxReadyStableMs = positiveNumber(browserOptions.max_ready_stable_ms, "jev_browser_mcp.browser.max_ready_stable_ms", true);
241
- const readyStableMsDefault = positiveNumber(browserOptions.ready_stable_ms_default, "jev_browser_mcp.browser.ready_stable_ms_default", true);
242
- if (readyTimeoutSecondsDefault > maxReadyTimeoutSeconds) {
243
- throw new JevBrowserError("config/ui-testing.json ready timeout default exceeds its configured maximum");
244
- }
245
- if (readyStableMsDefault > maxReadyStableMs) {
246
- throw new JevBrowserError("config/ui-testing.json stable snapshot default exceeds its configured maximum");
254
+ );
255
+ const busySelectorsDefault = stringList(
256
+ browserOptions.busy_selectors_default,
257
+ "jev_browser_mcp.browser.busy_selectors_default",
258
+ );
259
+ if (busySelectorsDefault.length > positiveNumber(browserOptions.max_busy_selectors, "jev_browser_mcp.browser.max_busy_selectors", true)) {
260
+ throw new JevBrowserError("config/ui-testing.json busy_selectors_default exceeds max_busy_selectors");
261
+ }
262
+ const loginUrlContainsDefault = stringList(
263
+ browserOptions.login_url_contains_default,
264
+ "jev_browser_mcp.browser.login_url_contains_default",
265
+ );
266
+ const loginTextDefault = stringList(
267
+ browserOptions.login_text_default,
268
+ "jev_browser_mcp.browser.login_text_default",
269
+ );
270
+ if (!new Set(["none", "diff", "full"]).has(browserOptions.return_snapshot_default)) {
271
+ throw new JevBrowserError("config/ui-testing.json return_snapshot_default must be none, diff, or full");
247
272
  }
248
- const postStepReadyTimeoutSeconds = positiveNumber(
249
- browserOptions.post_step_ready_timeout_seconds_default,
250
- "jev_browser_mcp.browser.post_step_ready_timeout_seconds_default",
251
- );
252
- if (postStepReadyTimeoutSeconds > maxReadyTimeoutSeconds) {
253
- throw new JevBrowserError("config/ui-testing.json post-step readiness timeout exceeds its configured maximum");
273
+ if (!new Set(["minor", "moderate", "serious", "critical"]).has(browserOptions.accessibility_fail_on_impact_default)) {
274
+ throw new JevBrowserError("config/ui-testing.json accessibility_fail_on_impact_default must be minor, moderate, serious, or critical");
254
275
  }
276
+ const maxReadyTimeoutSeconds = positiveNumber(browserOptions.max_ready_timeout_seconds, "jev_browser_mcp.browser.max_ready_timeout_seconds");
277
+ const readyTimeoutSecondsDefault = positiveNumber(browserOptions.ready_timeout_seconds_default, "jev_browser_mcp.browser.ready_timeout_seconds_default");
278
+ const maxReadyStableMs = positiveNumber(browserOptions.max_ready_stable_ms, "jev_browser_mcp.browser.max_ready_stable_ms", true);
279
+ const readyStableMsDefault = positiveNumber(browserOptions.ready_stable_ms_default, "jev_browser_mcp.browser.ready_stable_ms_default", true);
280
+ if (readyTimeoutSecondsDefault > maxReadyTimeoutSeconds) {
281
+ throw new JevBrowserError("config/ui-testing.json ready timeout default exceeds its configured maximum");
282
+ }
283
+ if (readyStableMsDefault > maxReadyStableMs) {
284
+ throw new JevBrowserError("config/ui-testing.json stable snapshot default exceeds its configured maximum");
285
+ }
286
+ const postStepReadyTimeoutSeconds = positiveNumber(
287
+ browserOptions.post_step_ready_timeout_seconds_default,
288
+ "jev_browser_mcp.browser.post_step_ready_timeout_seconds_default",
289
+ );
290
+ if (postStepReadyTimeoutSeconds > maxReadyTimeoutSeconds) {
291
+ throw new JevBrowserError("config/ui-testing.json post-step readiness timeout exceeds its configured maximum");
292
+ }
255
293
 
256
294
  return Object.freeze({
257
295
  env,
@@ -261,15 +299,25 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
261
299
  profileDir: profileDirectory(profileTemplate, channel, env.JEV_BROWSER_PROFILE),
262
300
  maxFlowSteps: positiveNumber(document.browser.max_flow_steps, "browser.max_flow_steps", true),
263
301
  maxTextEntryChars: positiveNumber(document.browser.max_text_entry_chars, "browser.max_text_entry_chars", true),
264
- actionTimeoutMs: positiveNumber(browserOptions.max_action_timeout_seconds, "jev_browser_mcp.browser.max_action_timeout_seconds") * 1000,
265
- maxReadyTimeoutSeconds,
266
- maxReadyStableMs,
267
- postStepReadyTimeoutMs: postStepReadyTimeoutSeconds * 1000,
268
- maxStepTimeoutSeconds: positiveNumber(browserOptions.max_step_timeout_seconds, "jev_browser_mcp.browser.max_step_timeout_seconds"),
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),
271
- maxNetworkErrorBodyBytes: positiveNumber(browserOptions.max_network_error_body_bytes, "jev_browser_mcp.browser.max_network_error_body_bytes", true),
302
+ actionTimeoutMs: positiveNumber(browserOptions.max_action_timeout_seconds, "jev_browser_mcp.browser.max_action_timeout_seconds") * 1000,
303
+ mutationConfirmationTtlMs: positiveNumber(browserOptions.mutation_confirmation_ttl_seconds, "jev_browser_mcp.browser.mutation_confirmation_ttl_seconds") * 1000,
304
+ maxReadyTimeoutSeconds,
305
+ maxReadyStableMs,
306
+ postStepReadyTimeoutMs: postStepReadyTimeoutSeconds * 1000,
307
+ maxStepTimeoutSeconds: positiveNumber(browserOptions.max_step_timeout_seconds, "jev_browser_mcp.browser.max_step_timeout_seconds"),
308
+ keyDelayMs: positiveNumber(browserOptions.key_delay_ms_default, "jev_browser_mcp.browser.key_delay_ms_default", true),
309
+ visibilityPollMs: positiveNumber(browserOptions.visibility_poll_interval_ms_default, "jev_browser_mcp.browser.visibility_poll_interval_ms_default", true),
310
+ maxNetworkErrorBodyBytes: positiveNumber(browserOptions.max_network_error_body_bytes, "jev_browser_mcp.browser.max_network_error_body_bytes", true),
272
311
  maxNetworkErrorMessageChars: positiveNumber(browserOptions.max_network_error_message_chars, "jev_browser_mcp.browser.max_network_error_message_chars", true),
312
+ maxNetworkHistoryEvents: positiveNumber(browserOptions.max_network_history_events, "jev_browser_mcp.browser.max_network_history_events", true),
313
+ maxToolResponseBytes: positiveNumber(browserOptions.max_tool_response_bytes, "jev_browser_mcp.browser.max_tool_response_bytes", true),
314
+ maxViewportWidth: positiveNumber(browserOptions.max_viewport_width, "jev_browser_mcp.browser.max_viewport_width", true),
315
+ maxViewportHeight: positiveNumber(browserOptions.max_viewport_height, "jev_browser_mcp.browser.max_viewport_height", true),
316
+ accessibilityFailOnImpactDefault: browserOptions.accessibility_fail_on_impact_default,
317
+ recordVideoSize: Object.freeze({
318
+ width: positiveNumber(browserOptions.record_video_width, "jev_browser_mcp.browser.record_video_width", true),
319
+ height: positiveNumber(browserOptions.record_video_height, "jev_browser_mcp.browser.record_video_height", true),
320
+ }),
273
321
  maxUploadFiles: positiveNumber(browserOptions.max_upload_files, "jev_browser_mcp.browser.max_upload_files", true),
274
322
  maxUploadPathChars: positiveNumber(browserOptions.max_upload_path_chars, "jev_browser_mcp.browser.max_upload_path_chars", true),
275
323
  maxUploadFileBytes: positiveNumber(browserOptions.max_upload_file_bytes, "jev_browser_mcp.browser.max_upload_file_bytes", true),
@@ -284,21 +332,30 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
284
332
  defaults: Object.freeze({
285
333
  fastPath: booleanValue(browserOptions.fast_path_single_plan_default, "jev_browser_mcp.browser.fast_path_single_plan_default"),
286
334
  screenshotOnFailure: booleanValue(browserOptions.screenshot_on_failure_default, "jev_browser_mcp.browser.screenshot_on_failure_default"),
287
- traceOnFailure: booleanValue(browserOptions.trace_on_failure_default, "jev_browser_mcp.browser.trace_on_failure_default"),
335
+ traceOnFailure: booleanValue(browserOptions.trace_on_failure_default, "jev_browser_mcp.browser.trace_on_failure_default"),
336
+ traceOnSuccess: booleanValue(browserOptions.trace_on_success_default, "jev_browser_mcp.browser.trace_on_success_default"),
288
337
  captureConsoleErrors: booleanValue(browserOptions.capture_console_errors_default, "jev_browser_mcp.browser.capture_console_errors_default"),
289
- captureNetworkErrors: booleanValue(browserOptions.capture_network_errors_default, "jev_browser_mcp.browser.capture_network_errors_default"),
290
- captureNetworkErrorBodies: booleanValue(browserOptions.capture_network_error_bodies_default, "jev_browser_mcp.browser.capture_network_error_bodies_default"),
291
- blockTrackers: booleanValue(browserOptions.block_trackers_default, "jev_browser_mcp.browser.block_trackers_default"),
292
- readyNetworkIdle: booleanValue(browserOptions.ready_network_idle_default, "jev_browser_mcp.browser.ready_network_idle_default"),
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"),
296
- readyTimeoutSeconds: readyTimeoutSecondsDefault,
297
- readyStableMs: readyStableMsDefault,
338
+ captureNetworkErrors: booleanValue(browserOptions.capture_network_errors_default, "jev_browser_mcp.browser.capture_network_errors_default"),
339
+ captureNetworkErrorBodies: booleanValue(browserOptions.capture_network_error_bodies_default, "jev_browser_mcp.browser.capture_network_error_bodies_default"),
340
+ blockTrackers: booleanValue(browserOptions.block_trackers_default, "jev_browser_mcp.browser.block_trackers_default"),
341
+ blockFonts: booleanValue(browserOptions.block_fonts_default, "jev_browser_mcp.browser.block_fonts_default"),
342
+ localOnly: booleanValue(browserOptions.local_only_default, "jev_browser_mcp.browser.local_only_default"),
343
+ autoAngularIdle: booleanValue(browserOptions.auto_angular_idle_default, "jev_browser_mcp.browser.auto_angular_idle_default"),
344
+ returnSnapshot: browserOptions.return_snapshot_default,
345
+ readyNetworkIdle: booleanValue(browserOptions.ready_network_idle_default, "jev_browser_mcp.browser.ready_network_idle_default"),
346
+ reusePage: booleanValue(browserOptions.reuse_page_default, "jev_browser_mcp.browser.reuse_page_default"),
347
+ stopOnExpected: booleanValue(browserOptions.stop_on_expected_default, "jev_browser_mcp.browser.stop_on_expected_default"),
348
+ snapshotIncludeHidden: booleanValue(browserOptions.snapshot_include_hidden_default, "jev_browser_mcp.browser.snapshot_include_hidden_default"),
349
+ readyTimeoutSeconds: readyTimeoutSecondsDefault,
350
+ readyStableMs: readyStableMsDefault,
298
351
  snapshotScope,
299
352
  }),
300
353
  trackerHostSuffixes: Object.freeze(trackerHostSuffixes),
301
354
  blockedResourceTypes: Object.freeze(blockedResourceTypes),
355
+ busySelectorsDefault: Object.freeze(busySelectorsDefault),
356
+ loginUrlContainsDefault: Object.freeze(loginUrlContainsDefault),
357
+ loginTextDefault: Object.freeze(loginTextDefault),
358
+ maxBusySelectors: positiveNumber(browserOptions.max_busy_selectors, "jev_browser_mcp.browser.max_busy_selectors", true),
302
359
  }),
303
360
  jev: Object.freeze({
304
361
  providerUrl,