@diegosouzacdv/jev-browser-mcp 0.5.0 → 0.6.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.
@@ -16,23 +16,24 @@ 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",
34
- "max_network_error_body_bytes",
35
- "max_network_error_message_chars",
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",
35
+ "max_network_error_body_bytes",
36
+ "max_network_error_message_chars",
36
37
  "max_upload_files",
37
38
  "max_upload_path_chars",
38
39
  "max_upload_file_bytes",
@@ -51,6 +52,14 @@ const CONFIG_KEYS = {
51
52
  "capture_console_errors_default",
52
53
  "capture_network_errors_default",
53
54
  "block_trackers_default",
55
+ "block_fonts_default",
56
+ "local_only_default",
57
+ "auto_angular_idle_default",
58
+ "return_snapshot_default",
59
+ "busy_selectors_default",
60
+ "login_url_contains_default",
61
+ "login_text_default",
62
+ "max_busy_selectors",
54
63
  "snapshot_scope_default",
55
64
  "tracker_host_suffixes",
56
65
  "blocked_resource_types",
@@ -221,7 +230,7 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
221
230
  const uploadRoot = configuredUploadRoot
222
231
  ? configuredDirectory(configuredUploadRoot, `environment ${uploadRootEnv}`)
223
232
  : null;
224
- const snapshotScope = browserOptions.snapshot_scope_default;
233
+ const snapshotScope = browserOptions.snapshot_scope_default;
225
234
  if (!new Set(["body", "main", "dialog"]).has(snapshotScope)) {
226
235
  throw new JevBrowserError("config/ui-testing.json jev_browser_mcp.browser.snapshot_scope_default must be body, main, or dialog");
227
236
  }
@@ -230,28 +239,46 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
230
239
  "jev_browser_mcp.browser.tracker_host_suffixes",
231
240
  (host) => /^[a-z0-9.-]+$/i.test(host) && !host.startsWith(".") && !host.endsWith("."),
232
241
  );
233
- const blockedResourceTypes = stringList(
242
+ const blockedResourceTypes = stringList(
234
243
  browserOptions.blocked_resource_types,
235
244
  "jev_browser_mcp.browser.blocked_resource_types",
236
245
  (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");
247
- }
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");
254
- }
246
+ );
247
+ const busySelectorsDefault = stringList(
248
+ browserOptions.busy_selectors_default,
249
+ "jev_browser_mcp.browser.busy_selectors_default",
250
+ );
251
+ if (busySelectorsDefault.length > positiveNumber(browserOptions.max_busy_selectors, "jev_browser_mcp.browser.max_busy_selectors", true)) {
252
+ throw new JevBrowserError("config/ui-testing.json busy_selectors_default exceeds max_busy_selectors");
253
+ }
254
+ const loginUrlContainsDefault = stringList(
255
+ browserOptions.login_url_contains_default,
256
+ "jev_browser_mcp.browser.login_url_contains_default",
257
+ );
258
+ const loginTextDefault = stringList(
259
+ browserOptions.login_text_default,
260
+ "jev_browser_mcp.browser.login_text_default",
261
+ );
262
+ if (!new Set(["none", "diff", "full"]).has(browserOptions.return_snapshot_default)) {
263
+ throw new JevBrowserError("config/ui-testing.json return_snapshot_default must be none, diff, or full");
264
+ }
265
+ const maxReadyTimeoutSeconds = positiveNumber(browserOptions.max_ready_timeout_seconds, "jev_browser_mcp.browser.max_ready_timeout_seconds");
266
+ const readyTimeoutSecondsDefault = positiveNumber(browserOptions.ready_timeout_seconds_default, "jev_browser_mcp.browser.ready_timeout_seconds_default");
267
+ const maxReadyStableMs = positiveNumber(browserOptions.max_ready_stable_ms, "jev_browser_mcp.browser.max_ready_stable_ms", true);
268
+ const readyStableMsDefault = positiveNumber(browserOptions.ready_stable_ms_default, "jev_browser_mcp.browser.ready_stable_ms_default", true);
269
+ if (readyTimeoutSecondsDefault > maxReadyTimeoutSeconds) {
270
+ throw new JevBrowserError("config/ui-testing.json ready timeout default exceeds its configured maximum");
271
+ }
272
+ if (readyStableMsDefault > maxReadyStableMs) {
273
+ throw new JevBrowserError("config/ui-testing.json stable snapshot default exceeds its configured maximum");
274
+ }
275
+ const postStepReadyTimeoutSeconds = positiveNumber(
276
+ browserOptions.post_step_ready_timeout_seconds_default,
277
+ "jev_browser_mcp.browser.post_step_ready_timeout_seconds_default",
278
+ );
279
+ if (postStepReadyTimeoutSeconds > maxReadyTimeoutSeconds) {
280
+ throw new JevBrowserError("config/ui-testing.json post-step readiness timeout exceeds its configured maximum");
281
+ }
255
282
 
