New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@guidepup/virtual-screen-reader

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@guidepup/virtual-screen-reader - npm Package Compare versions

Comparing version 0.20.0 to 0.21.0

lib/cjs/getNodeAccessibilityData/getAccessibleAttributeLabels/getLabelFromImplicitHtmlElementValue/getLevelFromDocumentStructure.js

76

lib/cjs/createAccessibilityTree.js

@@ -15,4 +15,5 @@ "use strict";

exports.createAccessibilityTree = exports.END_OF_ROLE_PREFIX = void 0;
const index_js_1 = require("./getNodeAccessibilityData/getAccessibleAttributeLabels/index.js");
const getIdRefsByAttribute_js_1 = require("./getIdRefsByAttribute.js");
const index_js_1 = require("./getNodeAccessibilityData/index.js");
const index_js_2 = require("./getNodeAccessibilityData/index.js");
const getNodeByIdRef_js_1 = require("./getNodeByIdRef.js");

@@ -102,32 +103,24 @@ const isDialogRole_js_1 = require("./isDialogRole.js");

}
function flattenTree(tree) {
function flattenTree(container, tree, parentAccessibilityNodeTree) {
const { children } = tree, treeNode = __rest(tree, ["children"]);
const isAnnounced = !!treeNode.accessibleName ||
!!treeNode.accessibleDescription ||
treeNode.accessibleAttributeLabels.length > 0 ||
!!treeNode.spokenRole;
treeNode.parentAccessibilityNodeTree = parentAccessibilityNodeTree;
const { accessibleAttributeLabels, accessibleAttributeToLabelMap } = (0, index_js_1.getAccessibleAttributeLabels)(Object.assign(Object.assign({}, treeNode), { container }));
const treeNodeWithAttributeLabels = Object.assign(Object.assign({}, treeNode), { accessibleAttributeLabels,
accessibleAttributeToLabelMap });
const isAnnounced = !!treeNodeWithAttributeLabels.accessibleName ||
!!treeNodeWithAttributeLabels.accessibleDescription ||
treeNodeWithAttributeLabels.accessibleAttributeLabels.length > 0 ||
!!treeNodeWithAttributeLabels.spokenRole;
const ignoreChildren = shouldIgnoreChildren(tree);
const flattenedTree = ignoreChildren
? []
: [...children.flatMap((child) => flattenTree(child))];
: [
...children.flatMap((child) => flattenTree(container, child, Object.assign(Object.assign({}, treeNodeWithAttributeLabels), { children }))),
];
const isRoleContainer = !!flattenedTree.length && !ignoreChildren && !!treeNode.spokenRole;
if (isAnnounced) {
flattenedTree.unshift(treeNode);
flattenedTree.unshift(treeNodeWithAttributeLabels);
}
if (isRoleContainer) {
flattenedTree.push({
accessibleAttributeLabels: treeNode.accessibleAttributeLabels,
accessibleAttributeToLabelMap: treeNode.accessibleAttributeToLabelMap,
accessibleDescription: treeNode.accessibleDescription,
accessibleName: treeNode.accessibleName,
accessibleValue: treeNode.accessibleValue,
allowedAccessibilityChildRoles: treeNode.allowedAccessibilityChildRoles,
alternateReadingOrderParents: treeNode.alternateReadingOrderParents,
childrenPresentational: treeNode.childrenPresentational,
node: treeNode.node,
parent: treeNode.parent,
parentDialog: treeNode.parentDialog,
role: treeNode.role,
spokenRole: `${exports.END_OF_ROLE_PREFIX} ${treeNode.spokenRole}`,
});
flattenedTree.push(Object.assign(Object.assign({}, treeNodeWithAttributeLabels), { spokenRole: `${exports.END_OF_ROLE_PREFIX} ${treeNodeWithAttributeLabels.spokenRole}` }));
}

@@ -167,3 +160,3 @@ return flattenedTree;

: [];
const { accessibleAttributeLabels, accessibleAttributeToLabelMap, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = (0, index_js_1.getNodeAccessibilityData)({
const { accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, isExplicitPresentational, role, spokenRole, } = (0, index_js_2.getNodeAccessibilityData)({
allowedAccessibilityRoles: tree.allowedAccessibilityChildRoles,

@@ -175,5 +168,3 @@ alternateReadingOrderParents,

});
tree.children.push(growTree(childNode, {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
const childTree = growTree(childNode, {
accessibleDescription,

@@ -187,2 +178,3 @@ accessibleName,

node: childNode,
parentAccessibilityNodeTree: null, // Added during flattening
parent: node,

@@ -192,3 +184,9 @@ parentDialog,

spokenRole,
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes }));
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes });
if (isExplicitPresentational) {
tree.children.push(...childTree.children);
}
else {
tree.children.push(childTree);
}
});

@@ -216,3 +214,3 @@ /**

: [];
const { accessibleAttributeLabels, accessibleAttributeToLabelMap, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = (0, index_js_1.getNodeAccessibilityData)({
const { accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, isExplicitPresentational, role, spokenRole, } = (0, index_js_2.getNodeAccessibilityData)({
allowedAccessibilityRoles: tree.allowedAccessibilityChildRoles,

@@ -224,5 +222,3 @@ alternateReadingOrderParents,

});
tree.children.push(growTree(childNode, {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
const childTree = growTree(childNode, {
accessibleDescription,

@@ -236,2 +232,3 @@ accessibleName,

node: childNode,
parentAccessibilityNodeTree: null, // Added during flattening
parent: node,

@@ -241,3 +238,9 @@ parentDialog,

spokenRole,
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes }));
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes });
if (isExplicitPresentational) {
tree.children.push(...childTree.children);
}
else {
tree.children.push(childTree);
}
});

@@ -253,3 +256,3 @@ return tree;

const visitedNodes = new Set();
const { accessibleAttributeLabels, accessibleAttributeToLabelMap, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = (0, index_js_1.getNodeAccessibilityData)({
const { accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = (0, index_js_2.getNodeAccessibilityData)({
allowedAccessibilityRoles: [],

@@ -262,4 +265,2 @@ alternateReadingOrderParents: [],

const tree = growTree(node, {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
accessibleDescription,

@@ -273,2 +274,3 @@ accessibleName,

node,
parentAccessibilityNodeTree: null, // Added during flattening
parent: null,

@@ -284,4 +286,4 @@ parentDialog: null,

});
return flattenTree(tree);
return flattenTree(node, tree, null);
}
exports.createAccessibilityTree = createAccessibilityTree;

@@ -7,7 +7,7 @@ "use strict";

const getLabelFromHtmlEquivalentAttribute_js_1 = require("./getLabelFromHtmlEquivalentAttribute.js");
const getLabelFromImplicitHtmlElementValue_js_1 = require("./getLabelFromImplicitHtmlElementValue.js");
const index_js_1 = require("./getLabelFromImplicitHtmlElementValue/index.js");
const isElement_js_1 = require("../../isElement.js");
const mapAttributeNameAndValueToLabel_js_1 = require("./mapAttributeNameAndValueToLabel.js");
const postProcessLabels_js_1 = require("./postProcessLabels.js");
const getAccessibleAttributeLabels = ({ accessibleValue, alternateReadingOrderParents, container, node, role, }) => {
const getAccessibleAttributeLabels = ({ accessibleValue, alternateReadingOrderParents, container, node, parentAccessibilityNodeTree, role, }) => {
if (!(0, isElement_js_1.isElement)(node)) {

@@ -46,6 +46,8 @@ return {

}
const { label: labelFromImplicitHtmlElementValue, value: valueFromImplicitHtmlElementValue, } = (0, getLabelFromImplicitHtmlElementValue_js_1.getLabelFromImplicitHtmlElementValue)({
const { label: labelFromImplicitHtmlElementValue, value: valueFromImplicitHtmlElementValue, } = (0, index_js_1.getLabelFromImplicitHtmlElementValue)({
attributeName,
container,
node,
parentAccessibilityNodeTree,
role,
});

@@ -52,0 +54,0 @@ if (labelFromImplicitHtmlElementValue) {

@@ -97,3 +97,3 @@ "use strict";

"aria-placeholder": string("placeholder"),
"aria-posinset": integer("item set position"),
"aria-posinset": integer("position"),
"aria-pressed": tristate(State.PRESSED, State.PARTIALLY_PRESSED),

@@ -109,3 +109,3 @@ "aria-readonly": state(State.READ_ONLY),

"aria-selected": state(State.SELECTED),
"aria-setsize": integer("item set size"),
"aria-setsize": integer("set size"),
"aria-sort": token({

@@ -112,0 +112,0 @@ ascending: "sorted in ascending order",

@@ -36,3 +36,4 @@ "use strict";

function getValue(node) {
if (!allowedLocalNames.includes(node.localName)) {
const localName = (0, getLocalName_js_1.getLocalName)(node);
if (!allowedLocalNames.includes(localName)) {
return "";

@@ -39,0 +40,0 @@ }

@@ -6,3 +6,2 @@ "use strict";

const getRole_js_1 = require("./getRole.js");
const index_js_1 = require("./getAccessibleAttributeLabels/index.js");
const getAccessibleDescription_js_1 = require("./getAccessibleDescription.js");

@@ -39,3 +38,3 @@ const getAccessibleName_js_1 = require("./getAccessibleName.js");

};
function getNodeAccessibilityData({ allowedAccessibilityRoles, alternateReadingOrderParents, container, inheritedImplicitPresentational, node, }) {
function getNodeAccessibilityData({ allowedAccessibilityRoles, inheritedImplicitPresentational, node, }) {
var _a, _b;

@@ -51,9 +50,2 @@ const accessibleDescription = (0, getAccessibleDescription_js_1.getAccessibleDescription)(node);

});
const { accessibleAttributeLabels, accessibleAttributeToLabelMap } = (0, index_js_1.getAccessibleAttributeLabels)({
accessibleValue,
alternateReadingOrderParents,
container,
node,
role,
});
const amendedAccessibleDescription = accessibleDescription === accessibleName ? "" : accessibleDescription;

@@ -103,4 +95,2 @@ const isExplicitPresentational = getRole_js_1.presentationRoles.includes(explicitRole);

return {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
accessibleDescription: amendedAccessibleDescription,

@@ -111,2 +101,3 @@ accessibleName,

childrenPresentational,
isExplicitPresentational,
role,

@@ -113,0 +104,0 @@ spokenRole,

@@ -0,1 +1,2 @@

import { getAccessibleAttributeLabels, } from "./getNodeAccessibilityData/getAccessibleAttributeLabels/index.js";
import { getIdRefsByAttribute } from "./getIdRefsByAttribute.js";

@@ -85,31 +86,35 @@ import { getNodeAccessibilityData } from "./getNodeAccessibilityData/index.js";

}
function flattenTree(tree) {
function flattenTree(container, tree, parentAccessibilityNodeTree) {
const { children, ...treeNode } = tree;
const isAnnounced = !!treeNode.accessibleName ||
!!treeNode.accessibleDescription ||
treeNode.accessibleAttributeLabels.length > 0 ||
!!treeNode.spokenRole;
treeNode.parentAccessibilityNodeTree = parentAccessibilityNodeTree;
const { accessibleAttributeLabels, accessibleAttributeToLabelMap } = getAccessibleAttributeLabels({
...treeNode,
container,
});
const treeNodeWithAttributeLabels = {
...treeNode,
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
};
const isAnnounced = !!treeNodeWithAttributeLabels.accessibleName ||
!!treeNodeWithAttributeLabels.accessibleDescription ||
treeNodeWithAttributeLabels.accessibleAttributeLabels.length > 0 ||
!!treeNodeWithAttributeLabels.spokenRole;
const ignoreChildren = shouldIgnoreChildren(tree);
const flattenedTree = ignoreChildren
? []
: [...children.flatMap((child) => flattenTree(child))];
: [
...children.flatMap((child) => flattenTree(container, child, {
...treeNodeWithAttributeLabels,
children,
})),
];
const isRoleContainer = !!flattenedTree.length && !ignoreChildren && !!treeNode.spokenRole;
if (isAnnounced) {
flattenedTree.unshift(treeNode);
flattenedTree.unshift(treeNodeWithAttributeLabels);
}
if (isRoleContainer) {
flattenedTree.push({
accessibleAttributeLabels: treeNode.accessibleAttributeLabels,
accessibleAttributeToLabelMap: treeNode.accessibleAttributeToLabelMap,
accessibleDescription: treeNode.accessibleDescription,
accessibleName: treeNode.accessibleName,
accessibleValue: treeNode.accessibleValue,
allowedAccessibilityChildRoles: treeNode.allowedAccessibilityChildRoles,
alternateReadingOrderParents: treeNode.alternateReadingOrderParents,
childrenPresentational: treeNode.childrenPresentational,
node: treeNode.node,
parent: treeNode.parent,
parentDialog: treeNode.parentDialog,
role: treeNode.role,
spokenRole: `${END_OF_ROLE_PREFIX} ${treeNode.spokenRole}`,
...treeNodeWithAttributeLabels,
spokenRole: `${END_OF_ROLE_PREFIX} ${treeNodeWithAttributeLabels.spokenRole}`,
});

@@ -150,3 +155,3 @@ }

: [];
const { accessibleAttributeLabels, accessibleAttributeToLabelMap, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = getNodeAccessibilityData({
const { accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, isExplicitPresentational, role, spokenRole, } = getNodeAccessibilityData({
allowedAccessibilityRoles: tree.allowedAccessibilityChildRoles,

@@ -158,5 +163,3 @@ alternateReadingOrderParents,

});
tree.children.push(growTree(childNode, {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
const childTree = growTree(childNode, {
accessibleDescription,

@@ -170,2 +173,3 @@ accessibleName,

node: childNode,
parentAccessibilityNodeTree: null, // Added during flattening
parent: node,

@@ -175,3 +179,9 @@ parentDialog,

spokenRole,
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes }));
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes });
if (isExplicitPresentational) {
tree.children.push(...childTree.children);
}
else {
tree.children.push(childTree);
}
});

@@ -199,3 +209,3 @@ /**

: [];
const { accessibleAttributeLabels, accessibleAttributeToLabelMap, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = getNodeAccessibilityData({
const { accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, isExplicitPresentational, role, spokenRole, } = getNodeAccessibilityData({
allowedAccessibilityRoles: tree.allowedAccessibilityChildRoles,

@@ -207,5 +217,3 @@ alternateReadingOrderParents,

});
tree.children.push(growTree(childNode, {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
const childTree = growTree(childNode, {
accessibleDescription,

@@ -219,2 +227,3 @@ accessibleName,

node: childNode,
parentAccessibilityNodeTree: null, // Added during flattening
parent: node,

@@ -224,3 +233,9 @@ parentDialog,

spokenRole,
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes }));
}, { alternateReadingOrderMap, container, ownedNodes, visitedNodes });
if (isExplicitPresentational) {
tree.children.push(...childTree.children);
}
else {
tree.children.push(childTree);
}
});

@@ -236,3 +251,3 @@ return tree;

const visitedNodes = new Set();
const { accessibleAttributeLabels, accessibleAttributeToLabelMap, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = getNodeAccessibilityData({
const { accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = getNodeAccessibilityData({
allowedAccessibilityRoles: [],

@@ -245,4 +260,2 @@ alternateReadingOrderParents: [],

const tree = growTree(node, {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
accessibleDescription,

@@ -256,2 +269,3 @@ accessibleName,

node,
parentAccessibilityNodeTree: null, // Added during flattening
parent: null,

@@ -267,3 +281,3 @@ parentDialog: null,

});
return flattenTree(tree);
return flattenTree(node, tree, null);
}
import { getAttributesByRole } from "./getAttributesByRole.js";
import { getLabelFromAriaAttribute } from "./getLabelFromAriaAttribute.js";
import { getLabelFromHtmlEquivalentAttribute } from "./getLabelFromHtmlEquivalentAttribute.js";
import { getLabelFromImplicitHtmlElementValue } from "./getLabelFromImplicitHtmlElementValue.js";
import { getLabelFromImplicitHtmlElementValue } from "./getLabelFromImplicitHtmlElementValue/index.js";
import { isElement } from "../../isElement.js";
import { mapAttributeNameAndValueToLabel } from "./mapAttributeNameAndValueToLabel.js";
import { postProcessLabels } from "./postProcessLabels.js";
export const getAccessibleAttributeLabels = ({ accessibleValue, alternateReadingOrderParents, container, node, role, }) => {
export const getAccessibleAttributeLabels = ({ accessibleValue, alternateReadingOrderParents, container, node, parentAccessibilityNodeTree, role, }) => {
if (!isElement(node)) {

@@ -46,2 +46,4 @@ return {

node,
parentAccessibilityNodeTree,
role,
});

@@ -48,0 +50,0 @@ if (labelFromImplicitHtmlElementValue) {

@@ -94,3 +94,3 @@ import { getAccessibleName } from "../getAccessibleName.js";

"aria-placeholder": string("placeholder"),
"aria-posinset": integer("item set position"),
"aria-posinset": integer("position"),
"aria-pressed": tristate(State.PRESSED, State.PARTIALLY_PRESSED),

@@ -106,3 +106,3 @@ "aria-readonly": state(State.READ_ONLY),

"aria-selected": state(State.SELECTED),
"aria-setsize": integer("item set size"),
"aria-setsize": integer("set size"),
"aria-sort": token({

@@ -109,0 +109,0 @@ ascending: "sorted in ascending order",

@@ -33,3 +33,4 @@ import { getLocalName } from "../getLocalName.js";

function getValue(node) {
if (!allowedLocalNames.includes(node.localName)) {
const localName = getLocalName(node);
if (!allowedLocalNames.includes(localName)) {
return "";

@@ -36,0 +37,0 @@ }

import { roles } from "aria-query";
import { getRole, presentationRoles } from "./getRole.js";
import { getAccessibleAttributeLabels } from "./getAccessibleAttributeLabels/index.js";
import { getAccessibleDescription } from "./getAccessibleDescription.js";

@@ -35,3 +34,3 @@ import { getAccessibleName } from "./getAccessibleName.js";

};
export function getNodeAccessibilityData({ allowedAccessibilityRoles, alternateReadingOrderParents, container, inheritedImplicitPresentational, node, }) {
export function getNodeAccessibilityData({ allowedAccessibilityRoles, inheritedImplicitPresentational, node, }) {
const accessibleDescription = getAccessibleDescription(node);

@@ -46,9 +45,2 @@ const accessibleName = getAccessibleName(node);

});
const { accessibleAttributeLabels, accessibleAttributeToLabelMap } = getAccessibleAttributeLabels({
accessibleValue,
alternateReadingOrderParents,
container,
node,
role,
});
const amendedAccessibleDescription = accessibleDescription === accessibleName ? "" : accessibleDescription;

@@ -98,4 +90,2 @@ const isExplicitPresentational = presentationRoles.includes(explicitRole);

return {
accessibleAttributeLabels,
accessibleAttributeToLabelMap,
accessibleDescription: amendedAccessibleDescription,

@@ -106,2 +96,3 @@ accessibleName,

childrenPresentational,
isExplicitPresentational,
role,

@@ -108,0 +99,0 @@ spokenRole,

@@ -13,2 +13,3 @@ import { AccessibleAttributeToLabelMap } from "./getNodeAccessibilityData/getAccessibleAttributeLabels/index.js";

node: Node;
parentAccessibilityNodeTree: AccessibilityNodeTree | null;
parent: Node | null;

@@ -19,2 +20,5 @@ parentDialog: HTMLElement | null;

}
export interface AccessibilityNodeTree extends Omit<AccessibilityNode, "accessibleAttributeLabels" | "accessibleAttributeToLabelMap"> {
children: AccessibilityNodeTree[];
}
export declare function createAccessibilityTree(node: Node | null): AccessibilityNode[];

@@ -0,1 +1,2 @@

import type { AccessibilityNodeTree } from "../../createAccessibilityTree.js";
export type AccessibleAttributeToLabelMap = Record<string, {

@@ -5,3 +6,3 @@ label: string;

}>;
export declare const getAccessibleAttributeLabels: ({ accessibleValue, alternateReadingOrderParents, container, node, role, }: {
export declare const getAccessibleAttributeLabels: ({ accessibleValue, alternateReadingOrderParents, container, node, parentAccessibilityNodeTree, role, }: {
accessibleValue: string;

@@ -11,2 +12,3 @@ alternateReadingOrderParents: Node[];

node: Node;
parentAccessibilityNodeTree: AccessibilityNodeTree;
role: string;

@@ -13,0 +15,0 @@ }) => {

@@ -1,2 +0,2 @@

export declare function getNodeAccessibilityData({ allowedAccessibilityRoles, alternateReadingOrderParents, container, inheritedImplicitPresentational, node, }: {
export declare function getNodeAccessibilityData({ allowedAccessibilityRoles, inheritedImplicitPresentational, node, }: {
allowedAccessibilityRoles: string[][];

@@ -8,4 +8,2 @@ alternateReadingOrderParents: Node[];

}): {
accessibleAttributeLabels: string[];
accessibleAttributeToLabelMap: import("./getAccessibleAttributeLabels/index.js").AccessibleAttributeToLabelMap;
accessibleDescription: string;

@@ -16,4 +14,5 @@ accessibleName: string;

childrenPresentational: boolean;
isExplicitPresentational: boolean;
role: string;
spokenRole: string;
};
{
"name": "@guidepup/virtual-screen-reader",
"version": "0.20.0",
"version": "0.21.0",
"description": "Virtual Screen Reader driver for unit test automation.",

@@ -5,0 +5,0 @@ "author": "Craig Morten <craig.morten@hotmail.co.uk>",

@@ -108,9 +108,15 @@ # Virtual Screen Reader

"heading, Section Heading, level 1",
"paragraph",
"Section Text",
"end of paragraph",
"article",
"banner",
"heading, Article Header Heading, level 1",
"paragraph",
"Article Header Text",
"end of paragraph",
"end of banner",
"paragraph",
"Article Text",
"end of paragraph",
"end of article",

@@ -136,3 +142,3 @@ "end of region",

- [`@guidepup/setup`](https://github.com/guidepup/setup) - Set up your local or CI environment for screen reader test automation.
- [`@guidepup/playwright`](https://github.com/guidepup/guidepup-playwright) - Seemless integration of Guidepup with Playwright.
- [`@guidepup/playwright`](https://github.com/guidepup/guidepup-playwright) - Seamless integration of Guidepup with Playwright.
- [`@guidepup/jest`](https://github.com/guidepup/jest) - Jest matchers for reliable unit testing of your screen reader a11y workflows.

@@ -139,0 +145,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc