Skip to content

Instantly share code, notes, and snippets.

@langalex
Created November 28, 2024 10:44
Show Gist options
  • Save langalex/52c3e973b7ad8d5d5ba28cc815dad2b5 to your computer and use it in GitHub Desktop.
Save langalex/52c3e973b7ad8d5d5ba28cc815dad2b5 to your computer and use it in GitHub Desktop.
Pa11y Setup
{
"concurrency": 2,
"useIncognitoBrowserContext": false,
"defaults": {
"reporters": [
"cli",
[
"./pa11y-ci-markdown-reporter.js",
{ "fileName": "./pa11y-cli-report.md" }
]
]
}
}
/* global require, process, module, __dirname */
'use strict';
const fs = require('fs');
const path = require('path');
const { resolve, isAbsolute, dirname } = require('path');
const mustache = require('mustache');
function writeReport(fileName, data) {
try {
const dirPath = dirname(fileName);
if (!(fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory())) {
fs.mkdirSync(dirPath, { recursive: true });
}
fs.writeFileSync(fileName, data);
} catch (error) {
console.error(`Unable to write ${fileName}`);
console.error(error);
}
}
function resolveFile(fileName) {
if (typeof fileName !== 'string') {
return null;
}
return isAbsolute(fileName) ? fileName : resolve(process.cwd(), fileName);
}
function markdown(allResults) {
const templateString = fs.readFileSync(
path.resolve(`${__dirname}/report-template.md`),
'utf-8',
);
const pages = allResults
.filter((r) => r.issues.length > 0)
.map((results) => {
return {
// Result information
issues: results.issues.map((issue) => {
return {
type: issue.type,
error: issue.type === 'error',
warning: issue.type === 'warning',
notice: issue.type === 'notice',
code: issue.code,
message: issue.message,
selector: issue.selector,
context: issue.context,
};
}),
pageUrl: formatPageUrl(results.pageUrl),
errorCount: results.issues.filter((issue) => issue.type === 'error')
.length,
warningCount: results.issues.filter((issue) => issue.type === 'warning')
.length,
noticeCount: results.issues.filter((issue) => issue.type === 'notice')
.length,
};
});
return mustache.render(templateString, {
// The current date
date: new Date(),
pages,
errorCount: pages.reduce((acc, page) => acc + page.errorCount, 0),
warningCount: pages.reduce((acc, page) => acc + page.warningCount, 0),
noticeCount: pages.reduce((acc, page) => acc + page.noticeCount, 0),
});
}
function formatPageUrl(filePath) {
const filename = path.basename(filePath);
const [verb, subdomain, urlpath] = decodeURIComponent(filename).split('!!');
return `${verb} ${subdomain}.cobot.me${urlpath.replace(/--/g, '/')}`;
}
module.exports = function htmlReporter(options = {}) {
const fileName = resolveFile(options.fileName);
const allResults = [];
return {
results(results) {
allResults.push(results);
},
afterAll() {
const html = markdown(allResults);
// If reporter options specify an output file, write to file.
// Otherwise, write to console.
if (fileName) {
writeReport(fileName, html);
} else {
console.log(html);
}
},
};
};
{
"name": "cobot-pa11y",
"version": "1.0.0",
"devDependencies": {
"mustache": "^4.2.0",
"pa11y-ci": "^3.1.0"
}
}

Accessibility Report

Generated at: {{date}} :rotating_light: {{errorCount}} errors, :warning: {{warningCount}} warnings, :notebook: {{noticeCount}} notices

{{#pages}}

{{{pageUrl}}}

🚨 {{errorCount}} errors, ⚠️ {{warningCount}} warnings, 📓 {{noticeCount}} notices

{{#issues}}

{{#error}}:rotating_light:{{/error}}{{#warning}}:warning:{{/warning}}{{#notice}}:notebook:{{/notice}} {{code}}

{{message}}

  • Type: {{type}}
  • Selector: {{selector}}
{{context}}

{{/issues}}

{{/pages}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment