Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing date picker and field components event props not working #3605

Merged
merged 11 commits into from
Oct 26, 2022
85 changes: 84 additions & 1 deletion packages/@react-spectrum/datepicker/test/DateField.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
* governing permissions and limitations under the License.
*/

import {act, render as render_, within} from '@react-spectrum/test-utils';
import {act, fireEvent, render as render_, within} from '@react-spectrum/test-utils';
import {CalendarDate} from '@internationalized/date';
import {DateField} from '../';
import {Provider} from '@react-spectrum/provider';
import React from 'react';
import {theme} from '@react-spectrum/theme-default';
import userEvent from '@testing-library/user-event';

function render(el) {
if (el.type === Provider) {
Expand Down Expand Up @@ -218,4 +219,86 @@ describe('DateField', function () {
}
});
});

describe('events', function () {
let onBlurSpy = jest.fn();
let onFocusChangeSpy = jest.fn();
let onFocusSpy = jest.fn();
let onKeyDownSpy = jest.fn();
let onKeyUpSpy = jest.fn();

afterEach(() => {
onBlurSpy.mockClear();
onFocusChangeSpy.mockClear();
onFocusSpy.mockClear();
onKeyDownSpy.mockClear();
onKeyUpSpy.mockClear();
});

it('should focus field and switching segments via tab does not change focus', function () {
let {getAllByRole} = render(<DateField label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} />);
let segments = getAllByRole('spinbutton');

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

userEvent.tab();
expect(segments[0]).toHaveFocus();

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

userEvent.tab();
expect(segments[1]).toHaveFocus();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});

it('should call blur when focus leaves', function () {
let {getAllByRole} = render(<DateField label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} />);
let segments = getAllByRole('spinbutton');

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

userEvent.tab();
expect(segments[0]).toHaveFocus();

userEvent.tab();
expect(segments[1]).toHaveFocus();

userEvent.tab();
expect(segments[2]).toHaveFocus();
expect(onBlurSpy).toHaveBeenCalledTimes(0);

userEvent.tab();
expect(onBlurSpy).toHaveBeenCalledTimes(1);
expect(onFocusChangeSpy).toHaveBeenCalledTimes(2);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});

it('should trigger right arrow key event for segment navigation', function () {
let {getAllByRole} = render(<DateField label="Date" onKeyDown={onKeyDownSpy} onKeyUp={onKeyUpSpy} />);
let segments = getAllByRole('spinbutton');

expect(onKeyDownSpy).not.toHaveBeenCalled();
expect(onKeyUpSpy).not.toHaveBeenCalled();

userEvent.tab();
expect(segments[0]).toHaveFocus();
// mock tab via userEvent calls up, but not down
snowystinger marked this conversation as resolved.
Show resolved Hide resolved
expect(onKeyDownSpy).not.toHaveBeenCalled();
expect(onKeyUpSpy).toHaveBeenCalledTimes(1);

fireEvent.keyDown(segments[0], {key: 'ArrowRight'});
fireEvent.keyUp(segments[0], {key: 'ArrowRight'});
snowystinger marked this conversation as resolved.
Show resolved Hide resolved
expect(segments[1]).toHaveFocus();
expect(onKeyDownSpy).toHaveBeenCalledTimes(1);
expect(onKeyUpSpy).toHaveBeenCalledTimes(2);
});
});
});
167 changes: 167 additions & 0 deletions packages/@react-spectrum/datepicker/test/DatePicker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,173 @@ describe('DatePicker', function () {
});
});

describe('events', function () {
let onBlurSpy = jest.fn();
let onFocusChangeSpy = jest.fn();
let onFocusSpy = jest.fn();
let onKeyDownSpy = jest.fn();
let onKeyUpSpy = jest.fn();

afterEach(() => {
onBlurSpy.mockClear();
onFocusChangeSpy.mockClear();
onFocusSpy.mockClear();
onKeyDownSpy.mockClear();
onKeyUpSpy.mockClear();
});

it('should focus field, move a segment, and open popover and does not blur', function () {
let {getByRole, getAllByRole} = render(<DatePicker label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} />);
let segments = getAllByRole('spinbutton');
let button = getByRole('button');

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

userEvent.tab();
expect(segments[0]).toHaveFocus();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

userEvent.tab();
expect(segments[1]).toHaveFocus();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

triggerPress(button);
act(() => jest.runAllTimers());

let dialog = getByRole('dialog');
expect(dialog).toBeVisible();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});

it('should focus field and leave to blur', function () {
let {getAllByRole} = render(<DatePicker label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} />);
let segments = getAllByRole('spinbutton');

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

userEvent.tab();
expect(segments[0]).toHaveFocus();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

userEvent.click(document.body);
expect(document.body).toHaveFocus();
expect(onBlurSpy).toHaveBeenCalledTimes(1);
expect(onFocusChangeSpy).toHaveBeenCalledTimes(2);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});

