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:
anthonyrawlins
2025-07-11 14:06:34 +10:00
parent c6d69695a8
commit aacb45156b
6109 changed files with 777927 additions and 1 deletions

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _matches = require("../matches");
Object.keys(_matches).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _matches[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _matches[key];
}
});
});
var _getNodeText = require("../get-node-text");
Object.keys(_getNodeText).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _getNodeText[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _getNodeText[key];
}
});
});
var _queryHelpers = require("../query-helpers");
Object.keys(_queryHelpers).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _queryHelpers[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _queryHelpers[key];
}
});
});
var _config = require("../config");
Object.keys(_config).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _config[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _config[key];
}
});
});

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByAltText = exports.queryAllByAltText = exports.getByAltText = exports.getAllByAltText = exports.findByAltText = exports.findAllByAltText = void 0;
var _queryHelpers = require("../query-helpers");
var _helpers = require("../helpers");
var _allUtils = require("./all-utils");
// Valid tags are img, input, area and custom elements
const VALID_TAG_REGEXP = /^(img|input|area|.+-.+)$/i;
const queryAllByAltText = (container, alt, options = {}) => {
(0, _helpers.checkContainerType)(container);
return (0, _queryHelpers.queryAllByAttribute)('alt', container, alt, options).filter(node => VALID_TAG_REGEXP.test(node.tagName));
};
const getMultipleError = (c, alt) => `Found multiple elements with the alt text: ${alt}`;
const getMissingError = (c, alt) => `Unable to find an element with the alt text: ${alt}`;
const queryAllByAltTextWithSuggestions = exports.queryAllByAltText = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByAltText, queryAllByAltText.name, 'queryAll');
const [queryByAltText, getAllByAltText, getByAltText, findAllByAltText, findByAltText] = (0, _allUtils.buildQueries)(queryAllByAltText, getMultipleError, getMissingError);
exports.findByAltText = findByAltText;
exports.findAllByAltText = findAllByAltText;
exports.getByAltText = getByAltText;
exports.getAllByAltText = getAllByAltText;
exports.queryByAltText = queryByAltText;

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByDisplayValue = exports.queryAllByDisplayValue = exports.getByDisplayValue = exports.getAllByDisplayValue = exports.findByDisplayValue = exports.findAllByDisplayValue = void 0;
var _queryHelpers = require("../query-helpers");
var _helpers = require("../helpers");
var _allUtils = require("./all-utils");
const queryAllByDisplayValue = (container, value, {
exact = true,
collapseWhitespace,
trim,
normalizer
} = {}) => {
(0, _helpers.checkContainerType)(container);
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches;
const matchNormalizer = (0, _allUtils.makeNormalizer)({
collapseWhitespace,
trim,
normalizer
});
return Array.from(container.querySelectorAll(`input,textarea,select`)).filter(node => {
if (node.tagName === 'SELECT') {
const selectedOptions = Array.from(node.options).filter(option => option.selected);
return selectedOptions.some(optionNode => matcher((0, _allUtils.getNodeText)(optionNode), optionNode, value, matchNormalizer));
} else {
return matcher(node.value, node, value, matchNormalizer);
}
});
};
const getMultipleError = (c, value) => `Found multiple elements with the display value: ${value}.`;
const getMissingError = (c, value) => `Unable to find an element with the display value: ${value}.`;
const queryAllByDisplayValueWithSuggestions = exports.queryAllByDisplayValue = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByDisplayValue, queryAllByDisplayValue.name, 'queryAll');
const [queryByDisplayValue, getAllByDisplayValue, getByDisplayValue, findAllByDisplayValue, findByDisplayValue] = (0, _allUtils.buildQueries)(queryAllByDisplayValue, getMultipleError, getMissingError);
exports.findByDisplayValue = findByDisplayValue;
exports.findAllByDisplayValue = findAllByDisplayValue;
exports.getByDisplayValue = getByDisplayValue;
exports.getAllByDisplayValue = getAllByDisplayValue;
exports.queryByDisplayValue = queryByDisplayValue;