256
283
  return Object.freeze({
257
284
  env,
@@ -261,15 +288,16 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
261
288
  profileDir: profileDirectory(profileTemplate, channel, env.JEV_BROWSER_PROFILE),
262
289
  maxFlowSteps: positiveNumber(document.browser.max_flow_steps, "browser.max_flow_steps", true),
263
290
  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),
272
- maxNetworkErrorMessageChars: positiveNumber(browserOptions.max_network_error_message_chars, "jev_browser_mcp.browser.max_network_error_message_chars", true),
291
+ actionTimeoutMs: positiveNumber(browserOptions.max_action_timeout_seconds, "jev_browser_mcp.browser.max_action_timeout_seconds") * 1000,
292
+ mutationConfirmationTtlMs: positiveNumber(browserOptions.mutation_confirmation_ttl_seconds, "jev_browser_mcp.browser.mutation_confirmation_ttl_seconds") * 1000,
293
+ maxReadyTimeoutSeconds,
294
+ maxReadyStableMs,
295
+ postStepReadyTimeoutMs: postStepReadyTimeoutSeconds * 1000,
296
+ maxStepTimeoutSeconds: positiveNumber(browserOptions.max_step_timeout_seconds, "jev_browser_mcp.browser.max_step_timeout_seconds"),
297
+ keyDelayMs: positiveNumber(browserOptions.key_delay_ms_default, "jev_browser_mcp.browser.key_delay_ms_default", true),
298
+ visibilityPollMs: positiveNumber(browserOptions.visibility_poll_interval_ms_default, "jev_browser_mcp.browser.visibility_poll_interval_ms_default", true),
299
+ maxNetworkErrorBodyBytes: positiveNumber(browserOptions.max_network_error_body_bytes, "jev_browser_mcp.browser.max_network_error_body_bytes", true),
300
+ maxNetworkErrorMessageChars: positiveNumber(browserOptions.max_network_error_message_chars, "jev_browser_mcp.browser.max_network_error_message_chars", true),
273
301
  maxUploadFiles: positiveNumber(browserOptions.max_upload_files, "jev_browser_mcp.browser.max_upload_files", true),
274
302
  maxUploadPathChars: positiveNumber(browserOptions.max_upload_path_chars, "jev_browser_mcp.browser.max_upload_path_chars", true),
275
303
  maxUploadFileBytes: positiveNumber(browserOptions.max_upload_file_bytes, "jev_browser_mcp.browser.max_upload_file_bytes", true),
@@ -286,19 +314,27 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
286
314
  screenshotOnFailure: booleanValue(browserOptions.screenshot_on_failure_default, "jev_browser_mcp.browser.screenshot_on_failure_default"),
287
315
  traceOnFailure: booleanValue(browserOptions.trace_on_failure_default, "jev_browser_mcp.browser.trace_on_failure_default"),
288
316
  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,
317
+ captureNetworkErrors: booleanValue(browserOptions.capture_network_errors_default, "jev_browser_mcp.browser.capture_network_errors_default"),
318
+ captureNetworkErrorBodies: booleanValue(browserOptions.capture_network_error_bodies_default, "jev_browser_mcp.browser.capture_network_error_bodies_default"),
319
+ blockTrackers: booleanValue(browserOptions.block_trackers_default, "jev_browser_mcp.browser.block_trackers_default"),
320
+ blockFonts: booleanValue(browserOptions.block_fonts_default, "jev_browser_mcp.browser.block_fonts_default"),
321
+ localOnly: booleanValue(browserOptions.local_only_default, "jev_browser_mcp.browser.local_only_default"),
322
+ autoAngularIdle: booleanValue(browserOptions.auto_angular_idle_default, "jev_browser_mcp.browser.auto_angular_idle_default"),
323
+ returnSnapshot: browserOptions.return_snapshot_default,
324
+ readyNetworkIdle: booleanValue(browserOptions.ready_network_idle_default, "jev_browser_mcp.browser.ready_network_idle_default"),
325
+ reusePage: booleanValue(browserOptions.reuse_page_default, "jev_browser_mcp.browser.reuse_page_default"),
326
+ stopOnExpected: booleanValue(browserOptions.stop_on_expected_default, "jev_browser_mcp.browser.stop_on_expected_default"),
327
+ snapshotIncludeHidden: booleanValue(browserOptions.snapshot_include_hidden_default, "jev_browser_mcp.browser.snapshot_include_hidden_default"),
328
+ readyTimeoutSeconds: readyTimeoutSecondsDefault,
329
+ readyStableMs: readyStableMsDefault,
298
330
  snapshotScope,
299
331
  }),
300
332
  trackerHostSuffixes: Object.freeze(trackerHostSuffixes),
301
333
  blockedResourceTypes: Object.freeze(blockedResourceTypes),
334
+ busySelectorsDefault: Object.freeze(busySelectorsDefault),
335
+ loginUrlContainsDefault: Object.freeze(loginUrlContainsDefault),
336
+ loginTextDefault: Object.freeze(loginTextDefault),
337
+ maxBusySelectors: positiveNumber(browserOptions.max_busy_selectors, "jev_browser_mcp.browser.max_busy_selectors", true),
302
338
  }),
303
339
  jev: Object.freeze({
304
340
  providerUrl,