 aacb45156b
			
		
	
	aacb45156b
	
	
	
		
			
			- Install Jest for unit testing with React Testing Library - Install Playwright for end-to-end testing - Configure Jest with proper TypeScript support and module mapping - Create test setup files and utilities for both unit and e2e tests Components: * Jest configuration with coverage thresholds * Playwright configuration with browser automation * Unit tests for LoginForm, AuthContext, and useSocketIO hook * E2E tests for authentication, dashboard, and agents workflows * GitHub Actions workflow for automated testing * Mock data and API utilities for consistent testing * Test documentation with best practices Testing features: - Unit tests with 70% coverage threshold - E2E tests with API mocking and user journey testing - CI/CD integration for automated test runs - Cross-browser testing support with Playwright - Authentication system testing end-to-end 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			185 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // https://w3c.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html
 | |
| 
 | |
| /**
 | |
|  * Safe Element.localName for all supported environments
 | |
|  * @param element
 | |
|  */
 | |
| export function getLocalName(element) {
 | |
|   var _element$localName;
 | |
|   return (// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
 | |
|     (_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName :
 | |
|     // eslint-disable-next-line no-restricted-properties -- required for the fallback
 | |
|     element.tagName.toLowerCase()
 | |
|   );
 | |
| }
 | |
| var localNameToRoleMappings = {
 | |
|   article: "article",
 | |
|   aside: "complementary",
 | |
|   button: "button",
 | |
|   datalist: "listbox",
 | |
|   dd: "definition",
 | |
|   details: "group",
 | |
|   dialog: "dialog",
 | |
|   dt: "term",
 | |
|   fieldset: "group",
 | |
|   figure: "figure",
 | |
|   // WARNING: Only with an accessible name
 | |
|   form: "form",
 | |
|   footer: "contentinfo",
 | |
|   h1: "heading",
 | |
|   h2: "heading",
 | |
|   h3: "heading",
 | |
|   h4: "heading",
 | |
|   h5: "heading",
 | |
|   h6: "heading",
 | |
|   header: "banner",
 | |
|   hr: "separator",
 | |
|   html: "document",
 | |
|   legend: "legend",
 | |
|   li: "listitem",
 | |
|   math: "math",
 | |
|   main: "main",
 | |
|   menu: "list",
 | |
|   nav: "navigation",
 | |
|   ol: "list",
 | |
|   optgroup: "group",
 | |
|   // WARNING: Only in certain context
 | |
|   option: "option",
 | |
|   output: "status",
 | |
|   progress: "progressbar",
 | |
|   // WARNING: Only with an accessible name
 | |
|   section: "region",
 | |
|   summary: "button",
 | |
|   table: "table",
 | |
|   tbody: "rowgroup",
 | |
|   textarea: "textbox",
 | |
|   tfoot: "rowgroup",
 | |
|   // WARNING: Only in certain context
 | |
|   td: "cell",
 | |
|   th: "columnheader",
 | |
|   thead: "rowgroup",
 | |
|   tr: "row",
 | |
|   ul: "list"
 | |
| };
 | |
| var prohibitedAttributes = {
 | |
|   caption: new Set(["aria-label", "aria-labelledby"]),
 | |
|   code: new Set(["aria-label", "aria-labelledby"]),
 | |
|   deletion: new Set(["aria-label", "aria-labelledby"]),
 | |
|   emphasis: new Set(["aria-label", "aria-labelledby"]),
 | |
|   generic: new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
 | |
|   insertion: new Set(["aria-label", "aria-labelledby"]),
 | |
|   paragraph: new Set(["aria-label", "aria-labelledby"]),
 | |
|   presentation: new Set(["aria-label", "aria-labelledby"]),
 | |
|   strong: new Set(["aria-label", "aria-labelledby"]),
 | |
|   subscript: new Set(["aria-label", "aria-labelledby"]),
 | |
|   superscript: new Set(["aria-label", "aria-labelledby"])
 | |
| };
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param element
 | |
|  * @param role The role used for this element. This is specified to control whether you want to use the implicit or explicit role.
 | |
|  */
 | |
| function hasGlobalAriaAttributes(element, role) {
 | |
|   // https://rawgit.com/w3c/aria/stable/#global_states
 | |
|   // commented attributes are deprecated
 | |
|   return ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-describedby", "aria-details",
 | |
|   // "disabled",
 | |
|   "aria-dropeffect",
 | |
|   // "errormessage",
 | |
|   "aria-flowto", "aria-grabbed",
 | |
|   // "haspopup",
 | |
|   "aria-hidden",
 | |
|   // "invalid",
 | |
|   "aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription"].some(function (attributeName) {
 | |
|     var _prohibitedAttributes;
 | |
|     return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
 | |
|   });
 | |
| }
 | |
