snap-ally 0.0.2 β 0.0.4
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 +44 -43
- package/dist/A11yScanner.d.ts +2 -0
- package/dist/A11yScanner.js +45 -9
- package/dist/SnapAllyReporter.d.ts +1 -0
- package/dist/SnapAllyReporter.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# snap-ally
|
|
1
|
+
# snap-ally πΈβΏ
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/snap-ally)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -7,17 +7,13 @@ A powerful, developer-friendly Playwright reporter for **Accessibility testing**
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## πΊ Demo
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
<video src="video.webm" width="800" controls aria-label="Snap-Ally accessibility reporter demonstration video showing HTML reports and visual overlays">
|
|
14
|
-
Your browser does not support the video tag. You can <a href="video.webm">download the video</a> to view it.
|
|
15
|
-
</video>
|
|
16
|
-
</div>
|
|
12
|
+
**[βΆοΈ Watch the Demo Video](https://www.loom.com/share/853c04f1f76242a699e8f82e54733007)**
|
|
17
13
|
|
|
18
14
|
---
|
|
19
15
|
|
|
20
|
-
##
|
|
16
|
+
## β¨ Features
|
|
21
17
|
|
|
22
18
|
- **Beautiful HTML Reporting**: Comprehensive summary and detail pages.
|
|
23
19
|
- **Visual Overlays**: Highlights violations directly on the page in screenshots.
|
|
@@ -28,7 +24,7 @@ A powerful, developer-friendly Playwright reporter for **Accessibility testing**
|
|
|
28
24
|
|
|
29
25
|
---
|
|
30
26
|
|
|
31
|
-
##
|
|
27
|
+
## π Installation
|
|
32
28
|
|
|
33
29
|
```bash
|
|
34
30
|
npm install snap-ally --save-dev
|
|
@@ -36,30 +32,33 @@ npm install snap-ally --save-dev
|
|
|
36
32
|
|
|
37
33
|
---
|
|
38
34
|
|
|
39
|
-
##
|
|
35
|
+
## π οΈ Setup
|
|
40
36
|
|
|
41
37
|
Add `snap-ally` to your `playwright.config.ts`:
|
|
42
38
|
|
|
43
39
|
```typescript
|
|
44
|
-
import { defineConfig } from
|
|
40
|
+
import { defineConfig } from "@playwright/test";
|
|
45
41
|
|
|
46
42
|
export default defineConfig({
|
|
47
43
|
reporter: [
|
|
48
|
-
[
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
[
|
|
45
|
+
"snap-ally",
|
|
46
|
+
{
|
|
47
|
+
outputFolder: "a11y-report",
|
|
48
|
+
// Optional: Visual Customization
|
|
49
|
+
colors: {
|
|
50
|
+
critical: "#dc2626",
|
|
51
|
+
serious: "#ea580c",
|
|
52
|
+
moderate: "#f59e0b",
|
|
53
|
+
minor: "#0ea5e9",
|
|
54
|
+
},
|
|
55
|
+
// Optional: Azure DevOps Integration
|
|
56
|
+
ado: {
|
|
57
|
+
organization: "your-org",
|
|
58
|
+
project: "your-project",
|
|
59
|
+
},
|
|
56
60
|
},
|
|
57
|
-
|
|
58
|
-
ado: {
|
|
59
|
-
organization: 'your-org',
|
|
60
|
-
project: 'your-project'
|
|
61
|
-
}
|
|
62
|
-
}]
|
|
61
|
+
],
|
|
63
62
|
],
|
|
64
63
|
});
|
|
65
64
|
```
|
|
@@ -71,23 +70,24 @@ export default defineConfig({
|
|
|
71
70
|
Import and use `scanA11y` within your Playwright tests:
|
|
72
71
|
|
|
73
72
|
```typescript
|
|
74
|
-
import { test } from
|
|
75
|
-
import { scanA11y } from
|
|
73
|
+
import { test } from "@playwright/test";
|
|
74
|
+
import { scanA11y } from "snap-ally";
|
|
75
|
+
|
|
76
|
+
test("verify page accessibility", async ({ page }, testInfo) => {
|
|
77
|
+
await page.goto("https://example.com");
|
|
76
78
|
|
|
77
|
-
test('verify page accessibility', async ({ page }, testInfo) => {
|
|
78
|
-
await page.goto('https://example.com');
|
|
79
|
-
|
|
80
79
|
// Basic scan
|
|
81
80
|
await scanA11y(page, testInfo);
|
|
82
81
|
|
|
83
82
|
// Advanced scan with configuration
|
|
84
83
|
await scanA11y(page, testInfo, {
|
|
84
|
+
verbose: true, // Log results to terminal
|
|
85
|
+
consoleLog: true, // Log results to browser console
|
|
86
|
+
pageKey: 'Homepage', // Custom name for the report file
|
|
87
|
+
tags: ['wcag2a', 'wcag2aa'],
|
|
85
88
|
rules: {
|
|
86
|
-
'color-contrast': { enabled: false },
|
|
87
|
-
}
|
|
88
|
-
tags: ['wcag2a', 'wcag2aa'], // Focus on specific WCAG levels
|
|
89
|
-
verbose: true,
|
|
90
|
-
pageKey: 'Homepage' // Custom name for the report file
|
|
89
|
+
'color-contrast': { enabled: false },
|
|
90
|
+
}
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
```
|
|
@@ -98,20 +98,21 @@ test('verify page accessibility', async ({ page }, testInfo) => {
|
|
|
98
98
|
|
|
99
99
|
### Reporter Options (in `playwright.config.ts`)
|
|
100
100
|
|
|
101
|
-
| Option
|
|
102
|
-
|
|
|
103
|
-
| `outputFolder`
|
|
104
|
-
| `colors`
|
|
105
|
-
| `ado`
|
|
106
|
-
| `ado.organization` | `string` | Your Azure DevOps organization name.
|
|
107
|
-
| `ado.project`
|
|
101
|
+
| Option | Type | Description |
|
|
102
|
+
| ------------------ | -------- | --------------------------------------------------------------- |
|
|
103
|
+
| `outputFolder` | `string` | Where to save the reports. Defaults to `steps-report`. |
|
|
104
|
+
| `colors` | `object` | Customize severity colors (critical, serious, moderate, minor). |
|
|
105
|
+
| `ado` | `object` | Azure DevOps configuration for deep linking. |
|
|
106
|
+
| `ado.organization` | `string` | Your Azure DevOps organization name. |
|
|
107
|
+
| `ado.project` | `string` | Your Azure DevOps project name. |
|
|
108
108
|
|
|
109
109
|
### `scanA11y` Options
|
|
110
110
|
|
|
111
111
|
| Option | Type | Description |
|
|
112
112
|
| --- | --- | --- |
|
|
113
113
|
| `include` | `string` | CSS selector to limit the scan to a specific element. |
|
|
114
|
-
| `verbose` | `boolean` |
|
|
114
|
+
| `verbose` | `boolean` | **Terminal Logs**: Print violations to terminal. Defaults to `true`. |
|
|
115
|
+
| `consoleLog` | `boolean` | **Browser Logs**: Print violations to browser console. Defaults to `true`. |
|
|
115
116
|
| `rules` | `object` | Axe-core rule configuration. |
|
|
116
117
|
| `tags` | `string[]` | List of Axe-core tags to run (e.g., `['wcag2aa']`). |
|
|
117
118
|
| `pageKey` | `string` | Custom identifier for the report file name. |
|
package/dist/A11yScanner.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface A11yScannerOptions {
|
|
|
16
16
|
tags?: string[];
|
|
17
17
|
/** Any other Axe-core options to pass to the builder. */
|
|
18
18
|
axeOptions?: Record<string, unknown>;
|
|
19
|
+
/** Custom identifier for the report file name. */
|
|
20
|
+
pageKey?: string;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Performs an accessibility audit using Axe and Lighthouse.
|
package/dist/A11yScanner.js
CHANGED
|
@@ -9,13 +9,38 @@ const playwright_1 = __importDefault(require("@axe-core/playwright"));
|
|
|
9
9
|
const test_1 = require("@playwright/test");
|
|
10
10
|
const A11yAuditOverlay_1 = require("./A11yAuditOverlay");
|
|
11
11
|
const models_1 = require("./models");
|
|
12
|
+
/**
|
|
13
|
+
* Sanitizes a string to be safe for use in file paths and prevents path traversal attacks.
|
|
14
|
+
* Removes or replaces dangerous characters and path separators.
|
|
15
|
+
*/
|
|
16
|
+
function sanitizePageKey(input) {
|
|
17
|
+
return input
|
|
18
|
+
// Remove protocol
|
|
19
|
+
.replace(/^https?:\/\//, '')
|
|
20
|
+
// Remove or replace path separators and dangerous characters
|
|
21
|
+
.replace(/[\/\\:*?"<>|]/g, '-')
|
|
22
|
+
// Remove any remaining path traversal attempts
|
|
23
|
+
.replace(/\.\./g, '')
|
|
24
|
+
// Replace multiple consecutive dashes with a single dash
|
|
25
|
+
.replace(/-+/g, '-')
|
|
26
|
+
// Remove leading/trailing dashes
|
|
27
|
+
.replace(/^-+|-+$/g, '')
|
|
28
|
+
// Convert to lowercase for consistency
|
|
29
|
+
.toLowerCase()
|
|
30
|
+
// Limit length to prevent filesystem issues
|
|
31
|
+
.substring(0, 200);
|
|
32
|
+
}
|
|
12
33
|
/**
|
|
13
34
|
* Performs an accessibility audit using Axe and Lighthouse.
|
|
14
35
|
*/
|
|
15
36
|
async function scanA11y(page, testInfo, options = {}) {
|
|
16
|
-
var _a;
|
|
17
|
-
const
|
|
18
|
-
const
|
|
37
|
+
var _a, _b;
|
|
38
|
+
const showTerminal = (_a = options.verbose) !== null && _a !== void 0 ? _a : true;
|
|
39
|
+
const showBrowser = (_b = options.consoleLog) !== null && _b !== void 0 ? _b : true;
|
|
40
|
+
// Sanitize pageKey to prevent path traversal attacks
|
|
41
|
+
const rawPageKey = options.pageKey || page.url();
|
|
42
|
+
const pageKey = sanitizePageKey(rawPageKey);
|
|
43
|
+
const overlay = new A11yAuditOverlay_1.A11yAuditOverlay(page, pageKey);
|
|
19
44
|
// Configure Axe
|
|
20
45
|
let axeBuilder = new playwright_1.default({ page });
|
|
21
46
|
const target = options.include || options.box;
|
|
@@ -39,11 +64,22 @@ async function scanA11y(page, testInfo, options = {}) {
|
|
|
39
64
|
}
|
|
40
65
|
const axeResults = await axeBuilder.analyze();
|
|
41
66
|
const violationCount = axeResults.violations.length;
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
67
|
+
if ((showTerminal || showBrowser) && violationCount > 0) {
|
|
68
|
+
const mainMsg = `[A11yScanner] Violations found: ${violationCount}`;
|
|
69
|
+
// Prepare all detail messages
|
|
70
|
+
const detailMessages = axeResults.violations.map((v, i) => ` ${i + 1}. ${v.id} [${v.impact}] - ${v.help}`);
|
|
71
|
+
// Log to terminal
|
|
72
|
+
if (showTerminal) {
|
|
73
|
+
console.log(`\n${mainMsg}`);
|
|
74
|
+
detailMessages.forEach(msg => console.log(msg));
|
|
75
|
+
}
|
|
76
|
+
// Batch log to Browser Console in a single evaluate call
|
|
77
|
+
if (showBrowser) {
|
|
78
|
+
await page.evaluate(([mainMsg, details]) => {
|
|
79
|
+
console.log(`%c ${mainMsg}`, 'color: #ea580c; font-weight: bold; font-size: 12px;');
|
|
80
|
+
details.forEach((msg) => console.log(msg));
|
|
81
|
+
}, [mainMsg, detailMessages]);
|
|
82
|
+
}
|
|
47
83
|
}
|
|
48
84
|
// Fail the test if violations found (softly)
|
|
49
85
|
test_1.expect.soft(violationCount, `Accessibility audit failed with ${violationCount} violations.`).toBe(0);
|
|
@@ -106,7 +142,7 @@ async function scanA11y(page, testInfo, options = {}) {
|
|
|
106
142
|
}
|
|
107
143
|
// Prepare data for the reporter
|
|
108
144
|
const reportData = {
|
|
109
|
-
pageKey
|
|
145
|
+
pageKey,
|
|
110
146
|
accessibilityScore: 0, // No longer used, derivation from Lighthouse removed
|
|
111
147
|
errors,
|
|
112
148
|
video: 'a11y-scan-video.webm', // Reference name for reporter
|
package/dist/SnapAllyReporter.js
CHANGED
|
@@ -44,6 +44,9 @@ const fs = __importStar(require("fs"));
|
|
|
44
44
|
* Generates an execution summary and detailed reports per test.
|
|
45
45
|
*/
|
|
46
46
|
class SnapAllyReporter {
|
|
47
|
+
printsToStdio() {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
47
50
|
constructor(options = {}) {
|
|
48
51
|
this.testIndex = 0;
|
|
49
52
|
this.assetsManager = new A11yReportAssets_1.A11yReportAssets();
|
package/package.json
CHANGED