 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>
		
			
				
	
	
		
			506 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| const conversions = require("webidl-conversions");
 | |
| const utils = require("./utils.js");
 | |
| 
 | |
| const Function = require("./Function.js");
 | |
| const newObjectInRealm = utils.newObjectInRealm;
 | |
| const implSymbol = utils.implSymbol;
 | |
| const ctorRegistrySymbol = utils.ctorRegistrySymbol;
 | |
| 
 | |
| const interfaceName = "URLSearchParams";
 | |
| 
 | |
| exports.is = value => {
 | |
|   return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation;
 | |
| };
 | |
| exports.isImpl = value => {
 | |
|   return utils.isObject(value) && value instanceof Impl.implementation;
 | |
| };
 | |
| exports.convert = (globalObject, value, { context = "The provided value" } = {}) => {
 | |
|   if (exports.is(value)) {
 | |
|     return utils.implForWrapper(value);
 | |
|   }
 | |
|   throw new globalObject.TypeError(`${context} is not of type 'URLSearchParams'.`);
 | |
| };
 | |
| 
 | |
| exports.createDefaultIterator = (globalObject, target, kind) => {
 | |
|   const ctorRegistry = globalObject[ctorRegistrySymbol];
 | |
|   const iteratorPrototype = ctorRegistry["URLSearchParams Iterator"];
 | |
|   const iterator = Object.create(iteratorPrototype);
 | |
|   Object.defineProperty(iterator, utils.iterInternalSymbol, {
 | |
|     value: { target, kind, index: 0 },
 | |
|     configurable: true
 | |
|   });
 | |
|   return iterator;
 | |
| };
 | |
| 
 | |
| function makeWrapper(globalObject, newTarget) {
 | |
|   let proto;
 | |
|   if (newTarget !== undefined) {
 | |
|     proto = newTarget.prototype;
 | |
|   }
 | |
| 
 | |
|   if (!utils.isObject(proto)) {
 | |
|     proto = globalObject[ctorRegistrySymbol]["URLSearchParams"].prototype;
 | |
|   }
 | |
| 
 | |
|   return Object.create(proto);
 | |
| }
 | |
| 
 | |
| exports.create = (globalObject, constructorArgs, privateData) => {
 | |
|   const wrapper = makeWrapper(globalObject);
 | |
|   return exports.setup(wrapper, globalObject, constructorArgs, privateData);
 | |
| };
 | |
| 
 | |
| exports.createImpl = (globalObject, constructorArgs, privateData) => {
 | |
|   const wrapper = exports.create(globalObject, constructorArgs, privateData);
 | |
|   return utils.implForWrapper(wrapper);
 | |
| };
 | |
| 
 | |
| exports._internalSetup = (wrapper, globalObject) => {};
 | |
| 
 | |
| exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => {
 | |
|   privateData.wrapper = wrapper;
 | |
| 
 | |
|   exports._internalSetup(wrapper, globalObject);
 | |
|   Object.defineProperty(wrapper, implSymbol, {
 | |
|     value: new Impl.implementation(globalObject, constructorArgs, privateData),
 | |
|     configurable: true
 | |
|   });
 | |
| 
 | |
|   wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
 | |
|   if (Impl.init) {
 | |
|     Impl.init(wrapper[implSymbol]);
 | |
|   }
 | |
|   return wrapper;
 | |
| };
 | |
| 
 | |
| exports.new = (globalObject, newTarget) => {
 | |
|   const wrapper = makeWrapper(globalObject, newTarget);
 | |
| 
 | |
|   exports._internalSetup(wrapper, globalObject);
 | |
|   Object.defineProperty(wrapper, implSymbol, {
 | |
|     value: Object.create(Impl.implementation.prototype),
 | |
|     configurable: true
 | |
|   });
 | |
| 
 | |
|   wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
 | |
|   if (Impl.init) {
 | |
|     Impl.init(wrapper[implSymbol]);
 | |
|   }
 | |
|   return wrapper[implSymbol];
 | |
| };
 | |
| 
 | |
| const exposed = new Set(["Window", "Worker"]);
 | |
| 
 | |