| function ignorePresentationalRole(element, implicitRole) {
 | |
|   // https://rawgit.com/w3c/aria/stable/#conflict_resolution_presentation_none
 | |
|   return hasGlobalAriaAttributes(element, implicitRole);
 | |
| }
 | |
| export default function getRole(element) {
 | |
|   var explicitRole = getExplicitRole(element);
 | |
|   if (explicitRole === null || explicitRole === "presentation") {
 | |
|     var implicitRole = getImplicitRole(element);
 | |
|     if (explicitRole !== "presentation" || ignorePresentationalRole(element, implicitRole || "")) {
 | |
|       return implicitRole;
 | |
|     }
 | |
|   }
 | |
|   return explicitRole;
 | |
| }
 | |
| function getImplicitRole(element) {
 | |
|   var mappedByTag = localNameToRoleMappings[getLocalName(element)];
 | |
|   if (mappedByTag !== undefined) {
 | |
|     return mappedByTag;
 | |
|   }
 | |
|   switch (getLocalName(element)) {
 | |
|     case "a":
 | |
|     case "area":
 | |
|     case "link":
 | |
|       if (element.hasAttribute("href")) {
 | |
|         return "link";
 | |
|       }
 | |
|       break;
 | |
|     case "img":
 | |
|       if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
 | |
|         return "presentation";
 | |
|       }
 | |
|       return "img";
 | |
|     case "input":
 | |
|       {
 | |
|         var _ref = element,
 | |
|           type = _ref.type;
 | |
|         switch (type) {
 | |
|           case "button":
 | |
|           case "image":
 | |
|           case "reset":
 | |
|           case "submit":
 | |
|             return "button";
 | |
|           case "checkbox":
 | |
|           case "radio":
 | |
|             return type;
 | |
|           case "range":
 | |
|             return "slider";
 | |
|           case "email":
 | |
|           case "tel":
 | |
|           case "text":
 | |
|           case "url":
 | |
|             if (element.hasAttribute("list")) {
 | |
|               return "combobox";
 | |
|             }
 | |
|             return "textbox";
 | |
|           case "search":
 | |
|             if (element.hasAttribute("list")) {
 | |
|               return "combobox";
 | |
|             }
 | |
|             return "searchbox";
 | |
|           case "number":
 | |
|             return "spinbutton";
 | |
|           default:
 | |
|             return null;
 | |
|         }
 | |
|       }
 | |
|     case "select":
 | |
|       if (element.hasAttribute("multiple") || element.size > 1) {
 | |
|         return "listbox";
 | |
|       }
 | |
|       return "combobox";
 | |
|   }
 | |
|   return null;
 | |
| }
 | |
| function getExplicitRole(element) {
 | |
|   var role = element.getAttribute("role");
 | |
|   if (role !== null) {
 | |
|     var explicitRole = role.trim().split(" ")[0];
 | |
|     // String.prototype.split(sep, limit) will always return an array with at least one member
 | |
|     // as long as limit is either undefined or > 0
 | |
|     if (explicitRole.length > 0) {
 | |
|       return explicitRole;
 | |
|     }
 | |
|   }
 | |
|   return null;
 | |
| }
 | |
| //# sourceMappingURL=getRole.mjs.map
 |