Skip to content

Commit

Permalink
[WNMGDS-66] Updating Autocomplete to use Downshift v3. (#407)
Browse files Browse the repository at this point in the history
* [HDSG-214] WIP. Updating Autocomplete to use Downshift v3.

* WIP. Refactoring Autocomplete to remove aXe errors.

* [HDSG-214] WIP. Committing ARIA 1.1 spec version before migration to 1.0.

* [HDSG-214] WIP. Moved to ARIA 1.0 spec with no aXe errors.

* [HDSG-214] WIP. Screen reader testing complete. Need to update loading message.

* [HDSG-214] WIP. Adding back the Clear search by default. Opt out now, not opt in.

* [HDSG-214] WIP. Refactoring to WAI-ARIA 1.0 with custom container.

* [HDSG-214] Renaming container div, clear search prop.

* [HDSG-214] Removed aria-owns from container div, added documentation.

* [HDSG-214] WIP. Adding a few e2e tests for Autocomplete.

* [HDSG-214] Adding full suite of e2e tests for Autocomplete, including keyboard tests.

* [HDSG-214] Updating the Autocomplete test variables to be more readable.

* [HDSG-214] Adding final keyboard focus assertion.

* [HDSG-214] Abstracted focus method to a helper for cleaner implementation.
  • Loading branch information
1Copenut authored May 22, 2019
1 parent a80b5db commit f4419e4
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 82 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@cmsgov/design-system-support": "^1.32.1",
"classnames": "^2.2.5",
"core-js": "^2.5.3",
"downshift": "1.31.16",
"downshift": "^3.0.0",
"ev-emitter": "^1.1.1",
"lodash.uniqueid": "^4.0.1",
"react-aria-modal": "^2.11.1"
Expand Down
138 changes: 133 additions & 5 deletions packages/core/src/components/Autocomplete/Autocomplete.e2e.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,145 @@
/* global driver */
/* global driver, by, key */
import {
getElementByClassName,
getElementByXPath,
getFocusInnerText
} from '../../helpers/e2e';
import { ROOT_URL } from '../../helpers/e2e/constants';

import assertNoAxeViolations from '../../helpers/e2e/assertNoAxeViolations';
import { getElementByClassName } from '../../helpers/e2e';

const rootURL = `${ROOT_URL}/example/components.autocomplete.react/`;

describe('Alert component', () => {
describe('Autocomplete component', () => {
it('Should render', async() => {
await driver.get(rootURL);

const el = await getElementByClassName('ds-u-clearfix ds-c-autocomplete');
expect(el).toBeTruthy();
const autocompleteField = await getElementByClassName(
'ds-u-clearfix ds-c-autocomplete'
);
expect(autocompleteField).toBeTruthy();
});

it('Should expand the listbox when keys are pressed', async() => {
await driver.get(rootURL);

const autocompleteField = await getElementByXPath(
'//*[@id="autocomplete_1"]'
);
autocompleteField.click();
await autocompleteField.sendKeys('c');

const listbox = await getElementByXPath(
'//*[@id="autocomplete_owned_container_4"]'
);
expect(listbox).toBeTruthy();
});

it('Should set the input value correctly when a listbox selection is clicked', async() => {
await driver.get(rootURL);

let autocompleteField = await getElementByXPath(
'//*[@id="autocomplete_1"]'
);
autocompleteField.click();
await autocompleteField.sendKeys('c');

const listboxItem = await getElementByXPath(
'//*[@id="downshift-0-item-0"]'
);
listboxItem.click();

autocompleteField = await getElementByXPath('//*[@id="autocomplete_1"]');
autocompleteField = await autocompleteField.getAttribute('value');
expect(autocompleteField).toEqual('Cook County, IL');
});

it('Should set the input value to empty when Clear search is clicked', async() => {
await driver.get(rootURL);

let autocompleteField = await getElementByXPath(
'//*[@id="autocomplete_1"]'
);
autocompleteField.click();
await autocompleteField.sendKeys('c');

const listboxItem = await getElementByXPath(
'//*[@id="downshift-0-item-0"]'
);
listboxItem.click();

const clearButton = await getElementByXPath(
'//*[@id="js-example"]/div/div[1]/button'
);
clearButton.click();

autocompleteField = await getElementByXPath('//*[@id="autocomplete_1"]');
autocompleteField = await autocompleteField.getAttribute('value');
expect(autocompleteField).toEqual('');
});

it('Should select list items by keyboard', async() => {
await driver.get(rootURL);

let autocompleteField = await getElementByXPath(
'//*[@id="autocomplete_1"]'
);
autocompleteField.click();
await autocompleteField.sendKeys('c');
await autocompleteField.sendKeys(key.ARROW_DOWN);
await autocompleteField.sendKeys(key.ENTER);

autocompleteField = await autocompleteField.getAttribute('value');
expect(autocompleteField).toEqual('Cook County, IL');
});

it('Should clear the input value by keyboard', async() => {
await driver.get(rootURL);

let autocompleteField = await getElementByXPath(
'//*[@id="autocomplete_1"]'
);
const clearSearch = await getElementByXPath(
'//*[@id="js-example"]/div/div[1]/button'
);

autocompleteField.click();
await autocompleteField.sendKeys('c');
await autocompleteField.sendKeys(key.ARROW_DOWN);
await autocompleteField.sendKeys(key.ENTER);
await autocompleteField.sendKeys(key.TAB);

/* Assert the clear search button has keyboard focus, then click it.
* We are using the Selenium driver object to determine keyboard
* focus after sending the TAB key.
*/
expect(await getFocusInnerText()).toEqual('Clear search');

clearSearch.click();

autocompleteField = await getElementByXPath('//*[@id="autocomplete_1"]');
autocompleteField = await autocompleteField.getAttribute('value');
expect(autocompleteField).toEqual('');
});

it('Closes the listbox when ESC is pressed', async() => {
await driver.get(rootURL);

const autocompleteField = await getElementByXPath(
'//*[@id="autocomplete_1"]'
);
autocompleteField.click();
await autocompleteField.sendKeys('c');
let listbox = await driver.findElements(
by.css('#autocomplete_owned_container_4')
);
expect(listbox.length).toEqual(1);

await autocompleteField.sendKeys(key.ESCAPE);
listbox = await driver.findElements(
by.css('#autocomplete_owned_container_4')
);
expect(listbox.length).toEqual(0);
});

it('Should have no accessibility violations', async() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,23 @@ ReactDOM.render(
/>
</Autocomplete>

<Autocomplete items={[]} loading>
<Autocomplete items={[]} loading clearSearchButton={false}>
<TextField
hint="List should return string Loading to simulate async data call."
label="Loading message"
name="Downshift_autocomplete"
/>
</Autocomplete>

<Autocomplete items={[]}>
<Autocomplete items={[]} clearSearchButton={false}>
<TextField
hint="List should return string No results found."
label="No results message"
name="Downshift_autocomplete"
/>
</Autocomplete>

<Autocomplete>
<Autocomplete clearSearchButton={false}>
<TextField
hint="No list should be shown if no item array is provided and it's not loading. This could be the case if a user has not yet entered the minimum number of characters required for a search."
label="Nothing shown"
Expand Down
Loading

0 comments on commit f4419e4

Please sign in to comment.