- 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>
80 lines
3.4 KiB
JavaScript
80 lines
3.4 KiB
JavaScript
const UIValue = Symbol('Displayed value in UI');
|
|
const UISelection = Symbol('Displayed selection in UI');
|
|
const InitialValue = Symbol('Initial value to compare on blur');
|
|
function isUIValue(value) {
|
|
return typeof value === 'object' && UIValue in value;
|
|
}
|
|
function isUISelectionStart(start) {
|
|
return !!start && typeof start === 'object' && UISelection in start;
|
|
}
|
|
function setUIValue(element, value) {
|
|
if (element[InitialValue] === undefined) {
|
|
element[InitialValue] = element.value;
|
|
}
|
|
element[UIValue] = value;
|
|
// eslint-disable-next-line no-new-wrappers
|
|
element.value = Object.assign(new String(value), {
|
|
[UIValue]: true
|
|
});
|
|
}
|
|
function getUIValue(element) {
|
|
return element[UIValue] === undefined ? element.value : String(element[UIValue]);
|
|
}
|
|
/** Flag the IDL value as clean. This does not change the value.*/ function setUIValueClean(element) {
|
|
element[UIValue] = undefined;
|
|
}
|
|
function clearInitialValue(element) {
|
|
element[InitialValue] = undefined;
|
|
}
|
|
function getInitialValue(element) {
|
|
return element[InitialValue];
|
|
}
|
|
function setUISelectionRaw(element, selection) {
|
|
element[UISelection] = selection;
|
|
}
|
|
function setUISelection(element, { focusOffset: focusOffsetParam, anchorOffset: anchorOffsetParam = focusOffsetParam }, mode = 'replace') {
|
|
const valueLength = getUIValue(element).length;
|
|
const sanitizeOffset = (o)=>Math.max(0, Math.min(valueLength, o));
|
|
const anchorOffset = mode === 'replace' || element[UISelection] === undefined ? sanitizeOffset(anchorOffsetParam) : element[UISelection].anchorOffset;
|
|
const focusOffset = sanitizeOffset(focusOffsetParam);
|
|
const startOffset = Math.min(anchorOffset, focusOffset);
|
|
const endOffset = Math.max(anchorOffset, focusOffset);
|
|
element[UISelection] = {
|
|
anchorOffset,
|
|
focusOffset
|
|
};
|
|
if (element.selectionStart === startOffset && element.selectionEnd === endOffset) {
|
|
return;
|
|
}
|
|
// eslint-disable-next-line no-new-wrappers
|
|
const startObj = Object.assign(new Number(startOffset), {
|
|
[UISelection]: true
|
|
});
|
|
try {
|
|
element.setSelectionRange(startObj, endOffset);
|
|
} catch {
|
|
// DOMException for invalid state is expected when calling this
|
|
// on an element without support for setSelectionRange
|
|
}
|
|
}
|
|
function getUISelection(element) {
|
|
var _element_selectionStart, _element_selectionEnd, _element_UISelection;
|
|
const sel = (_element_UISelection = element[UISelection]) !== null && _element_UISelection !== undefined ? _element_UISelection : {
|
|
anchorOffset: (_element_selectionStart = element.selectionStart) !== null && _element_selectionStart !== undefined ? _element_selectionStart : 0,
|
|
focusOffset: (_element_selectionEnd = element.selectionEnd) !== null && _element_selectionEnd !== undefined ? _element_selectionEnd : 0
|
|
};
|
|
return {
|
|
...sel,
|
|
startOffset: Math.min(sel.anchorOffset, sel.focusOffset),
|
|
endOffset: Math.max(sel.anchorOffset, sel.focusOffset)
|
|
};
|
|
}
|
|
function hasUISelection(element) {
|
|
return !!element[UISelection];
|
|
}
|
|
/** Flag the IDL selection as clean. This does not change the selection. */ function setUISelectionClean(element) {
|
|
element[UISelection] = undefined;
|
|
}
|
|
|
|
export { clearInitialValue, getInitialValue, getUISelection, getUIValue, hasUISelection, isUISelectionStart, isUIValue, setUISelection, setUISelectionClean, setUISelectionRaw, setUIValue, setUIValueClean };
|