UNPKG

@testing-library/react-native

Version:

Simple and complete React Native testing utilities that encourage good testing practices.

102 lines (98 loc) 4.06 kB
"use strict"; 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