mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
@@ -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. */
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
Reference in New Issue
Block a user