| exports.install = (globalObject, globalNames) => {
 | |
|   if (!globalNames.some(globalName => exposed.has(globalName))) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   const ctorRegistry = utils.initCtorRegistry(globalObject);
 | |
|   class URLSearchParams {
 | |
|     constructor() {
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         if (curArg !== undefined) {
 | |
|           if (utils.isObject(curArg)) {
 | |
|             if (curArg[Symbol.iterator] !== undefined) {
 | |
|               if (!utils.isObject(curArg)) {
 | |
|                 throw new globalObject.TypeError(
 | |
|                   "Failed to construct 'URLSearchParams': parameter 1" + " sequence" + " is not an iterable object."
 | |
|                 );
 | |
|               } else {
 | |
|                 const V = [];
 | |
|                 const tmp = curArg;
 | |
|                 for (let nextItem of tmp) {
 | |
|                   if (!utils.isObject(nextItem)) {
 | |
|                     throw new globalObject.TypeError(
 | |
|                       "Failed to construct 'URLSearchParams': parameter 1" +
 | |
|                         " sequence" +
 | |
|                         "'s element" +
 | |
|                         " is not an iterable object."
 | |
|                     );
 | |
|                   } else {
 | |
|                     const V = [];
 | |
|                     const tmp = nextItem;
 | |
|                     for (let nextItem of tmp) {
 | |
|                       nextItem = conversions["USVString"](nextItem, {
 | |
|                         context:
 | |
|                           "Failed to construct 'URLSearchParams': parameter 1" +
 | |
|                           " sequence" +
 | |
|                           "'s element" +
 | |
|                           "'s element",
 | |
|                         globals: globalObject
 | |
|                       });
 | |
| 
 | |
|                       V.push(nextItem);
 | |
|                     }
 | |
|                     nextItem = V;
 | |
|                   }
 | |
| 
 | |
|                   V.push(nextItem);
 | |
|                 }
 | |
|                 curArg = V;
 | |
|               }
 | |
|             } else {
 | |
|               if (!utils.isObject(curArg)) {
 | |
|                 throw new globalObject.TypeError(
 | |
|                   "Failed to construct 'URLSearchParams': parameter 1" + " record" + " is not an object."
 | |
|                 );
 | |
|               } else {
 | |
|                 const result = Object.create(null);
 | |
|                 for (const key of Reflect.ownKeys(curArg)) {
 | |
|                   const desc = Object.getOwnPropertyDescriptor(curArg, key);
 | |
|                   if (desc && desc.enumerable) {
 | |
|                     let typedKey = key;
 | |
| 
 | |
|                     typedKey = conversions["USVString"](typedKey, {
 | |
|                       context: "Failed to construct 'URLSearchParams': parameter 1" + " record" + "'s key",
 | |
|                       globals: globalObject
 | |
|                     });
 | |
| 
 | |
|                     let typedValue = curArg[key];
 | |
| 
 | |
|                     typedValue = conversions["USVString"](typedValue, {
 | |
|                       context: "Failed to construct 'URLSearchParams': parameter 1" + " record" + "'s value",
 | |
|                       globals: globalObject
 | |
|                     });
 | |
| 
 | |
|                     result[typedKey] = typedValue;
 | |
|                   }
 | |
|                 }
 | |
|                 curArg = result;
 | |
|               }
 | |
|             }
 | |
|           } else {
 | |
|             curArg = conversions["USVString"](curArg, {
 | |
|               context: "Failed to construct 'URLSearchParams': parameter 1",
 | |
|               globals: globalObject
 | |
|             });
 | |
|           }
 | |
|         } else {
 | |
|           curArg = "";
 | |
|         }
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return exports.setup(Object.create(new.target.prototype), globalObject, args);
 | |
|     }
 | |
| 
 | |
|     append(name, value) {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'append' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       if (arguments.length < 2) {
 | |
|         throw new globalObject.TypeError(
 | |
|           `Failed to execute 'append' on 'URLSearchParams': 2 arguments required, but only ${arguments.length} present.`
 | |
|         );
 | |
|       }
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'append' on 'URLSearchParams': parameter 1",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       {
 | |
|         let curArg = arguments[1];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'append' on 'URLSearchParams': parameter 2",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return utils.tryWrapperForImpl(esValue[implSymbol].append(...args));
 | |
|     }
 | |
| 
 | |
|     delete(name) {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'delete' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       if (arguments.length < 1) {
 | |
|         throw new globalObject.TypeError(
 | |
|           `Failed to execute 'delete' on 'URLSearchParams': 1 argument required, but only ${arguments.length} present.`
 | |
|         );
 | |
|       }
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'delete' on 'URLSearchParams': parameter 1",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       {
 | |
|         let curArg = arguments[1];
 | |
|         if (curArg !== undefined) {
 | |
|           curArg = conversions["USVString"](curArg, {
 | |
|             context: "Failed to execute 'delete' on 'URLSearchParams': parameter 2",
 | |
|             globals: globalObject
 | |
|           });
 | |
|         }
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return utils.tryWrapperForImpl(esValue[implSymbol].delete(...args));
 | |
|     }
 | |
| 
 | |
|     get(name) {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError("'get' called on an object that is not a valid instance of URLSearchParams.");
 | |
|       }
 | |
| 
 | |
|       if (arguments.length < 1) {
 | |
|         throw new globalObject.TypeError(
 | |
|           `Failed to execute 'get' on 'URLSearchParams': 1 argument required, but only ${arguments.length} present.`
 | |
|         );
 | |
|       }
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'get' on 'URLSearchParams': parameter 1",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return esValue[implSymbol].get(...args);
 | |
|     }
 | |
| 
 | |
|     getAll(name) {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'getAll' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       if (arguments.length < 1) {
 | |
|         throw new globalObject.TypeError(
 | |
|           `Failed to execute 'getAll' on 'URLSearchParams': 1 argument required, but only ${arguments.length} present.`
 | |
|         );
 | |
|       }
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'getAll' on 'URLSearchParams': parameter 1",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return utils.tryWrapperForImpl(esValue[implSymbol].getAll(...args));
 | |
|     }
 | |
| 
 | |
|     has(name) {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError("'has' called on an object that is not a valid instance of URLSearchParams.");
 | |
|       }
 | |
| 
 | |
|       if (arguments.length < 1) {
 | |
|         throw new globalObject.TypeError(
 | |
|           `Failed to execute 'has' on 'URLSearchParams': 1 argument required, but only ${arguments.length} present.`
 | |
|         );
 | |
|       }
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'has' on 'URLSearchParams': parameter 1",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       {
 | |
|         let curArg = arguments[1];
 | |
|         if (curArg !== undefined) {
 | |
|           curArg = conversions["USVString"](curArg, {
 | |
|             context: "Failed to execute 'has' on 'URLSearchParams': parameter 2",
 | |
|             globals: globalObject
 | |
|           });
 | |
|         }
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return esValue[implSymbol].has(...args);
 | |
|     }
 | |
