the-forest/client/node_modules/@testing-library/dom/dist/queries/label-text.js
2024-09-17 20:35:18 -04:00

133 lines
6.2 KiB
JavaScript

"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');