View File

@@ -0,0 +1,93 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _labelText = require("./label-text");
Object.keys(_labelText).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _labelText[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _labelText[key];
}
});
});
var _placeholderText = require("./placeholder-text");
Object.keys(_placeholderText).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _placeholderText[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _placeholderText[key];
}
});
});
var _text = require("./text");
Object.keys(_text).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _text[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _text[key];
}
});
});
var _displayValue = require("./display-value");
Object.keys(_displayValue).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _displayValue[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _displayValue[key];
}
});
});
var _altText = require("./alt-text");
Object.keys(_altText).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _altText[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _altText[key];
}
});
});
var _title = require("./title");
Object.keys(_title).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _title[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _title[key];
}
});
});
var _role = require("./role");
Object.keys(_role).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _role[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _role[key];
}
});
});
var _testId = require("./test-id");
Object.keys(_testId).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _testId[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _testId[key];
}
});
});

View File

@@ -0,0 +1,133 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByLabelText = exports.queryAllByLabelText = exports.getByLabelText = exports.getAllByLabelText = exports.findByLabelText = exports.findAllByLabelText = void 0;
var _config = require("../config");
var _helpers = require("../helpers");
var _labelHelpers = require("../label-helpers");
var _allUtils = require("./all-utils");
function queryAllLabels(container) {
return Array.from(container.querySelectorAll('label,input')).map(node => {
return {
node,
textToMatch: (0, _labelHelpers.getLabelContent)(node)
};
}).filter(({
textToMatch
}) => textToMatch !== null);
}
const queryAllLabelsByText = (container, text, {
exact = true,
trim,
collapseWhitespace,
normalizer
} = {}) => {
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches;
const matchNormalizer = (0, _allUtils.makeNormalizer)({
collapseWhitespace,
trim,
normalizer
});
const textToMatchByLabels = queryAllLabels(container);
return textToMatchByLabels.filter(({
node,
textToMatch
}) => matcher(textToMatch, node, text, matchNormalizer)).map(({
node
}) => node);
};
const queryAllByLabelText = (container, text, {
selector = '*',
exact = true,
collapseWhitespace,
trim,
normalizer
} = {}) => {
(0, _helpers.checkContainerType)(container);
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches;
const matchNormalizer = (0, _allUtils.makeNormalizer)({
collapseWhitespace,
trim,
normalizer
});
const matchingLabelledElements = Array.from(container.querySelectorAll('*')).filter(element => {
return (0, _labelHelpers.getRealLabels)(element).length || element.hasAttribute('aria-labelledby');
}).reduce((labelledElements, labelledElement) => {
const labelList = (0, _labelHelpers.getLabels)(container, labelledElement, {
selector
});
labelList.filter(label => Boolean(label.formControl)).forEach(label => {
if (matcher(label.content, label.formControl, text, matchNormalizer) && label.formControl) {
labelledElements.push(label.formControl);
}
});
const labelsValue = labelList.filter(label => Boolean(label.content)).map(label => label.content);
if (matcher(labelsValue.join(' '), labelledElement, text, matchNormalizer)) {
labelledElements.push(labelledElement);
}
if (labelsValue.length > 1) {
labelsValue.forEach((labelValue, index) => {
if (matcher(labelValue, labelledElement, text, matchNormalizer)) {
labelledElements.push(labelledElement);
}
const labelsFiltered = [...labelsValue];
labelsFiltered.splice(index, 1);
if (labelsFiltered.length > 1) {
if (matcher(labelsFiltered.join(' '), labelledElement, text, matchNormalizer)) {
labelledElements.push(labelledElement);
}
}
});
}
return labelledElements;
}, []).concat((0, _allUtils.queryAllByAttribute)('aria-label', container, text, {
exact,
normalizer: matchNormalizer
}));
return Array.from(new Set(matchingLabelledElements)).filter(element => element.matches(selector));
};
// the getAll* query would normally look like this:
// const getAllByLabelText = makeGetAllQuery(
// queryAllByLabelText,
// (c, text) => `Unable to find a label with the text of: ${text}`,
// )
// however, we can give a more helpful error message than the generic one,
// so we're writing this one out by hand.
const getAllByLabelText = (container, text, ...rest) => {
const els = queryAllByLabelText(container, text, ...rest);
if (!els.length) {
const labels = queryAllLabelsByText(container, text, ...rest);
if (labels.length) {
const tagNames = labels.map(label => getTagNameOfElementAssociatedWithLabelViaFor(container, label)).filter(tagName => !!tagName);
if (tagNames.length) {
throw (0, _config.getConfig)().getElementError(tagNames.map(tagName => `Found a label with the text of: ${text}, however the element associated with this label (<${tagName} />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <${tagName} />, you can use aria-label or aria-labelledby instead.`).join('\n\n'), container);
} else {
throw (0, _config.getConfig)().getElementError(`Found a label with the text of: ${text}, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.`, container);
}
} else {
throw (0, _config.getConfig)().getElementError(`Unable to find a label with the text of: ${text}`, container);
}
}
return els;
};
function getTagNameOfElementAssociatedWithLabelViaFor(container, label) {
const htmlFor = label.getAttribute('for');
if (!htmlFor) {
return null;
}
const element = container.querySelector(`[id="${htmlFor}"]`);
return element ? element.tagName.toLowerCase() : null;
}
// the reason mentioned above is the same reason we're not using buildQueries
const getMultipleError = (c, text) => `Found multiple elements with the text of: ${text}`;
const queryByLabelText = exports.queryByLabelText = (0, _allUtils.wrapSingleQueryWithSuggestion)((0, _allUtils.makeSingleQuery)(queryAllByLabelText, getMultipleError), queryAllByLabelText.name, 'query');
const getByLabelText = (0, _allUtils.makeSingleQuery)(getAllByLabelText, getMultipleError);
const findAllByLabelText = exports.findAllByLabelText = (0, _allUtils.makeFindQuery)((0, _allUtils.wrapAllByQueryWithSuggestion)(getAllByLabelText, getAllByLabelText.name, 'findAll'));
const findByLabelText = exports.findByLabelText = (0, _allUtils.makeFindQuery)((0, _allUtils.wrapSingleQueryWithSuggestion)(getByLabelText, getAllByLabelText.name, 'find'));
const getAllByLabelTextWithSuggestions = exports.getAllByLabelText = (0, _allUtils.wrapAllByQueryWithSuggestion)(getAllByLabelText, getAllByLabelText.name, 'getAll');
const getByLabelTextWithSuggestions = exports.getByLabelText = (0, _allUtils.wrapSingleQueryWithSuggestion)(getByLabelText, getAllByLabelText.name, 'get');
const queryAllByLabelTextWithSuggestions = exports.queryAllByLabelText = (0, _allUtils.wrapAllByQueryWithSuggestion)(queryAllByLabelText, queryAllByLabelText.name, 'queryAll');

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByPlaceholderText = exports.queryAllByPlaceholderText = exports.getByPlaceholderText = exports.getAllByPlaceholderText = exports.findByPlaceholderText = exports.findAllByPlaceholderText = void 0;
var _queryHelpers = require("../query-helpers");
var _helpers = require("../helpers");
var _allUtils = require("./all-utils");
const queryAllByPlaceholderText = (...args) => {
(0, _helpers.checkContainerType)(args[0]);
return (0, _allUtils.queryAllByAttribute)('placeholder', ...args);
};
const getMultipleError = (c, text) => `Found multiple elements with the placeholder text of: ${text}`;
const getMissingError = (c, text) => `Unable to find an element with the placeholder text of: ${text}`;
const queryAllByPlaceholderTextWithSuggestions = exports.queryAllByPlaceholderText = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByPlaceholderText, queryAllByPlaceholderText.name, 'queryAll');
const [queryByPlaceholderText, getAllByPlaceholderText, getByPlaceholderText, findAllByPlaceholderText, findByPlaceholderText] = (0, _allUtils.buildQueries)(queryAllByPlaceholderText, getMultipleError, getMissingError);
exports.findByPlaceholderText = findByPlaceholderText;
exports.findAllByPlaceholderText = findAllByPlaceholderText;
exports.getByPlaceholderText = getByPlaceholderText;
exports.getAllByPlaceholderText = getAllByPlaceholderText;
exports.queryByPlaceholderText = queryByPlaceholderText;