| 
 | |
|     set(name, value) {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError("'set' called on an object that is not a valid instance of URLSearchParams.");
 | |
|       }
 | |
| 
 | |
|       if (arguments.length < 2) {
 | |
|         throw new globalObject.TypeError(
 | |
|           `Failed to execute 'set' on 'URLSearchParams': 2 arguments required, but only ${arguments.length} present.`
 | |
|         );
 | |
|       }
 | |
|       const args = [];
 | |
|       {
 | |
|         let curArg = arguments[0];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'set' on 'URLSearchParams': parameter 1",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       {
 | |
|         let curArg = arguments[1];
 | |
|         curArg = conversions["USVString"](curArg, {
 | |
|           context: "Failed to execute 'set' on 'URLSearchParams': parameter 2",
 | |
|           globals: globalObject
 | |
|         });
 | |
|         args.push(curArg);
 | |
|       }
 | |
|       return utils.tryWrapperForImpl(esValue[implSymbol].set(...args));
 | |
|     }
 | |
| 
 | |
|     sort() {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError("'sort' called on an object that is not a valid instance of URLSearchParams.");
 | |
|       }
 | |
| 
 | |
|       return utils.tryWrapperForImpl(esValue[implSymbol].sort());
 | |
|     }
 | |
| 
 | |
|     toString() {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'toString' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       return esValue[implSymbol].toString();
 | |
|     }
 | |
| 
 | |
|     keys() {
 | |
|       if (!exports.is(this)) {
 | |
|         throw new globalObject.TypeError("'keys' called on an object that is not a valid instance of URLSearchParams.");
 | |
|       }
 | |
|       return exports.createDefaultIterator(globalObject, this, "key");
 | |
|     }
 | |
