@hs-web-team/eslint-config-node 3.2.0 → 3.3.0

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 CHANGED
@@ -10,6 +10,7 @@ This package provides ESLint rules and configurations for **Hubspot Marketing We
10
10
  - [Browser/React Setup](#browserreact-setup)
11
11
  - [Stylelint Setup](#stylelint-setup)
12
12
  - [Cypress Setup](#cypress-setup)
13
+ - [Accessibility Testing](#accessibility-testing-optional)
13
14
  - [Where to use it](#where-to-use-it)
14
15
  - [Using the Prettier Scripts](#using-the-prettier-scripts)
15
16
  <!-- index-end -->
@@ -123,6 +124,39 @@ This package provides shared Cypress configuration for E2E testing.
123
124
 
124
125
  For detailed Cypress configuration and migration documentation, see [examples/cypress-usage.md](./examples/cypress-usage.md).
125
126
 
127
+ ## Accessibility Testing (optional)
128
+
129
+ This package includes a shared accessibility testing setup using [cypress-axe](https://github.com/component-driven/cypress-axe). Projects can opt in with a single import — no need to install `cypress-axe` or `axe-core` directly.
130
+
131
+ 1. Add to `cypress/support/e2e.ts`
132
+
133
+ ```ts
134
+ import '@hs-web-team/eslint-config-node/cypress';
135
+ ```
136
+
137
+ This registers `cy.injectAxe()`, `cy.checkA11y()`, and `cy.checkAccessibility()`.
138
+
139
+ 2. Call `cy.injectAxe()` in your project's navigation command, after the page visit e.g.
140
+
141
+ ```ts
142
+ // cypress/support/commands.ts
143
+ cy.visitPageIfUrlChanged(urlPath).then(() => {
144
+ cy.injectAxe();
145
+ });
146
+ ```
147
+
148
+ 3. Use `cy.checkAccessibility()` in your tests e.g.
149
+
150
+ ```ts
151
+ // Check the whole page
152
+ cy.checkAccessibility();
153
+
154
+ // Scope to a specific component
155
+ cy.checkAccessibility('.csol-accordion');
156
+ ```
157
+
158
+ `cy.checkAccessibility()` adds the `high-contrast` class to `body`, runs WCAG 2.2 Level AA rules only, and logs each violation with its id, help text, impact, element targets, and help URL. TypeScript types are included — no `tsconfig.json` changes required.
159
+
126
160
  ## Where to use it
127
161
 
128
162
  This package provides multiple configurations:
@@ -131,6 +165,7 @@ This package provides multiple configurations:
131
165
  - **Browser configuration** (`/browser` export): For browser-based projects including React applications
132
166
  - **Stylelint configuration** (`.stylelintrc.json` export): For SCSS/CSS linting
133
167
  - **Cypress configuration** (`cypress.config` export): For E2E testing with Cypress
168
+ - **Accessibility testing** (`/cypress` export): Opt-in cypress-axe setup with WCAG 2.2 AA checks
134
169
  - **Prettier configuration** (`.prettierrc.json` export): For code formatting
135
170
 
136
171
  Choose the appropriate configurations based on your project needs.
@@ -0,0 +1,7 @@
1
+ /// <reference types="cypress" />
2
+
3
+ declare namespace Cypress {
4
+ interface Chainable {
5
+ checkAccessibility(context?: string | Node | JQueryWithSelector): Chainable<void>;
6
+ }
7
+ }
@@ -0,0 +1,34 @@
1
+ import 'cypress-axe';
2
+
3
+ const WCAG_RULE_SETS = ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'];
4
+
5
+ function logViolations(violations) {
6
+ violations.forEach(({ id, help, impact, nodes, helpUrl }) => {
7
+ const targets = nodes.map(({ target }) => target.join(', ')).join('\n ');
8
+ console.error(`[a11y][${impact}] ${id}: ${help}\n targets: ${targets}\n ${helpUrl}`);
9
+ Cypress.log({
10
+ name: 'a11y violation',
11
+ message: `[${impact}] ${id}: ${help}`,
12
+ consoleProps: () => ({ id, help, impact, targets, helpUrl }),
13
+ });
14
+ });
15
+ }
16
+
17
+ Cypress.Commands.add('checkAccessibility', (context) => {
18
+ cy.get('body').then(($body) => {
19
+ if (!$body.hasClass('high-contrast')) {
20
+ $body.addClass('high-contrast');
21
+ }
22
+ });
23
+
24
+ cy.checkA11y(
25
+ context,
26
+ {
27
+ runOnly: {
28
+ type: 'tag',
29
+ values: WCAG_RULE_SETS,
30
+ },
31
+ },
32
+ logViolations,
33
+ );
34
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hs-web-team/eslint-config-node",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "HubSpot Marketing WebTeam shared configurations for ESLint, Prettier, Stylelint, and Cypress",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -12,12 +12,19 @@
12
12
  "./cypress.config": {
13
13
  "types": "./cypress.config.d.ts",
14
14
  "require": "./cypress.config.cjs"
15
+ },
16
+ "./cypress": {
17
+ "types": "./cypress/index.d.ts",
18
+ "default": "./cypress/index.js"
15
19
  }
16
20
  },
17
21
  "typesVersions": {
18
22
  "*": {
19
23
  "cypress.config": [
20
24
  "./cypress.config.d.ts"
25
+ ],
26
+ "cypress": [
27
+ "./cypress/index.d.ts"
21
28
  ]
22
29
  }
23
30
  },
@@ -55,6 +62,9 @@
55
62
  "@eslint/js": "^9.39.1",
56
63
  "@typescript-eslint/eslint-plugin": "^8.46.3",
57
64
  "@typescript-eslint/parser": "^8.46.3",
65
+ "axe-core": "^4.11.3",
66
+ "cypress-axe": "^1.7.0",
67
+ "esbuild": "^0.27.2",
58
68
  "eslint": "^9.39.2",
59
69
  "eslint-formatter-checkstyle": "^9.0.1",
60
70
  "eslint-plugin-jsx-a11y": "^6.10.2",
@@ -62,10 +72,9 @@
62
72
  "eslint-plugin-react-hooks": "^7.0.1",
63
73
  "globals": "^17.3.0",
64
74
  "jiti": "^2.6.1",
75
+ "js-yaml": "^4.1.1",
65
76
  "prettier": "^3.8.1",
66
- "typescript-eslint": "^8.54.0",
67
- "esbuild": "^0.27.2",
68
- "js-yaml": "^4.1.1"
77
+ "typescript-eslint": "^8.54.0"
69
78
  },
70
79
  "peerDependencies": {
71
80
  "@badeball/cypress-cucumber-preprocessor": "^24.0.0",