@focusconsulting/auto-a11y
Version:
A powerful tool that combines AI with accessibility-first element selection for Playwright tests
118 lines (117 loc) • 4.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.simplifyHtml = simplifyHtml;
exports.extractBodyContent = extractBodyContent;
const cheerio = __importStar(require("cheerio"));
const sanitize_html_1 = __importDefault(require("sanitize-html"));
/**
* Simplifies HTML by keeping only essential elements and attributes
* @param html The HTML content to simplify
* @returns Simplified HTML string
*/
function simplifyHtml(html) {
return (0, sanitize_html_1.default)(html, {
allowedTags: [
"a",
"button",
"input",
"select",
"textarea",
"label",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"p",
"img",
],
exclusiveFilter: (frame) => {
// TODO: check how this function works
return (frame.tag === "div" || frame.tag === "span") && Object.keys(frame.attribs).includes("role");
},
allowedAttributes: {
"*": ["checked", "aria-*", "name", "data-testid", "role", "region", "value"]
}
});
}
/**
* Extracts and sanitizes the body content from HTML
* @param html The full HTML content
* @param description The element description to help focus the extraction
* @returns Sanitized body content
*/
function extractBodyContent(html) {
try {
const cleaned = (0, sanitize_html_1.default)(html, {
allowedTags: sanitize_html_1.default.defaults.allowedTags.concat(["img"]),
allowedAttributes: {
"*": ["checked", "aria-*", "name", "data-testid", "role", "region", "value"]
}
});
const $ = cheerio.load(cleaned);
// Simplify deeply nested structures
$("div > div:only-child").each((_, el) => {
const $el = $(el);
const $parent = $el.parent();
if ($parent.children().length === 1 &&
!$el.is("button, a, input, select, textarea")) {
// Replace the parent with its children
const $children = $el.children();
$el.replaceWith($children);
}
});
// Remove empty containers
$("div:empty, span:empty").remove();
// If no relevant elements found or context extraction failed,
// get the body content and truncate if necessary
let bodyContent = $("body").html() || $.html();
if (bodyContent.length > 8192) {
console.warn("Body content might be too large for the context window");
}
return bodyContent.trim();
}
catch (error) {
console.warn(`Error extracting body content: ${error}`);
return html.length > 20000
? html.substring(0, 10000) + "..." + html.substring(html.length - 10000)
: html;
}
}