fix(autocomplete): aria-expanded should be updated when panel hides (#3494)

* fix(autocomplete): aria-expanded should be updated when panel hides

* address comments
This commit is contained in:
Kara
2017-03-13 14:14:55 -07:00
committed by mmalerba
parent bcb16c615f
commit 932b4a0767
3 changed files with 81 additions and 51 deletions
+1 -1
View File
@@ -114,7 +114,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
/* Whether or not the autocomplete panel is open. */
get panelOpen(): boolean {
return this._panelOpen;
return this._panelOpen && this.autocomplete.showPanel;
}
/** Opens the autocomplete suggestion panel. */
+67 -50
View File
@@ -15,6 +15,7 @@ import {MdAutocomplete} from './autocomplete';
import {MdInputContainer} from '../input/input-container';
import {Observable} from 'rxjs/Observable';
import {dispatchFakeEvent} from '../core/testing/dispatch-events';
import {typeInElement} from '../core/testing/type-in-element';
import 'rxjs/add/operator/map';
@@ -66,35 +67,39 @@ describe('MdAutocomplete', () => {
input = fixture.debugElement.query(By.css('input')).nativeElement;
});
it('should open the panel when the input is focused', () => {
it('should open the panel when the input is focused', async(() => {
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(false, `Expected panel state to start out closed.`);
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel state to read open when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('Alabama', `Expected panel to display when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('California', `Expected panel to display when input is focused.`);
});
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel state to read open when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('Alabama', `Expected panel to display when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('California', `Expected panel to display when input is focused.`);
});
}));
it('should open the panel programmatically', () => {
it('should open the panel programmatically', async(() => {
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(false, `Expected panel state to start out closed.`);
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel state to read open when opened programmatically.`);
expect(overlayContainerElement.textContent)
.toContain('Alabama', `Expected panel to display when opened programmatically.`);
expect(overlayContainerElement.textContent)
.toContain('California', `Expected panel to display when opened programmatically.`);
});
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel state to read open when opened programmatically.`);
expect(overlayContainerElement.textContent)
.toContain('Alabama', `Expected panel to display when opened programmatically.`);
expect(overlayContainerElement.textContent)
.toContain('California', `Expected panel to display when opened programmatically.`);
});
}));
it('should close the panel when blurred', async(() => {
dispatchFakeEvent(input, 'focus');
@@ -190,8 +195,6 @@ describe('MdAutocomplete', () => {
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel to stay open when options list is empty.`);
expect(panel.classList)
.toContain('mat-autocomplete-hidden', `Expected panel to hide itself when empty.`);
});
@@ -774,20 +777,43 @@ describe('MdAutocomplete', () => {
.toBe('false', 'Expected aria-expanded to be false while panel is closed.');
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
expect(input.getAttribute('aria-expanded'))
.toBe('true', 'Expected aria-expanded to be true while panel is open.');
fixture.componentInstance.trigger.closePanel();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(input.getAttribute('aria-expanded'))
.toBe('false', 'Expected aria-expanded to be false when panel closes again.');
.toBe('true', 'Expected aria-expanded to be true while panel is open.');
fixture.componentInstance.trigger.closePanel();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(input.getAttribute('aria-expanded'))
.toBe('false', 'Expected aria-expanded to be false when panel closes again.');
});
});
}));
it('should set aria-expanded properly when the panel is hidden', async(() => {
fixture.componentInstance.trigger.openPanel();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(input.getAttribute('aria-expanded'))
.toBe('true', 'Expected aria-expanded to be true while panel is open.');
typeInElement('zz', input);
fixture.whenStable().then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(input.getAttribute('aria-expanded'))
.toBe('false', 'Expected aria-expanded to be false when panel hides itself.');
});
});
});
}));
it('should set aria-owns based on the attached autocomplete', () => {
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
@@ -901,21 +927,24 @@ describe('MdAutocomplete', () => {
});
}));
it('should work when input is wrapped in ngIf', () => {
it('should work when input is wrapped in ngIf', async(() => {
const fixture = TestBed.createComponent(NgIfAutocomplete);
fixture.detectChanges();
const input = fixture.debugElement.query(By.css('input')).nativeElement;
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel state to read open when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('One', `Expected panel to display when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('Two', `Expected panel to display when input is focused.`);
});
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(true, `Expected panel state to read open when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('One', `Expected panel to display when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('Two', `Expected panel to display when input is focused.`);
});
}));
it('should filter properly with ngIf after setting the active item', fakeAsync(() => {
const fixture = TestBed.createComponent(NgIfAutocomplete);
@@ -1086,18 +1115,6 @@ class AutocompleteWithNgModel {
}
/**
* Focuses an input, sets its value and dispatches
* the `input` event, simulating the user typing.
* @param value Value to be set on the input.
* @param element Element onto which to set the value.
*/
function typeInElement(value: string, element: HTMLInputElement, autoFocus = true) {
element.focus();
element.value = value;
dispatchFakeEvent(element, 'input');
}
/** This is a mock keyboard event to test keyboard events in the autocomplete. */
class MockKeyboardEvent {
constructor(public keyCode: number) {}
+13
View File
@@ -0,0 +1,13 @@
import {dispatchFakeEvent} from './dispatch-events';
/**
* Focuses an input, sets its value and dispatches
* the `input` event, simulating the user typing.
* @param value Value to be set on the input.
* @param element Element onto which to set the value.
*/
export function typeInElement(value: string, element: HTMLInputElement, autoFocus = true) {
element.focus();
element.value = value;
dispatchFakeEvent(element, 'input');
}