Skip to content

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-gendron committed May 11, 2020
1 parent 6522890 commit 4809735
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 16 deletions.
200 changes: 199 additions & 1 deletion packages/react/src/components/select/select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,208 @@ describe('Select', () => {
const callback = jest.fn();
const wrapper = shallow(<Select onChange={callback} options={provinces} />);

getByTestId(wrapper, 'list').simulate('change', { value: 'ns', label: 'Nova Scotia' });
getByTestId(wrapper, 'listbox').simulate('change', { value: 'ns', label: 'Nova Scotia' });
expect(callback).toHaveBeenCalledWith({ value: 'ns', label: 'Nova Scotia' });
});

test('listbox should be closed by default', () => {
const wrapper = shallow(<Select options={provinces} />);

expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('listbox should be open when defaultOpen prop is set to true', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('input should have default value', () => {
const wrapper = shallow(<Select options={provinces} defaultValue="qc" />);

expect(getByTestId(wrapper, 'input').props().value).toBe('Quebec');
});

test('listbox should open on click', () => {
const wrapper = shallow(<Select options={provinces} />);

getByTestId(wrapper, 'input-wrapper').simulate('click');
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('listbox should not open on click [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable/>);

getByTestId(wrapper, 'input-wrapper').simulate('click');
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('listbox should close on click', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

getByTestId(wrapper, 'input-wrapper').simulate('click');
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('listbox should open when arrow is clicked', () => {
const wrapper = shallow(<Select options={provinces} />);

getByTestId(wrapper, 'arrow').simulate('click');
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('listbox should close when arrow is clicked', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen/>);

getByTestId(wrapper, 'arrow').simulate('click');
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

describe('input', () => {
test('ArrowUp should open listbox', () => {
const wrapper = shallow(<Select options={provinces} />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 38 });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('ArrowUp should open listbox [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 38 });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('ArrowDown should open listbox', () => {
const wrapper = shallow(<Select options={provinces} />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 40 });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('ArrowDown should open listbox [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 40 });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('Enter should open listbox', () => {
const wrapper = shallow(<Select options={provinces} />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 13, preventDefault: jest.fn() });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('ArrowDown should not open listbox [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 13, preventDefault: jest.fn() });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('Spacebar should open listbox', () => {
const wrapper = shallow(<Select options={provinces} />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 32, preventDefault: jest.fn() });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('Spacebar should open listbox [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 32, preventDefault: jest.fn() });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('Escape should close listbox', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 27 });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('Escape should close listbox [searchable]', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen searchable />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 27 });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('input value should be cleared when escape is pressed [searchable]', () => {
const wrapper = shallow(<Select options={provinces} defaultValue="qc" searchable />);

getByTestId(wrapper, 'input').simulate('keydown', { keyCode: 27 });
expect(getByTestId(wrapper, 'input').props().value).toBe('');
});

test('listbox should open when search entry has matching result(s) [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('change', { target: { value: 'a' } });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeTruthy();
});

test('listbox should close when search entry has no matching result [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('change', { target: { value: 'at' } });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('should select value that matches search value on blur [searchable]', () => {
const wrapper = shallow(<Select options={provinces} searchable />);

getByTestId(wrapper, 'input').simulate('change', { target: { value: 'quebec' } });
getByTestId(wrapper, 'input').simulate('blur');
expect(getByTestId(wrapper, 'input').props().value).toBe('Quebec');
});
});

describe('listbox', () => {
test('should close when escape is pressed', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

getByTestId(wrapper, 'listbox').simulate('keydown', { key: 'Escape' });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});

test('should clear input value when escape is pressed [searchable]', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen defaultValue="qc" searchable />);

getByTestId(wrapper, 'listbox').simulate('keydown', { key: 'Escape' });
expect(getByTestId(wrapper, 'input').props().value).toBe('');
});

test('should focus last element from array when ArrowUp is pressed', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

getByTestId(wrapper, 'listbox').simulate('keydown', { key: 'ArrowUp' });
expect(getByTestId(wrapper, 'listbox').props().focusedValue).toBe('yt');
});

test('should focus the first element starting with the letter N', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

getByTestId(wrapper, 'listbox').simulate('keydown', { keyCode: 78, key: 'n' });
expect(getByTestId(wrapper, 'listbox').props().focusedValue).toBe('ns');
});

test('should remove focus when a character is pressed [searchable]', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen searchable />);

getByTestId(wrapper, 'listbox').simulate('keydown', { keyCode: 78, key: 'n' });
expect(getByTestId(wrapper, 'listbox').props().autofocus).toBeFalsy();
});

test('should close onChange', () => {
const wrapper = shallow(<Select options={provinces} defaultOpen />);

getByTestId(wrapper, 'listbox').simulate('change', { option: { label: 'Quebec', value: 'qc' } });
expect(getByTestId(wrapper, 'listbox').props().visible).toBeFalsy();
});
});

