Set up comprehensive frontend testing infrastructure
- 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>
This commit is contained in:
		
							
								
								
									
										172
									
								
								frontend/node_modules/parse5/dist/cjs/serializer/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								frontend/node_modules/parse5/dist/cjs/serializer/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | ||||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.serialize = serialize; | ||||
| exports.serializeOuter = serializeOuter; | ||||
| const html_js_1 = require("../common/html.js"); | ||||
| const escape_1 = require("entities/escape"); | ||||
| const default_js_1 = require("../tree-adapters/default.js"); | ||||
| // Sets | ||||
| const VOID_ELEMENTS = new Set([ | ||||
|     html_js_1.TAG_NAMES.AREA, | ||||
|     html_js_1.TAG_NAMES.BASE, | ||||
|     html_js_1.TAG_NAMES.BASEFONT, | ||||
|     html_js_1.TAG_NAMES.BGSOUND, | ||||
|     html_js_1.TAG_NAMES.BR, | ||||
|     html_js_1.TAG_NAMES.COL, | ||||
|     html_js_1.TAG_NAMES.EMBED, | ||||
|     html_js_1.TAG_NAMES.FRAME, | ||||
|     html_js_1.TAG_NAMES.HR, | ||||
|     html_js_1.TAG_NAMES.IMG, | ||||
|     html_js_1.TAG_NAMES.INPUT, | ||||
|     html_js_1.TAG_NAMES.KEYGEN, | ||||
|     html_js_1.TAG_NAMES.LINK, | ||||
|     html_js_1.TAG_NAMES.META, | ||||
|     html_js_1.TAG_NAMES.PARAM, | ||||
|     html_js_1.TAG_NAMES.SOURCE, | ||||
|     html_js_1.TAG_NAMES.TRACK, | ||||
|     html_js_1.TAG_NAMES.WBR, | ||||
| ]); | ||||
| function isVoidElement(node, options) { | ||||
|     return (options.treeAdapter.isElementNode(node) && | ||||
|         options.treeAdapter.getNamespaceURI(node) === html_js_1.NS.HTML && | ||||
|         VOID_ELEMENTS.has(options.treeAdapter.getTagName(node))); | ||||
| } | ||||
| const defaultOpts = { treeAdapter: default_js_1.defaultTreeAdapter, scriptingEnabled: true }; | ||||
| /** | ||||
|  * Serializes an AST node to an HTML string. | ||||
|  * | ||||
|  * @example | ||||
|  * | ||||
|  * ```js | ||||
|  * const parse5 = require('parse5'); | ||||
|  * | ||||
|  * const document = parse5.parse('<!DOCTYPE html><html><head></head><body>Hi there!</body></html>'); | ||||
|  * | ||||
|  * // Serializes a document. | ||||
|  * const html = parse5.serialize(document); | ||||
|  * | ||||
|  * // Serializes the <html> element content. | ||||
|  * const str = parse5.serialize(document.childNodes[1]); | ||||
|  * | ||||
|  * console.log(str); //> '<head></head><body>Hi there!</body>' | ||||
|  * ``` | ||||
|  * | ||||
|  * @param node Node to serialize. | ||||
|  * @param options Serialization options. | ||||
|  */ | ||||
| function serialize(node, options) { | ||||
|     const opts = Object.assign(Object.assign({}, defaultOpts), options); | ||||
|     if (isVoidElement(node, opts)) { | ||||
|         return ''; | ||||
|     } | ||||
|     return serializeChildNodes(node, opts); | ||||
| } | ||||
| /** | ||||
|  * Serializes an AST element node to an HTML string, including the element node. | ||||
|  * | ||||
|  * @example | ||||
|  * | ||||
|  * ```js | ||||
|  * const parse5 = require('parse5'); | ||||
|  * | ||||
|  * const document = parse5.parseFragment('<div>Hello, <b>world</b>!</div>'); | ||||
|  * | ||||
|  * // Serializes the <div> element. | ||||
|  * const str = parse5.serializeOuter(document.childNodes[0]); | ||||
|  * | ||||
|  * console.log(str); //> '<div>Hello, <b>world</b>!</div>' | ||||
|  * ``` | ||||
|  * | ||||
|  * @param node Node to serialize. | ||||
|  * @param options Serialization options. | ||||
|  */ | ||||
| function serializeOuter(node, options) { | ||||
|     const opts = Object.assign(Object.assign({}, defaultOpts), options); | ||||
|     return serializeNode(node, opts); | ||||
| } | ||||
| function serializeChildNodes(parentNode, options) { | ||||
|     let html = ''; | ||||
|     // Get container of the child nodes | ||||
|     const container = options.treeAdapter.isElementNode(parentNode) && | ||||
|         options.treeAdapter.getTagName(parentNode) === html_js_1.TAG_NAMES.TEMPLATE && | ||||
|         options.treeAdapter.getNamespaceURI(parentNode) === html_js_1.NS.HTML | ||||
|         ? options.treeAdapter.getTemplateContent(parentNode) | ||||
|         : parentNode; | ||||
|     const childNodes = options.treeAdapter.getChildNodes(container); | ||||
|     if (childNodes) { | ||||
|         for (const currentNode of childNodes) { | ||||
|             html += serializeNode(currentNode, options); | ||||
|         } | ||||
|     } | ||||
|     return html; | ||||
| } | ||||
| function serializeNode(node, options) { | ||||
|     if (options.treeAdapter.isElementNode(node)) { | ||||
|         return serializeElement(node, options); | ||||
|     } | ||||
|     if (options.treeAdapter.isTextNode(node)) { | ||||
|         return serializeTextNode(node, options); | ||||
|     } | ||||
|     if (options.treeAdapter.isCommentNode(node)) { | ||||
|         return serializeCommentNode(node, options); | ||||
|     } | ||||
|     if (options.treeAdapter.isDocumentTypeNode(node)) { | ||||
|         return serializeDocumentTypeNode(node, options); | ||||
|     } | ||||
|     // Return an empty string for unknown nodes | ||||
|     return ''; | ||||
| } | ||||
| function serializeElement(node, options) { | ||||
|     const tn = options.treeAdapter.getTagName(node); | ||||
|     return `<${tn}${serializeAttributes(node, options)}>${isVoidElement(node, options) ? '' : `${serializeChildNodes(node, options)}</${tn}>`}`; | ||||
| } | ||||
| function serializeAttributes(node, { treeAdapter }) { | ||||
|     let html = ''; | ||||
|     for (const attr of treeAdapter.getAttrList(node)) { | ||||
|         html += ' '; | ||||
|         if (attr.namespace) { | ||||
|             switch (attr.namespace) { | ||||
|                 case html_js_1.NS.XML: { | ||||
|                     html += `xml:${attr.name}`; | ||||
|                     break; | ||||
|                 } | ||||
|                 case html_js_1.NS.XMLNS: { | ||||
|                     if (attr.name !== 'xmlns') { | ||||
|                         html += 'xmlns:'; | ||||
|                     } | ||||
|                     html += attr.name; | ||||
|                     break; | ||||
|                 } | ||||
|                 case html_js_1.NS.XLINK: { | ||||
|                     html += `xlink:${attr.name}`; | ||||
|                     break; | ||||
|                 } | ||||
|                 default: { | ||||
|                     html += `${attr.prefix}:${attr.name}`; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             html += attr.name; | ||||
|         } | ||||
|         html += `="${(0, escape_1.escapeAttribute)(attr.value)}"`; | ||||
|     } | ||||
|     return html; | ||||
| } | ||||
| function serializeTextNode(node, options) { | ||||
|     const { treeAdapter } = options; | ||||
|     const content = treeAdapter.getTextNodeContent(node); | ||||
|     const parent = treeAdapter.getParentNode(node); | ||||
|     const parentTn = parent && treeAdapter.isElementNode(parent) && treeAdapter.getTagName(parent); | ||||
|     return parentTn && | ||||
|         treeAdapter.getNamespaceURI(parent) === html_js_1.NS.HTML && | ||||
|         (0, html_js_1.hasUnescapedText)(parentTn, options.scriptingEnabled) | ||||
|         ? content | ||||
|         : (0, escape_1.escapeText)(content); | ||||
| } | ||||
| function serializeCommentNode(node, { treeAdapter }) { | ||||
|     return `<!--${treeAdapter.getCommentNodeContent(node)}-->`; | ||||
| } | ||||
| function serializeDocumentTypeNode(node, { treeAdapter }) { | ||||
|     return `<!DOCTYPE ${treeAdapter.getDocumentTypeNodeName(node)}>`; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 anthonyrawlins
					anthonyrawlins