View File

@@ -0,0 +1,274 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByRole = exports.queryAllByRole = exports.getByRole = exports.getAllByRole = exports.findByRole = exports.findAllByRole = void 0;
var _domAccessibilityApi = require("dom-accessibility-api");
var _ariaQuery = require("aria-query");
var _roleHelpers = require("../role-helpers");
var _queryHelpers = require("../query-helpers");
var _helpers = require("../helpers");
var _allUtils = require("./all-utils");
/* eslint-disable complexity */
const queryAllByRole = (container, role, {
hidden = (0, _allUtils.getConfig)().defaultHidden,
name,
description,
queryFallbacks = false,
selected,
busy,
checked,
pressed,
current,
level,
expanded,
value: {
now: valueNow,
min: valueMin,
max: valueMax,
text: valueText
} = {}
} = {}) => {
(0, _helpers.checkContainerType)(container);
if (selected !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-selected'] === undefined) {
throw new Error(`"aria-selected" is not supported on role "${role}".`);
}
}
if (busy !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-busy'] === undefined) {
throw new Error(`"aria-busy" is not supported on role "${role}".`);
}
}
if (checked !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-checked'] === undefined) {
throw new Error(`"aria-checked" is not supported on role "${role}".`);
}
}
if (pressed !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-pressed'] === undefined) {
throw new Error(`"aria-pressed" is not supported on role "${role}".`);
}
}
if (current !== undefined) {
/* istanbul ignore next */
// guard against unknown roles
// All currently released ARIA versions support `aria-current` on all roles.
// Leaving this for symmetry and forward compatibility
if (_ariaQuery.roles.get(role)?.props['aria-current'] === undefined) {
throw new Error(`"aria-current" is not supported on role "${role}".`);
}
}
if (level !== undefined) {
// guard against using `level` option with any role other than `heading`
if (role !== 'heading') {
throw new Error(`Role "${role}" cannot have "level" property.`);
}
}
if (valueNow !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-valuenow'] === undefined) {
throw new Error(`"aria-valuenow" is not supported on role "${role}".`);
}
}
if (valueMax !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-valuemax'] === undefined) {
throw new Error(`"aria-valuemax" is not supported on role "${role}".`);
}
}
if (valueMin !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-valuemin'] === undefined) {
throw new Error(`"aria-valuemin" is not supported on role "${role}".`);
}
}
if (valueText !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-valuetext'] === undefined) {
throw new Error(`"aria-valuetext" is not supported on role "${role}".`);
}
}
if (expanded !== undefined) {
// guard against unknown roles
if (_ariaQuery.roles.get(role)?.props['aria-expanded'] === undefined) {
throw new Error(`"aria-expanded" is not supported on role "${role}".`);
}
}
const subtreeIsInaccessibleCache = new WeakMap();
function cachedIsSubtreeInaccessible(element) {
if (!subtreeIsInaccessibleCache.has(element)) {
subtreeIsInaccessibleCache.set(element, (0, _roleHelpers.isSubtreeInaccessible)(element));
}
return subtreeIsInaccessibleCache.get(element);
}
return Array.from(container.querySelectorAll(
// Only query elements that can be matched by the following filters
makeRoleSelector(role))).filter(node => {
const isRoleSpecifiedExplicitly = node.hasAttribute('role');
if (isRoleSpecifiedExplicitly) {
const roleValue = node.getAttribute('role');
if (queryFallbacks) {
return roleValue.split(' ').filter(Boolean).some(roleAttributeToken => roleAttributeToken === role);
}
// other wise only send the first token to match
const [firstRoleAttributeToken] = roleValue.split(' ');
return firstRoleAttributeToken === role;
}
const implicitRoles = (0, _roleHelpers.getImplicitAriaRoles)(node);
return implicitRoles.some(implicitRole => {
return implicitRole === role;
});
}).filter(element => {
if (selected !== undefined) {
return selected === (0, _roleHelpers.computeAriaSelected)(element);
}
if (busy !== undefined) {
return busy === (0, _roleHelpers.computeAriaBusy)(element);
}
if (checked !== undefined) {
return checked === (0, _roleHelpers.computeAriaChecked)(element);
}
if (pressed !== undefined) {
return pressed === (0, _roleHelpers.computeAriaPressed)(element);
}
if (current !== undefined) {
return current === (0, _roleHelpers.computeAriaCurrent)(element);
}
if (expanded !== undefined) {
return expanded === (0, _roleHelpers.computeAriaExpanded)(element);
}
if (level !== undefined) {
return level === (0, _roleHelpers.computeHeadingLevel)(element);
}
if (valueNow !== undefined || valueMax !== undefined || valueMin !== undefined || valueText !== undefined) {
let valueMatches = true;
if (valueNow !== undefined) {
valueMatches &&= valueNow === (0, _roleHelpers.computeAriaValueNow)(element);
}
if (valueMax !== undefined) {
valueMatches &&= valueMax === (0, _roleHelpers.computeAriaValueMax)(element);
}
if (valueMin !== undefined) {
valueMatches &&= valueMin === (0, _roleHelpers.computeAriaValueMin)(element);
}
if (valueText !== undefined) {
valueMatches &&= (0, _allUtils.matches)((0, _roleHelpers.computeAriaValueText)(element) ?? null, element, valueText, text => text);
}
return valueMatches;
}
// don't care if aria attributes are unspecified
return true;
}).filter(element => {
if (name === undefined) {
// Don't care
return true;
}
return (0, _allUtils.matches)((0, _domAccessibilityApi.computeAccessibleName)(element, {
computedStyleSupportsPseudoElements: (0, _allUtils.getConfig)().computedStyleSupportsPseudoElements
}), element, name, text => text);
}).filter(element => {
if (description === undefined) {
// Don't care
return true;
}
return (0, _allUtils.matches)((0, _domAccessibilityApi.computeAccessibleDescription)(element, {
computedStyleSupportsPseudoElements: (0, _allUtils.getConfig)().computedStyleSupportsPseudoElements
}), element, description, text => text);
}).filter(element => {
return hidden === false ? (0, _roleHelpers.isInaccessible)(element, {
isSubtreeInaccessible: cachedIsSubtreeInaccessible
}) === false : true;
});
};
function makeRoleSelector(role) {
const explicitRoleSelector = `*[role~="${role}"]`;
const roleRelations = _ariaQuery.roleElements.get(role) ?? new Set();
const implicitRoleSelectors = new Set(Array.from(roleRelations).map(({
name
}) => name));
// Current transpilation config sometimes assumes `...` is always applied to arrays.
// `...` is equivalent to `Array.prototype.concat` for arrays.
// If you replace this code with `[explicitRoleSelector, ...implicitRoleSelectors]`, make sure every transpilation target retains the `...` in favor of `Array.prototype.concat`.
return [explicitRoleSelector].concat(Array.from(implicitRoleSelectors)).join(',');
}
const getNameHint = name => {
let nameHint = '';
if (name === undefined) {
nameHint = '';
} else if (typeof name === 'string') {
nameHint = ` and name "${name}"`;
} else {
nameHint = ` and name \`${name}\``;
}
return nameHint;
};
const getMultipleError = (c, role, {
name
} = {}) => {
return `Found multiple elements with the role "${role}"${getNameHint(name)}`;
};
const getMissingError = (container, role, {
hidden = (0, _allUtils.getConfig)().defaultHidden,
name,
description
} = {}) => {
if ((0, _allUtils.getConfig)()._disableExpensiveErrorDiagnostics) {
return `Unable to find role="${role}"${getNameHint(name)}`;
}
let roles = '';
Array.from(container.children).forEach(childElement => {
roles += (0, _roleHelpers.prettyRoles)(childElement, {
hidden,
includeDescription: description !== undefined
});
});
let roleMessage;
if (roles.length === 0) {
if (hidden === false) {
roleMessage = 'There are no accessible roles. But there might be some inaccessible roles. ' + 'If you wish to access them, then set the `hidden` option to `true`. ' + 'Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole';
} else {
roleMessage = 'There are no available roles.';
}
} else {
roleMessage = `
Here are the ${hidden === false ? 'accessible' : 'available'} roles:
${roles.replace(/\n/g, '\n ').replace(/\n\s\s\n/g, '\n\n')}
`.trim();
}
let nameHint = '';
if (name === undefined) {
nameHint = '';
} else if (typeof name === 'string') {
nameHint = ` and name "${name}"`;
} else {
nameHint = ` and name \`${name}\``;
}
let descriptionHint = '';
if (description === undefined) {
descriptionHint = '';
} else if (typeof description === 'string') {
descriptionHint = ` and description "${description}"`;
} else {
descriptionHint = ` and description \`${description}\``;
}
return `
Unable to find an ${hidden === false ? 'accessible ' : ''}element with the role "${role}"${nameHint}${descriptionHint}
${roleMessage}`.trim();
};
const queryAllByRoleWithSuggestions = exports.queryAllByRole = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByRole, queryAllByRole.name, 'queryAll');
const [queryByRole, getAllByRole, getByRole, findAllByRole, findByRole] = (0, _allUtils.buildQueries)(queryAllByRole, getMultipleError, getMissingError);
exports.findByRole = findByRole;
exports.findAllByRole = findAllByRole;
exports.getByRole = getByRole;
exports.getAllByRole = getAllByRole;
exports.queryByRole = queryByRole;

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByTestId = exports.queryAllByTestId = exports.getByTestId = exports.getAllByTestId = exports.findByTestId = exports.findAllByTestId = void 0;
var _helpers = require("../helpers");
var _queryHelpers = require("../query-helpers");
var _allUtils = require("./all-utils");
const getTestIdAttribute = () => (0, _allUtils.getConfig)().testIdAttribute;
const queryAllByTestId = (...args) => {
(0, _helpers.checkContainerType)(args[0]);
return (0, _allUtils.queryAllByAttribute)(getTestIdAttribute(), ...args);
};
const getMultipleError = (c, id) => `Found multiple elements by: [${getTestIdAttribute()}="${id}"]`;
const getMissingError = (c, id) => `Unable to find an element by: [${getTestIdAttribute()}="${id}"]`;
const queryAllByTestIdWithSuggestions = exports.queryAllByTestId = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByTestId, queryAllByTestId.name, 'queryAll');
const [queryByTestId, getAllByTestId, getByTestId, findAllByTestId, findByTestId] = (0, _allUtils.buildQueries)(queryAllByTestId, getMultipleError, getMissingError);
exports.findByTestId = findByTestId;
exports.findAllByTestId = findAllByTestId;
exports.getByTestId = getByTestId;
exports.getAllByTestId = getAllByTestId;
exports.queryByTestId = queryByTestId;