test('matches the snapshot', () => {
const tree = renderWithProviders(
<Select
Expand Down
12 changes: 12 additions & 0 deletions packages/react/src/components/select/select.test.tsx.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 17 additions & 15 deletions packages/react/src/components/select/select.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, useEffect, useMemo, useRef, useState } from 'react';
import React, { ChangeEvent, KeyboardEvent, ReactElement, useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
import uuid from 'uuid/v4';

Expand Down Expand Up @@ -220,6 +220,7 @@ export function Select({

if (matchingOption) {
setSelectedOptionValue(matchingOption.value);
setInputValue(matchingOption.label);
}
}

Expand All @@ -228,12 +229,8 @@ export function Select({
matchInputValueToOption();
}

function handleBlur(event: FocusEvent<HTMLInputElement>): void {
const checkSearchValue = findOption(options, event.target.value);
if (checkSearchValue && checkSearchValue.value !== selectedOptionValue) {
setSelectedOptionValue(checkSearchValue.value);
onChange && onChange(checkSearchValue);
}
function handleBlur(): void {
matchInputValueToOption();
if (!open) {
setFocus(false);
}
Expand Down Expand Up @@ -388,15 +385,17 @@ export function Select({
handleOpen();
} else if (event.key === 'ArrowUp' && !focusedValue) {
focusLastElementFromArray(options);
} else if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown' && searchable) {
setAutofocus(false);
setFocusedValue('');
inputRef.current && inputRef.current.focus();
} else if (event.keyCode > 64 && event.keyCode < 91) /* Check if key is a character */ {
const suggestOption =
if (searchable) {
setAutofocus(false);
setFocusedValue('');
inputRef.current && inputRef.current.focus();
} else {
const suggestOption =
options.find(option => option.label.toLowerCase().startsWith(event.key.toLowerCase()));
if (suggestOption) {
setFocusedValue(suggestOption.value);
if (suggestOption) {
setFocusedValue(suggestOption.value);
}
}
}
}
Expand Down Expand Up @@ -440,6 +439,7 @@ export function Select({
aria-expanded={open}
aria-haspopup="listbox"
aria-owns={`listbox_${id}`}
data-testid="input-wrapper"
containerOutline={containerOutline}
isMobile={isMobile}
disabled={disabled}
Expand All @@ -454,6 +454,7 @@ export function Select({
aria-autocomplete={searchable ? 'both' : 'list'}
aria-controls={`listbox_${id}`}
aria-multiline="false"
data-testid="input"
isMobile={isMobile}
disabled={disabled}
name={name}
Expand All @@ -470,6 +471,7 @@ export function Select({
/>
<Arrow
type="button"
data-testid="arrow"
tabIndex={-1}
onClick={disabled ? undefined : handleArrowClick}
disabled={disabled}
Expand All @@ -481,7 +483,7 @@ export function Select({
autofocus={searchable ? autoFocus : open}
visible={open}
checkIndicator
data-testid="list"
data-testid="listbox"
defaultValue={defaultValue}
focusedValue={focusedValue}
id={id}
Expand Down

0 comments on commit 4809735

Please sign in to comment.