Skip to content

Commit

Permalink
feat(sdk/testing): support axe-core 4.7 (#1494)
Browse files Browse the repository at this point in the history
* feat(sdk/testing): support axe-core 4.7

* Fix lookup accessibility when using ariaLabel and not ariaLabelledBy

* Revert autocomplete, update isOpen logic, consolidate ag-grid lookup field ariaLabel

* Simplify changes

* Update property name

* Use `controlId` for aria-labelledby rather than creating a `<label>` element
  • Loading branch information
johnhwhite committed Aug 18, 2023
1 parent 6fa2d7e commit 1481956
Show file tree
Hide file tree
Showing 15 changed files with 281 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -562,36 +562,80 @@ describe('SkyAgGridWrapperComponent via fixture', () => {

describe('accessibility', () => {
[false, true].forEach((enableTopScroll) => {
[false, true].forEach((editable) => {
it(`should be accessible in ${editable ? 'edit' : 'view'} mode ${
enableTopScroll ? 'with' : 'without'
} top scroll`, async () => {
TestBed.configureTestingModule({
imports: [SkyAgGridFixtureModule],
providers: [
{
provide: Editable,
useValue: editable,
},
{
provide: EnableTopScroll,
useValue: enableTopScroll,
},
],
teardown: {
destroyAfterEach: false,
it(`should be accessible in view mode ${
enableTopScroll ? 'with' : 'without'
} top scroll`, async () => {
TestBed.configureTestingModule({
imports: [SkyAgGridFixtureModule],
providers: [
{
provide: Editable,
useValue: false,
},
{
provide: EnableTopScroll,
useValue: enableTopScroll,
},
});
gridWrapperFixture = TestBed.createComponent(
SkyAgGridFixtureComponent
);
gridWrapperNativeElement = gridWrapperFixture.nativeElement;
],
});
gridWrapperFixture = TestBed.createComponent(SkyAgGridFixtureComponent);
gridWrapperNativeElement = gridWrapperFixture.nativeElement;

gridWrapperFixture.detectChanges();
await gridWrapperFixture.whenStable();
gridWrapperFixture.detectChanges();
await gridWrapperFixture.whenStable();

await expectAsync(gridWrapperNativeElement).toBeAccessible();
});
await expectAsync(gridWrapperNativeElement).toBeAccessible();
});
});

it(`should be accessible in edit mode`, async () => {
TestBed.configureTestingModule({
imports: [SkyAgGridFixtureModule],
providers: [
{
provide: Editable,
useValue: true,
},
{
provide: EnableTopScroll,
useValue: false,
},
],
});
gridWrapperFixture = TestBed.createComponent(SkyAgGridFixtureComponent);
gridWrapperNativeElement = gridWrapperFixture.nativeElement;

gridWrapperFixture.detectChanges();
await gridWrapperFixture.whenStable();

await expectAsync(gridWrapperNativeElement).toBeAccessible();

gridWrapperFixture.componentInstance.agGrid?.api.startEditingCell({
rowIndex: 0,
colKey: 'lookupSingle',
});
gridWrapperFixture.detectChanges();
await gridWrapperFixture.whenStable();
await expectAsync(gridWrapperNativeElement).toBeAccessible();

gridWrapperFixture.componentInstance.agGrid?.api.stopEditing();
gridWrapperFixture.detectChanges();
await gridWrapperFixture.whenStable();

gridWrapperFixture.componentInstance.agGrid?.api.startEditingCell({
rowIndex: 0,
colKey: 'lookupMultiple',
});
gridWrapperFixture.detectChanges();
await gridWrapperFixture.whenStable();
await expectAsync(
gridWrapperNativeElement.ownerDocument.body
).toBeAccessible({
rules: {
region: {
enabled: false,
},
},
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[formGroup]="editorForm"
>
<sky-lookup
[ariaLabel]="skyComponentProperties?.ariaLabel"
[ariaLabel]="ariaLabel"
[ariaLabelledBy]="skyComponentProperties?.ariaLabelledBy"
[autocompleteAttribute]="skyComponentProperties?.autocompleteAttribute"
[data]="skyComponentProperties?.data"
Expand All @@ -23,12 +23,12 @@
[searchTextMinimumCharacters]="
skyComponentProperties?.searchTextMinimumCharacters
"
(searchAsync)="skyComponentProperties?.searchAsync($event)"
(searchAsync)="skyComponentProperties?.searchAsync?.($event)"
[selectMode]="skyComponentProperties?.selectMode"
[showAddButton]="skyComponentProperties?.showAddButton"
[showMoreConfig]="skyComponentProperties?.showMoreConfig"
[wrapperClass]="skyComponentProperties?.wrapperClass"
(addClick)="skyComponentProperties?.addClick($event)"
(addClick)="skyComponentProperties?.addClick?.($event)"
(openChange)="onLookupOpenChange($event)"
>
</sky-lookup>
Expand All @@ -39,7 +39,7 @@
[formGroup]="editorForm"
>
<sky-lookup
[ariaLabel]="skyComponentProperties?.ariaLabel"
[ariaLabel]="ariaLabel"
[ariaLabelledBy]="skyComponentProperties?.ariaLabelledBy"
[autocompleteAttribute]="skyComponentProperties?.autocompleteAttribute"
[data]="skyComponentProperties?.data"
Expand All @@ -62,7 +62,7 @@
[showAddButton]="skyComponentProperties?.showAddButton"
[showMoreConfig]="skyComponentProperties?.showMoreConfig"
[wrapperClass]="skyComponentProperties?.wrapperClass"
(addClick)="skyComponentProperties?.addClick($event)"
(addClick)="skyComponentProperties?.addClick?.($event)"
(openChange)="onLookupOpenChange($event)"
>
</sky-lookup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,43 @@ describe('SkyAgGridCellEditorLookupComponent', () => {
expect(component).toBeTruthy();
});

it('should initialize with different label sources', () => {
component.agInit({
...(cellEditorParams as ICellEditorParams),
});
fixture.detectChanges();
expect(component).toBeTruthy();

component.agInit({
...(cellEditorParams as ICellEditorParams),
colDef: {},
});
fixture.detectChanges();
expect(component).toBeTruthy();

component.agInit({
...(cellEditorParams as ICellEditorParams),
colDef: {},
skyComponentProperties: {
...cellEditorParams.skyComponentProperties,
ariaLabel: 'label',
},
});
fixture.detectChanges();
expect(component).toBeTruthy();

component.agInit({
...(cellEditorParams as ICellEditorParams),
colDef: {},
skyComponentProperties: {
...cellEditorParams.skyComponentProperties,
ariaLabelledBy: 'label-id',
},
});
fixture.detectChanges();
expect(component).toBeTruthy();
});

it('should initialize with disabled control', () => {
component.agInit({
...(cellEditorParams as ICellEditorParams),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export class SkyAgGridCellEditorLookupComponent
});
public useAsyncSearch = false;

protected ariaLabel: string | undefined = undefined;

#lookupOpen = false;
#params: SkyCellEditorLookupParams | undefined;
#triggerType: SkyAgGridCellEditorInitialAction | undefined;
Expand All @@ -67,6 +69,13 @@ export class SkyAgGridCellEditorLookupComponent

this.#triggerType = SkyAgGridCellEditorUtils.getEditorInitialAction(params);
const control = this.editorForm.get('selection');
this.ariaLabel = params.skyComponentProperties?.ariaLabelledBy
? undefined
: params.skyComponentProperties?.ariaLabel ||
params.colDef.headerName ||
params.colDef.headerTooltip ||
params.colDef.field ||
params.colDef.colId;

if (control) {
switch (this.#triggerType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class SkyAutocompleteInputDirective
this.#textChangesObs = this.#textChanges.asObservable();
}

public ngOnInit() {
public ngOnInit(): void {
const element = this.#elementRef.nativeElement;

this.#setAttributes(this.#elementRef);
Expand Down Expand Up @@ -283,17 +283,20 @@ export class SkyAutocompleteInputDirective
}
}

public setAriaOwns(overlayId: string | null): void {
/**
* Used to connect the input to the overlay.
*/
public setAriaControls(overlayId: string | null): void {
if (overlayId) {
this.#renderer.setAttribute(
this.#elementRef.nativeElement,
'aria-owns',
'aria-controls',
overlayId
);
} else {
this.#renderer.removeAttribute(
this.#elementRef.nativeElement,
'aria-owns'
'aria-controls'
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
aria-haspopup="listbox"
class="sky-autocomplete"
role="combobox"
[attr.aria-expanded]="isOpen"
[attr.aria-expanded]="isDropdownVisible | async"
[attr.aria-labelledby]="ariaLabelledBy"
[attr.aria-owns]="isOpen ? resultsListId : null"
[attr.aria-controls]="(isDropdownVisible | async) ? resultsListId : null"
[attr.id]="resultsWrapperId"
>
<ng-content></ng-content>
Expand All @@ -32,7 +32,7 @@

<ng-template #resultControlsTemplateRef>
<div
*ngIf="searchText && (!showActionsArea || searchResults.length > 0)"
*ngIf="isDropdownVisible | async"
class="sky-autocomplete-results"
role="listbox"
[attr.aria-labelledby]="ariaLabelledBy"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1094,27 +1094,54 @@ describe('Autocomplete component', () => {
await fixture.whenStable();
await expectAsync(document.body).toBeAccessible(axeConfig);
fixture.detectChanges();
inputElement.focus();
SkyAppTestUtility.fireDomEvent(inputElement, 'focus');
inputElement.value = 'r';
SkyAppTestUtility.fireDomEvent(inputElement, 'input');
fixture.detectChanges();
await fixture.whenStable();
expect(getSearchResultsContainer()).toBeTruthy();
await expectAsync(document.body).toBeAccessible(axeConfig);
});

it('should be accessible with enableShowMore', async () => {
component.enableShowMore = true;

const axeConfig = {
rules: {
region: {
enabled: false,
},
},
};

fixture.detectChanges();

const inputElement: HTMLInputElement = getInputElement();

await fixture.whenStable();
SkyAppTestUtility.fireDomEvent(inputElement, 'focus');
fixture.detectChanges();
await fixture.whenStable();
expect(getSearchResultsContainer()).toBeTruthy();
await expectAsync(document.body).toBeAccessible(axeConfig);
});

it('should set `aria-owns` attribute', fakeAsync(() => {
it('should set `aria-controls` attribute', fakeAsync(() => {
fixture.detectChanges();

const wrapper = document.querySelector('.sky-autocomplete');
expect(wrapper?.getAttribute('aria-owns')).toBeNull();
expect(wrapper?.getAttribute('aria-controls')).toBeNull();

enterSearch('r', fixture);

const searchResultsContainer = getSearchResultsSection();
expect(wrapper?.getAttribute('aria-owns')).toEqual(
expect(wrapper?.getAttribute('aria-controls')).toEqual(
searchResultsContainer?.id
);

blurInput(getInputElement(), fixture);
expect(wrapper?.getAttribute('aria-owns')).toBeNull();
expect(wrapper?.getAttribute('aria-controls')).toBeNull();
}));

describe('highlighting', () => {
Expand Down
Loading

0 comments on commit 1481956

Please sign in to comment.