@diegosouzacdv/jev-browser-mcp 0.6.1 → 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.
@@ -4,7 +4,7 @@ export const ACCESSIBILITY_STANDARDS = Object.freeze({
4
4
  wcag2aa: Object.freeze(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"]),
5
5
  });
6
6
 
7
- export async function runAccessibilityAudit(page, standard, settings) {
7
+ export async function runAccessibilityAudit(page, standard, settings, { scope, failOnImpact } = {}) {
8
8
  const tags = ACCESSIBILITY_STANDARDS[standard];
9
9
  if (!tags) throw new JevBrowserError("audit_accessibility standard must be wcag2aa");
10
10
 
@@ -15,17 +15,26 @@ export async function runAccessibilityAudit(page, standard, settings) {
15
15
  throw new JevBrowserError("accessibility auditing requires the installed @axe-core/playwright dependency");
16
16
  }
17
17
 
18
- let results;
19
- try {
20
- results = await new AxeBuilder({ page }).withTags([...tags]).analyze();
18
+ let results;
19
+ try {
20
+ let audit = new AxeBuilder({ page }).withTags([...tags]);
21
+ if (scope) audit = audit.include(scope);
22
+ results = await audit.analyze();
21
23
  } catch {
22
24
  throw new JevBrowserError("axe-core could not complete the accessibility audit");
23
25
  }
24
- const violations = Array.isArray(results?.violations) ? results.violations : [];
25
- const incomplete = Array.isArray(results?.incomplete) ? results.incomplete : [];
26
- return {
27
- standard,
28
- violations_count: violations.length,
26
+ const violations = Array.isArray(results?.violations) ? results.violations : [];
27
+ const incomplete = Array.isArray(results?.incomplete) ? results.incomplete : [];
28
+ const impactOrder = ["minor", "moderate", "serious", "critical"];
29
+ const threshold = impactOrder.indexOf(failOnImpact || settings.browser.accessibilityFailOnImpactDefault);
30
+ if (threshold < 0) throw new JevBrowserError("accessibility fail_on_impact must be minor, moderate, serious, or critical");
31
+ const blockingViolations = violations.filter((violation) => impactOrder.indexOf(violation.impact) >= threshold);
32
+ return {
33
+ standard,
34
+ ...(scope ? { scope } : {}),
35
+ fail_on_impact: impactOrder[threshold],
36
+ violations_count: violations.length,
37
+ blocking_violations_count: blockingViolations.length,
29
38
  violations_truncated: violations.length > settings.jev.maxAccessibilityViolations,
30
39
  violations: violations.slice(0, settings.jev.maxAccessibilityViolations).map((violation) => ({
31
40
  id: String(violation.id || "unknown").slice(0, 100),
@@ -32,8 +32,15 @@ const CONFIG_KEYS = {
32
32
  "snapshot_include_hidden_default",
33
33
  "visibility_poll_interval_ms_default",
34
34
  "capture_network_error_bodies_default",
35
- "max_network_error_body_bytes",
36
- "max_network_error_message_chars",
35
+ "max_network_error_body_bytes",
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",
37
44
  "max_upload_files",
38
45
  "max_upload_path_chars",
39
46
  "max_upload_file_bytes",
@@ -48,7 +55,8 @@ const CONFIG_KEYS = {
48
55
  "max_frame_snapshots",
49
56
  "fast_path_single_plan_default",
50
57
  "screenshot_on_failure_default",
51
- "trace_on_failure_default",
58
+ "trace_on_failure_default",
59
+ "trace_on_success_default",
52
60
  "capture_console_errors_default",
53
61
  "capture_network_errors_default",
54
62
  "block_trackers_default",
@@ -259,9 +267,12 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
259
267
  browserOptions.login_text_default,
260
268
  "jev_browser_mcp.browser.login_text_default",
261
269
  );
262
- if (!new Set(["none", "diff", "full"]).has(browserOptions.return_snapshot_default)) {
270
+ if (!new Set(["none", "diff", "full"]).has(browserOptions.return_snapshot_default)) {
263
271
  throw new JevBrowserError("config/ui-testing.json return_snapshot_default must be none, diff, or full");
264
- }
272
+ }
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");
275
+ }
265
276
  const maxReadyTimeoutSeconds = positiveNumber(browserOptions.max_ready_timeout_seconds, "jev_browser_mcp.browser.max_ready_timeout_seconds");
266
277
  const readyTimeoutSecondsDefault = positiveNumber(browserOptions.ready_timeout_seconds_default, "jev_browser_mcp.browser.ready_timeout_seconds_default");
267
278
  const maxReadyStableMs = positiveNumber(browserOptions.max_ready_stable_ms, "jev_browser_mcp.browser.max_ready_stable_ms", true);
@@ -297,7 +308,16 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
297
308
  keyDelayMs: positiveNumber(browserOptions.key_delay_ms_default, "jev_browser_mcp.browser.key_delay_ms_default", true),
298
309
  visibilityPollMs: positiveNumber(browserOptions.visibility_poll_interval_ms_default, "jev_browser_mcp.browser.visibility_poll_interval_ms_default", true),
299
310
  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),
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
+ }),
301
321
  maxUploadFiles: positiveNumber(browserOptions.max_upload_files, "jev_browser_mcp.browser.max_upload_files", true),
302
322
  maxUploadPathChars: positiveNumber(browserOptions.max_upload_path_chars, "jev_browser_mcp.browser.max_upload_path_chars", true),
303
323
  maxUploadFileBytes: positiveNumber(browserOptions.max_upload_file_bytes, "jev_browser_mcp.browser.max_upload_file_bytes", true),
@@ -312,7 +332,8 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
312
332
  defaults: Object.freeze({
313
333
  fastPath: booleanValue(browserOptions.fast_path_single_plan_default, "jev_browser_mcp.browser.fast_path_single_plan_default"),
314
334
  screenshotOnFailure: booleanValue(browserOptions.screenshot_on_failure_default, "jev_browser_mcp.browser.screenshot_on_failure_default"),
315
- 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"),
316
337
  captureConsoleErrors: booleanValue(browserOptions.capture_console_errors_default, "jev_browser_mcp.browser.capture_console_errors_default"),
317
338
  captureNetworkErrors: booleanValue(browserOptions.capture_network_errors_default, "jev_browser_mcp.browser.capture_network_errors_default"),
318
339
  captureNetworkErrorBodies: booleanValue(browserOptions.capture_network_error_bodies_default, "jev_browser_mcp.browser.capture_network_error_bodies_default"),