@enact/sandstone
Version:
Large-screen/TV support library for Enact, containing a variety of UI components.
529 lines (527 loc) • 22.1 kB
JavaScript
"use strict";
var _FloatingLayer = require("@enact/ui/FloatingLayer");
require("@testing-library/jest-dom");
var _react = require("@testing-library/react");
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
var _Input = _interopRequireDefault(require("../Input"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
var FloatingLayerController = (0, _FloatingLayer.FloatingLayerDecorator)('div');
describe('Input specs', function () {
test('should be rendered opened if open is set to true', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true
})
}));
var actual = _react.screen.getAllByLabelText('- Input field')[0].parentElement.nextElementSibling.children.length > 0;
expect(actual).toBeTruthy();
});
test('should set title when there is title text', function () {
var str = 'title text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true,
title: str
})
}));
var titleField = _react.screen.getByText(str).parentElement.parentElement;
var expected = 'title';
expect(titleField).toBeInTheDocument();
expect(titleField).toHaveClass(expected);
});
test('should set title below when there is title below text', function () {
var str = 'title below text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true,
subtitle: str
})
}));
var subtitleField = _react.screen.getByText(str).parentElement.parentElement;
var expected = 'subtitle';
expect(subtitleField).toBeInTheDocument();
expect(subtitleField).toHaveClass(expected);
});
test('should set value at input when there is value text', function () {
var str = 'value text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true,
value: str
})
}));
var inputField = _react.screen.getByPlaceholderText('-');
expect(inputField).toHaveValue(str);
});
test('should set placeholder at input when there is placeholder text', function () {
var str = 'placeholder text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true,
placeholder: str
})
}));
var inputField = _react.screen.getByPlaceholderText(str);
var expectedAttribute = 'placeholder';
expect(inputField).toHaveAttribute(expectedAttribute, str);
});
test('should set type to password at input when input type is `password`', function () {
var str = 'placeholder text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true,
placeholder: str,
type: "password"
})
}));
var inputField = _react.screen.getByPlaceholderText(str);
var expectedAttribute = 'type';
var expectedValue = 'password';
expect(inputField).toHaveAttribute(expectedAttribute, expectedValue);
});
test('should set `spellcheck=false` attribute when type is `password`', function () {
var str = 'placeholder text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
placeholder: str,
open: true,
type: "password"
})
}));
var inputField = _react.screen.getByPlaceholderText(str);
var expectedAttribute = 'spellcheck';
var expectedValue = 'false';
expect(inputField).toHaveAttribute(expectedAttribute, expectedValue);
});
test('should set type to url at input when input type is `url`', function () {
var str = 'placeholder text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
open: true,
placeholder: str,
type: "url"
})
}));
var inputField = _react.screen.getByPlaceholderText(str);
var expectedAttribute = 'type';
var expectedValue = 'url';
expect(inputField).toHaveAttribute(expectedAttribute, expectedValue);
});
test('should set disabled at button when popup is disabled', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
disabled: true
}));
var buttonInput = _react.screen.getByRole('button');
var expectedAttribute = 'aria-disabled';
var expectedValue = 'true';
expect(buttonInput).toHaveAttribute(expectedAttribute, expectedValue);
});
test('should fire `onOpenPopup` and `onShow` with type when open', /*#__PURE__*/_asyncToGenerator(function* () {
var handleOpenPopup = jest.fn();
var handleShow = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
onOpenPopup: handleOpenPopup,
onShow: handleShow
})
}));
yield user.click(_react.screen.getByRole('button'));
var openExpected = {
type: 'onOpenPopup'
};
var openActual = handleOpenPopup.mock.calls.length && handleOpenPopup.mock.calls[0][0];
var showExpected = {
type: 'onShow'
};
var showActual = handleShow.mock.calls.length && handleShow.mock.calls[0][0];
expect(openActual).toMatchObject(openExpected);
expect(showActual).toMatchObject(showExpected);
}));
test('should fire `onBeforeChange` and `onChange` with type when value changed', /*#__PURE__*/_asyncToGenerator(function* () {
var handleBeforeChange = jest.fn();
var handleChange = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
onBeforeChange: handleBeforeChange,
onChange: handleChange,
open: true
})
}));
yield user.type(_react.screen.getByPlaceholderText('-'), 'a');
var beforeExpected = {
type: 'onBeforeChange'
};
var beforeActual = handleBeforeChange.mock.calls.length && handleBeforeChange.mock.calls[0][0];
var changeExpected = {
type: 'onChange'
};
var changeActual = handleChange.mock.calls.length && handleChange.mock.calls[0][0];
expect(beforeActual).toMatchObject(beforeExpected);
expect(changeActual).toMatchObject(changeExpected);
}));
test('should fire `onClose` and `onComplete` with type when enter key pressed', function () {
var handleClose = jest.fn();
var handleComplete = jest.fn();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
onClose: handleClose,
onComplete: handleComplete,
open: true
})
}));
_react.fireEvent.keyDown(_react.screen.getByPlaceholderText('-'), {
keyCode: 13
});
var closeExpected = {
type: 'onClose'
};
var closeActual = handleClose.mock.calls.length && handleClose.mock.calls[0][0];
var completeExpected = {
type: 'onComplete'
};
var completeActual = handleComplete.mock.calls.length && handleComplete.mock.calls[0][0];
expect(closeActual).toMatchObject(closeExpected);
expect(completeActual).toMatchObject(completeExpected);
});
// Type = number
describe('of type number', function () {
test('should be rendered opened if open is set to true', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 4
})
}));
var actual = _react.screen.getAllByLabelText('- Input field')[0].parentElement.nextElementSibling.children.length > 0;
expect(actual).toBeTruthy();
});
test('should set title when there is title text', function () {
var str = 'title text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 4,
title: str
})
}));
var titleField = _react.screen.getByText(str).parentElement.parentElement;
var expected = 'title';
expect(titleField).toBeInTheDocument();
expect(titleField).toHaveClass(expected);
});
test('should set title below when there is title below text', function () {
var str = 'title below text';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 4,
subtitle: str
})
}));
var subtitleField = _react.screen.getByText(str).parentElement.parentElement;
var expected = 'subtitle';
expect(subtitleField).toBeInTheDocument();
expect(subtitleField).toHaveClass(expected);
});
test('should set value at input when there is value text', function () {
var str = '1234';
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 4,
value: str
})
}));
var expected = str;
var actual = _react.screen.getByRole('list').textContent;
expect(actual).toBe(expected);
});
test('should set disabled at button when the component is disabled', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
length: 4,
disabled: true
}));
var buttonInput = _react.screen.getByRole('button');
var expectedAttribute = 'aria-disabled';
var expectedValue = 'true';
expect(buttonInput).toHaveAttribute(expectedAttribute, expectedValue);
});
test('should not be able to add more characters when the maxlength is reached', /*#__PURE__*/_asyncToGenerator(function* () {
var spy = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
minLength: 1,
maxLength: 4,
open: true,
onChange: spy,
value: "1234"
})
}));
var numberButton = _react.screen.getByText('6');
yield user.click(numberButton);
expect(spy).not.toHaveBeenCalled();
}));
test('should include a submit button when `minLength` !== `maxLength` for number input', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
"data-testid": "input",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
minLength: 4,
maxLength: 6,
open: true
})
}));
var buttonSubmit = _react.screen.getByText('Submit');
expect(buttonSubmit).not.toBeNull();
});
test('should include a submit button for implicit joined number input', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
length: 10,
open: true
})
}));
var buttonSubmit = _react.screen.getByText('Submit');
expect(buttonSubmit).not.toBeNull();
});
test('should include a submit button for explicit joined number input', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
length: 4,
open: true,
numberInputField: "joined"
})
}));
var buttonSubmit = _react.screen.getByText('Submit');
expect(buttonSubmit).not.toBeNull();
});
test('should exclude a submit button when separated number input', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
length: 4,
open: true
})
}));
var buttonSubmit = _react.screen.queryByText('Submit');
expect(buttonSubmit).toBeNull();
});
test('should exclude a submit button for explicit separated number input', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
length: 10,
open: true,
numberInputField: "separated"
})
}));
var buttonSubmit = _react.screen.queryByText('Submit');
expect(buttonSubmit).toBeNull();
});
test('should show an invalid tooltip if invalid and message supplied', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 10,
invalid: true,
invalidMessage: "Invalid"
})
}));
var invalidTextField = _react.screen.getByText('Invalid').parentElement.parentElement;
var expected = 'tooltipLabel';
expect(invalidTextField).toHaveClass(expected);
});
test('should not show invalid tooltip if not invalid but message supplied', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 10,
invalidMessage: "Invalid"
})
}));
var actual = _react.screen.queryByText('Invalid');
expect(actual).toBeNull();
});
test('should show an invalid tooltip if invalid and no message supplied', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 10,
invalid: true
})
}));
var invalidTextField = _react.screen.getByText('Please enter a valid value.').parentElement.parentElement;
var expected = 'tooltipLabel';
expect(invalidTextField).toHaveClass(expected);
});
test('should not show an invalid tooltip if invalid and message is falsy', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 10,
invalid: true,
invalidMessage: ""
})
}));
var expected = 1;
var actual = _react.screen.getAllByRole('button')[2].parentElement.previousElementSibling.previousElementSibling.children.length;
expect(actual).toBe(expected);
});
test('should call onComplete when submit button clicked', /*#__PURE__*/_asyncToGenerator(function* () {
jest.useFakeTimers();
var spy = jest.fn();
var user = _userEvent["default"].setup({
advanceTimers: jest.advanceTimersByTime
});
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
minLength: 1,
maxLength: 4,
open: true,
onComplete: spy
})
}));
var numberButton = _react.screen.getByText('2');
var submitButton = _react.screen.getByText('Submit');
yield user.click(numberButton);
yield user.click(submitButton);
(0, _react.act)(function () {
return jest.advanceTimersByTime(300);
});
expect(spy).toHaveBeenCalled();
jest.useRealTimers();
}));
test('should call onChange when submit button clicked', /*#__PURE__*/_asyncToGenerator(function* () {
var spy = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
minLength: 1,
maxLength: 4,
open: true,
onChange: spy
})
}));
var numberButton = _react.screen.getByText('2');
var submitButton = _react.screen.getByText('Submit');
yield user.click(numberButton);
yield user.click(submitButton);
expect(spy).toHaveBeenCalled();
}));
test('should call onBeforeChange once when input occurs', /*#__PURE__*/_asyncToGenerator(function* () {
var spy = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
open: true,
length: 10,
onBeforeChange: spy
})
}));
var numberButton = _react.screen.getByText('2');
yield user.click(numberButton);
expect(spy).toHaveBeenCalled();
}));
test('should prevent input when onBeforeChange calls preventDefault', /*#__PURE__*/_asyncToGenerator(function* () {
var spy = jest.fn();
var mock = jest.fn(function (ev) {
if (ev.value === '2') {
ev.preventDefault();
}
});
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
minLength: 1,
maxLength: 4,
open: true,
onBeforeChange: mock,
onChange: spy
})
}));
var numberButton2 = _react.screen.getByText('2');
var numberButton1 = _react.screen.getByText('1');
var submitButton = _react.screen.getByText('Submit');
yield user.click(numberButton2);
yield user.click(numberButton1);
yield user.click(submitButton);
var expected = 1;
expect(spy).toHaveBeenCalledTimes(expected);
}));
test('should delete an input when delete button clicked', /*#__PURE__*/_asyncToGenerator(function* () {
var spy = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
value: "12",
minLength: 1,
maxLength: 4,
open: true,
onChange: spy
})
}));
var backspaceButton = _react.screen.getByText('␈');
yield user.click(backspaceButton);
var expected = '1';
var actual = _react.screen.getByRole('list').textContent;
expect(spy).toHaveBeenCalled();
expect(actual).toBe(expected);
}));
test('should call onBeforeChange when delete button clicked', /*#__PURE__*/_asyncToGenerator(function* () {
var spy = jest.fn();
var user = _userEvent["default"].setup();
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
value: "12",
minLength: 1,
maxLength: 4,
open: true,
onBeforeChange: spy
})
}));
var backspaceButton = _react.screen.getByText('␈');
yield user.click(backspaceButton);
var expected = '1';
var actual = _react.screen.getByRole('list').textContent;
expect(spy).toHaveBeenCalled();
expect(actual).toBe(expected);
}));
test('should not include a submit button when noSubmitButton is used', function () {
(0, _react.render)( /*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
type: "number",
length: 4,
open: true,
numberInputField: "joined",
noSubmitButton: true
})
}));
var buttonSubmit = _react.screen.queryByText('Submit');
expect(buttonSubmit).toBeNull();
});
});
});