it('should open popover and call picker onFocus', function () {
let {getByRole} = render(<DatePicker label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} />);
let button = getByRole('button');

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

triggerPress(button);
act(() => jest.runAllTimers());

let dialog = getByRole('dialog');
expect(dialog).toBeVisible();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});

it('should open and close popover and only call blur when focus leaves picker', function () {
let {getByRole} = render(<DatePicker label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} />);
let button = getByRole('button');

expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

triggerPress(button);
act(() => jest.runAllTimers());

let dialog = getByRole('dialog');
expect(dialog).toBeVisible();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

fireEvent.keyDown(dialog, {key: 'Escape'});
fireEvent.keyUp(dialog, {key: 'Escape'});
snowystinger marked this conversation as resolved.
Show resolved Hide resolved
act(() => jest.runAllTimers());

expect(dialog).not.toBeInTheDocument();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

act(() => button.focus());
snowystinger marked this conversation as resolved.
Show resolved Hide resolved
userEvent.tab();
expect(document.body).toHaveFocus();
expect(onBlurSpy).toHaveBeenCalledTimes(1);
expect(onFocusChangeSpy).toHaveBeenCalledTimes(2);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});

it('should trigger right arrow key event for segment navigation', function () {
let {getAllByRole} = render(<DatePicker label="Date" onKeyDown={onKeyDownSpy} onKeyUp={onKeyUpSpy} />);
let segments = getAllByRole('spinbutton');

expect(onKeyDownSpy).not.toHaveBeenCalled();
expect(onKeyUpSpy).not.toHaveBeenCalled();

userEvent.tab();
expect(segments[0]).toHaveFocus();
// mock tab via userEvent calls up, but not down
expect(onKeyDownSpy).not.toHaveBeenCalled();
expect(onKeyUpSpy).toHaveBeenCalledTimes(1);

fireEvent.keyDown(segments[0], {key: 'ArrowRight'});
fireEvent.keyUp(segments[0], {key: 'ArrowRight'});
expect(segments[1]).toHaveFocus();
expect(onKeyDownSpy).toHaveBeenCalledTimes(1);
expect(onKeyUpSpy).toHaveBeenCalledTimes(2);
});

it('should trigger key event in popover and focus/blur/key events are not called', function () {
let {getByRole} = render(<DatePicker label="Date" onBlur={onBlurSpy} onFocus={onFocusSpy} onFocusChange={onFocusChangeSpy} onKeyDown={onKeyDownSpy} onKeyUp={onKeyUpSpy} />);
let button = getByRole('button');

expect(onKeyDownSpy).not.toHaveBeenCalled();
expect(onKeyUpSpy).not.toHaveBeenCalled();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).not.toHaveBeenCalled();
expect(onFocusSpy).not.toHaveBeenCalled();

triggerPress(button);

let dialog = getByRole('dialog');
expect(dialog).toBeVisible();
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);

fireEvent.keyDown(document.activeElement, {key: 'ArrowRight'});
fireEvent.keyUp(document.activeElement, {key: 'ArrowRight'});
expect(onKeyDownSpy).toHaveBeenCalledTimes(0);
expect(onKeyUpSpy).toHaveBeenCalledTimes(0);
expect(onBlurSpy).not.toHaveBeenCalled();
expect(onFocusChangeSpy).toHaveBeenCalledTimes(1);
expect(onFocusSpy).toHaveBeenCalledTimes(1);
});
});

describe('calendar popover', function () {
it('should emit onChange when selecting a date in the calendar in controlled mode', function () {
let onChange = jest.fn();
Expand Down
Loading