@testing-library/react-native
Version:
Simple and complete React Native testing utilities that encourage good testing practices.
102 lines (98 loc) • 4.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.emitTypingEvents = emitTypingEvents;
exports.type = type;
var _errors = require("../../helpers/errors");
var _hostComponentNames = require("../../helpers/host-component-names");
var _pointerEvents = require("../../helpers/pointer-events");
var _textInput = require("../../helpers/text-input");
var _nativeState = require("../../native-state");
var _eventBuilder = require("../event-builder");
var _utils = require("../utils");
var _parseKeys = require("./parse-keys");
async function type(element, text, options) {
if (!(0, _hostComponentNames.isHostTextInput)(element)) {
throw new _errors.ErrorWithStack(`type() works only with host "TextInput" elements. Passed element has type "${element.type}".`, type);
}
// Skip events if the element is disabled
if (!(0, _textInput.isEditableTextInput)(element) || !(0, _pointerEvents.isPointerEventEnabled)(element)) {
return;
}
const keys = (0, _parseKeys.parseKeys)(text);
if (!options?.skipPress) {
(0, _utils.dispatchEvent)(element, 'pressIn', _eventBuilder.EventBuilder.Common.touch());
}
(0, _utils.dispatchEvent)(element, 'focus', _eventBuilder.EventBuilder.Common.focus());
if (!options?.skipPress) {
await (0, _utils.wait)(this.config);
(0, _utils.dispatchEvent)(element, 'pressOut', _eventBuilder.EventBuilder.Common.touch());
}
let currentText = (0, _textInput.getTextInputValue)(element);
for (const key of keys) {
const previousText = (0, _textInput.getTextInputValue)(element);
const proposedText = applyKey(previousText, key);
const isAccepted = isTextChangeAccepted(element, proposedText);
currentText = isAccepted ? proposedText : previousText;
await emitTypingEvents(element, {
config: this.config,
key,
text: currentText,
isAccepted
});
}
const finalText = (0, _textInput.getTextInputValue)(element);
await (0, _utils.wait)(this.config);
if (options?.submitEditing) {
(0, _utils.dispatchEvent)(element, 'submitEditing', _eventBuilder.EventBuilder.TextInput.submitEditing(finalText));
}
if (!options?.skipBlur) {
(0, _utils.dispatchEvent)(element, 'endEditing', _eventBuilder.EventBuilder.TextInput.endEditing(finalText));
(0, _utils.dispatchEvent)(element, 'blur', _eventBuilder.EventBuilder.Common.blur());
}
}
async function emitTypingEvents(element, {
config,
key,
text,
isAccepted
}) {
const isMultiline = element.props.multiline === true;
await (0, _utils.wait)(config);
(0, _utils.dispatchEvent)(element, 'keyPress', _eventBuilder.EventBuilder.TextInput.keyPress(key));
// Platform difference (based on experiments):
// - iOS and RN Web: TextInput emits only `keyPress` event when max length has been reached
// - Android: TextInputs does not emit any events
if (isAccepted === false) {
return;
}
_nativeState.nativeState.valueForElement.set(element, text);
(0, _utils.dispatchEvent)(element, 'change', _eventBuilder.EventBuilder.TextInput.change(text));
(0, _utils.dispatchEvent)(element, 'changeText', text);
const selectionRange = {
start: text.length,
end: text.length
};
(0, _utils.dispatchEvent)(element, 'selectionChange', _eventBuilder.EventBuilder.TextInput.selectionChange(selectionRange));
// According to the docs only multiline TextInput emits contentSizeChange event
// @see: https://reactnative.dev/docs/textinput#oncontentsizechange
if (isMultiline) {
const contentSize = (0, _utils.getTextContentSize)(text);
(0, _utils.dispatchEvent)(element, 'contentSizeChange', _eventBuilder.EventBuilder.TextInput.contentSizeChange(contentSize));
}
}
function applyKey(text, key) {
if (key === 'Enter') {
return `${text}\n`;
}
if (key === 'Backspace') {
return text.slice(0, -1);
}
return text + key;
}
function isTextChangeAccepted(element, text) {
const maxLength = element.props.maxLength;
return maxLength === undefined || text.length <= maxLength;
}
//# sourceMappingURL=type.js.map