View File

@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByText = exports.queryAllByText = exports.getByText = exports.getAllByText = exports.findByText = exports.findAllByText = void 0;
var _queryHelpers = require("../query-helpers");
var _helpers = require("../helpers");
var _allUtils = require("./all-utils");
const queryAllByText = (container, text, {
selector = '*',
exact = true,
collapseWhitespace,
trim,
ignore = (0, _allUtils.getConfig)().defaultIgnore,
normalizer
} = {}) => {
(0, _helpers.checkContainerType)(container);
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches;
const matchNormalizer = (0, _allUtils.makeNormalizer)({
collapseWhitespace,
trim,
normalizer
});
let baseArray = [];
if (typeof container.matches === 'function' && container.matches(selector)) {
baseArray = [container];
}
return [...baseArray, ...Array.from(container.querySelectorAll(selector))]
// TODO: `matches` according lib.dom.d.ts can get only `string` but according our code it can handle also boolean :)
.filter(node => !ignore || !node.matches(ignore)).filter(node => matcher((0, _allUtils.getNodeText)(node), node, text, matchNormalizer));
};
const getMultipleError = (c, text) => `Found multiple elements with the text: ${text}`;
const getMissingError = (c, text, options = {}) => {
const {
collapseWhitespace,
trim,
normalizer,
selector
} = options;
const matchNormalizer = (0, _allUtils.makeNormalizer)({
collapseWhitespace,
trim,
normalizer
});
const normalizedText = matchNormalizer(text.toString());
const isNormalizedDifferent = normalizedText !== text.toString();
const isCustomSelector = (selector ?? '*') !== '*';
return `Unable to find an element with the text: ${isNormalizedDifferent ? `${normalizedText} (normalized from '${text}')` : text}${isCustomSelector ? `, which matches selector '${selector}'` : ''}. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.`;
};
const queryAllByTextWithSuggestions = exports.queryAllByText = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByText, queryAllByText.name, 'queryAll');
const [queryByText, getAllByText, getByText, findAllByText, findByText] = (0, _allUtils.buildQueries)(queryAllByText, getMultipleError, getMissingError);
exports.findByText = findByText;
exports.findAllByText = findAllByText;
exports.getByText = getByText;
exports.getAllByText = getAllByText;
exports.queryByText = queryByText;

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queryByTitle = exports.queryAllByTitle = exports.getByTitle = exports.getAllByTitle = exports.findByTitle = exports.findAllByTitle = void 0;
var _queryHelpers = require("../query-helpers");
var _helpers = require("../helpers");
var _allUtils = require("./all-utils");
const isSvgTitle = node => node.tagName.toLowerCase() === 'title' && node.parentElement?.tagName.toLowerCase() === 'svg';
const queryAllByTitle = (container, text, {
exact = true,
collapseWhitespace,
trim,
normalizer
} = {}) => {
(0, _helpers.checkContainerType)(container);
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches;
const matchNormalizer = (0, _allUtils.makeNormalizer)({
collapseWhitespace,
trim,
normalizer
});
return Array.from(container.querySelectorAll('[title], svg > title')).filter(node => matcher(node.getAttribute('title'), node, text, matchNormalizer) || isSvgTitle(node) && matcher((0, _allUtils.getNodeText)(node), node, text, matchNormalizer));
};
const getMultipleError = (c, title) => `Found multiple elements with the title: ${title}.`;
const getMissingError = (c, title) => `Unable to find an element with the title: ${title}.`;
const queryAllByTitleWithSuggestions = exports.queryAllByTitle = (0, _queryHelpers.wrapAllByQueryWithSuggestion)(queryAllByTitle, queryAllByTitle.name, 'queryAll');
const [queryByTitle, getAllByTitle, getByTitle, findAllByTitle, findByTitle] = (0, _allUtils.buildQueries)(queryAllByTitle, getMultipleError, getMissingError);
exports.findByTitle = findByTitle;
exports.findAllByTitle = findAllByTitle;
exports.getByTitle = getByTitle;
exports.getAllByTitle = getAllByTitle;
exports.queryByTitle = queryByTitle;