| 
 | |
|     values() {
 | |
|       if (!exports.is(this)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'values' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
|       return exports.createDefaultIterator(globalObject, this, "value");
 | |
|     }
 | |
| 
 | |
|     entries() {
 | |
|       if (!exports.is(this)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'entries' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
|       return exports.createDefaultIterator(globalObject, this, "key+value");
 | |
|     }
 | |
| 
 | |
|     forEach(callback) {
 | |
|       if (!exports.is(this)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'forEach' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
|       if (arguments.length < 1) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "Failed to execute 'forEach' on 'iterable': 1 argument required, but only 0 present."
 | |
|         );
 | |
|       }
 | |
|       callback = Function.convert(globalObject, callback, {
 | |
|         context: "Failed to execute 'forEach' on 'iterable': The callback provided as parameter 1"
 | |
|       });
 | |
|       const thisArg = arguments[1];
 | |
|       let pairs = Array.from(this[implSymbol]);
 | |
|       let i = 0;
 | |
|       while (i < pairs.length) {
 | |
|         const [key, value] = pairs[i].map(utils.tryWrapperForImpl);
 | |
|         callback.call(thisArg, value, key, this);
 | |
|         pairs = Array.from(this[implSymbol]);
 | |
|         i++;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     get size() {
 | |
|       const esValue = this !== null && this !== undefined ? this : globalObject;
 | |
| 
 | |
|       if (!exports.is(esValue)) {
 | |
|         throw new globalObject.TypeError(
 | |
|           "'get size' called on an object that is not a valid instance of URLSearchParams."
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       return esValue[implSymbol]["size"];
 | |
|     }
 | |
|   }
 | |
|   Object.defineProperties(URLSearchParams.prototype, {
 | |
|     append: { enumerable: true },
 | |
|     delete: { enumerable: true },
 | |
|     get: { enumerable: true },
 | |
|     getAll: { enumerable: true },
 | |
|     has: { enumerable: true },
 | |
|     set: { enumerable: true },
 | |
|     sort: { enumerable: true },
 | |
|     toString: { enumerable: true },
 | |
|     keys: { enumerable: true },
 | |
|     values: { enumerable: true },
 | |
|     entries: { enumerable: true },
 | |
|     forEach: { enumerable: true },
 | |
|     size: { enumerable: true },
 | |
|     [Symbol.toStringTag]: { value: "URLSearchParams", configurable: true },
 | |
|     [Symbol.iterator]: { value: URLSearchParams.prototype.entries, configurable: true, writable: true }
 | |
|   });
 | |
|   ctorRegistry[interfaceName] = URLSearchParams;
 | |
| 
 | |
|   ctorRegistry["URLSearchParams Iterator"] = Object.create(ctorRegistry["%IteratorPrototype%"], {
 | |
|     [Symbol.toStringTag]: {
 | |
|       configurable: true,
 | |
|       value: "URLSearchParams Iterator"
 | |
|     }
 | |
|   });
 | |
|   utils.define(ctorRegistry["URLSearchParams Iterator"], {
 | |
|     next() {
 | |
|       const internal = this && this[utils.iterInternalSymbol];
 | |
|       if (!internal) {
 | |
|         throw new globalObject.TypeError("next() called on a value that is not a URLSearchParams iterator object");
 | |
|       }
 | |
| 
 | |
|       const { target, kind, index } = internal;
 | |
|       const values = Array.from(target[implSymbol]);
 | |
|       const len = values.length;
 | |
|       if (index >= len) {
 | |
|         return newObjectInRealm(globalObject, { value: undefined, done: true });
 | |
|       }
 | |
| 
 | |
|       const pair = values[index];
 | |
|       internal.index = index + 1;
 | |
|       return newObjectInRealm(globalObject, utils.iteratorResult(pair.map(utils.tryWrapperForImpl), kind));
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   Object.defineProperty(globalObject, interfaceName, {
 | |
|     configurable: true,
 | |
|     writable: true,
 | |
|     value: URLSearchParams
 | |
|   });
 | |
| };
 | |
| 
 | |
| const Impl = require("./URLSearchParams-impl.js");
 |