mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ACS-9267] a11y testing: Datatable - columns settings menu (#10668)
* [ACS-9267] a11y testing: Datatable - columns settings menu * delete comment * [ACS-9267] add empty line * [ACS-9267] adress sonarcloud issues * [ACS-9267] fix unit tests
This commit is contained in:
parent
ba322b70b2
commit
1e83be9194
@ -1137,7 +1137,7 @@ describe('DocumentList', () => {
|
||||
it('should display [empty folder] template ', () => {
|
||||
fixture.detectChanges();
|
||||
runInInjectionContext(injector, () => {
|
||||
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock);
|
||||
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock, null);
|
||||
});
|
||||
expect(documentList.dataTable).toBeDefined();
|
||||
expect(fixture.debugElement.query(By.css('adf-empty-list'))).not.toBeNull();
|
||||
@ -1158,7 +1158,7 @@ describe('DocumentList', () => {
|
||||
|
||||
it('should empty folder NOT show the pagination', () => {
|
||||
runInInjectionContext(injector, () => {
|
||||
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock);
|
||||
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock, null);
|
||||
});
|
||||
|
||||
expect(documentList.isEmpty()).toBeTruthy();
|
||||
|
@ -1,8 +1,7 @@
|
||||
<div
|
||||
class="adf-columns-selector"
|
||||
role="presentation"
|
||||
data-automation-id="adf-columns-selector"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
(keyup.enter)="$event.stopPropagation()"
|
||||
(click)="$event.stopPropagation();"
|
||||
>
|
||||
@ -14,6 +13,8 @@
|
||||
<button
|
||||
data-automation-id="adf-columns-selector-close-button"
|
||||
mat-icon-button
|
||||
role="menuitem"
|
||||
[attr.aria-label]="'CLOSE' | translate"
|
||||
(click)="closeMenu()"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
@ -33,6 +34,7 @@
|
||||
class="adf-columns-selector-search-input"
|
||||
data-automation-id="adf-columns-selector-search-input"
|
||||
type="text"
|
||||
role="menuitem"
|
||||
[placeholder]='"ADF-DATATABLE.COLUMNS_SELECTOR.SEARCH" | translate'>
|
||||
</div>
|
||||
|
||||
@ -43,7 +45,9 @@
|
||||
class="adf-columns-selector-column-checkbox"
|
||||
[attr.data-automation-id]="'adf-columns-selector-column-checkbox-' + column.title"
|
||||
[checked]="!column.isHidden"
|
||||
role="menuitem"
|
||||
[disabled]="isCheckboxDisabled(column)"
|
||||
(keydown.enter)="changeColumnVisibility(column)"
|
||||
(change)="changeColumnVisibility(column)">
|
||||
<div class="adf-columns-selector-list-content">
|
||||
{{column.title | translate}}
|
||||
@ -68,6 +72,7 @@
|
||||
<div class="adf-columns-selector-footer">
|
||||
<button
|
||||
mat-flat-button
|
||||
role="menuitem"
|
||||
data-automation-id="adf-columns-selector-apply-button"
|
||||
color="primary"
|
||||
(click)="apply()">
|
||||
|
@ -161,16 +161,18 @@
|
||||
title="{{ 'ADF-DATATABLE.CONTENT-ACTIONS.SELECT_COLUMNS' | translate }}"
|
||||
mat-icon-button
|
||||
#mainMenuTrigger="matMenuTrigger"
|
||||
(keydown.enter)="mainMenuTrigger.openMenu()"
|
||||
(click)="onMainMenuOpen()"
|
||||
[matMenuTriggerFor]="mainMenu">
|
||||
<mat-icon>view_week_outline</mat-icon>
|
||||
</button>
|
||||
<mat-menu #mainMenu>
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="mainActionTemplate"
|
||||
[ngTemplateOutletContext]="{
|
||||
$implicit: mainMenuTrigger
|
||||
}" />
|
||||
<mat-menu #mainMenu (closed)="onMainMenuClosed()">
|
||||
<div #mainMenuTemplate role="presentation" (keydown.tab)="$event.stopPropagation()">
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="mainActionTemplate"
|
||||
[ngTemplateOutletContext]="{
|
||||
$implicit: mainMenuTrigger
|
||||
}" />
|
||||
</div>
|
||||
</mat-menu>
|
||||
<span class="adf-sr-only">{{ 'ADF-DATATABLE.ACCESSIBILITY.ACTIONS' | translate }}</span>
|
||||
</ng-container>
|
||||
|
@ -34,6 +34,7 @@ import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { UnitTestingUtils } from '../../../testing/unit-testing-utils';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-custom-column-template-component',
|
||||
@ -1508,15 +1509,19 @@ describe('DataTable', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Accesibility', () => {
|
||||
describe('Accessibility', () => {
|
||||
let fixture: ComponentFixture<DataTableComponent>;
|
||||
let dataTable: DataTableComponent;
|
||||
let columnCustomTemplate: TemplateRef<any>;
|
||||
let testingUtils: UnitTestingUtils;
|
||||
|
||||
const focusTrapFactory = jasmine.createSpyObj('ConfigurableFocusTrapFactory', ['create']);
|
||||
const focusTrap = jasmine.createSpyObj('ConfigurableFocusTrap', ['focusInitialElement', 'destroy']);
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, CustomColumnTemplateComponent],
|
||||
providers: [{ provide: ConfigurableFocusTrapFactory, useValue: focusTrapFactory }],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
});
|
||||
columnCustomTemplate = TestBed.createComponent(CustomColumnTemplateComponent).componentInstance.templateRef;
|
||||
@ -1708,6 +1713,36 @@ describe('Accesibility', () => {
|
||||
const cell = testingUtils.getByCSS('.adf-datatable-row[data-automation-id="datatable-row-0"] .adf-cell-value');
|
||||
expect(cell?.nativeElement.getAttribute('tabindex')).toBe('0');
|
||||
});
|
||||
|
||||
it('should create focus trap on main menu open', () => {
|
||||
dataTable.showHeader = ShowHeaderMode.Always;
|
||||
dataTable.showMainDatatableActions = true;
|
||||
dataTable.mainActionTemplate = columnCustomTemplate;
|
||||
focusTrapFactory.create.and.returnValue(focusTrap);
|
||||
spyOn(dataTable, 'onMainMenuOpen').and.callThrough();
|
||||
|
||||
dataTable.ngOnChanges({
|
||||
rows: new SimpleChange(null, [{ name: 'test1' }, { name: 'test2' }], false)
|
||||
});
|
||||
fixture.detectChanges();
|
||||
dataTable.ngAfterViewInit();
|
||||
|
||||
testingUtils.clickByDataAutomationId('adf-datatable-main-menu-button');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dataTable.onMainMenuOpen).toHaveBeenCalled();
|
||||
expect(focusTrapFactory.create).toHaveBeenCalledWith(dataTable.mainMenuTemplate.nativeElement);
|
||||
expect(focusTrap.focusInitialElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should destroy focus trap on main menu closed', () => {
|
||||
dataTable.focusTrap = focusTrap;
|
||||
|
||||
dataTable.onMainMenuClosed();
|
||||
|
||||
expect(focusTrap.destroy).toHaveBeenCalled();
|
||||
expect(dataTable.focusTrap).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Drag&Drop column header', () => {
|
||||
|
@ -38,10 +38,11 @@ import {
|
||||
SimpleChange,
|
||||
SimpleChanges,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
ViewChildren,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { FocusKeyManager } from '@angular/cdk/a11y';
|
||||
import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory, FocusKeyManager } from '@angular/cdk/a11y';
|
||||
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
|
||||
import { Observable, Observer, Subscription } from 'rxjs';
|
||||
@ -133,6 +134,9 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
@ViewChildren(DataTableRowComponent)
|
||||
rowsList: QueryList<DataTableRowComponent>;
|
||||
|
||||
@ViewChild('mainMenuTemplate')
|
||||
mainMenuTemplate: ElementRef;
|
||||
|
||||
@ContentChild(DataColumnListComponent)
|
||||
columnList: DataColumnListComponent;
|
||||
|
||||
@ -324,6 +328,7 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
hoveredHeaderColumnIndex = -1;
|
||||
resizingColumnIndex = -1;
|
||||
isDraggingRow = false;
|
||||
focusTrap: ConfigurableFocusTrap;
|
||||
|
||||
private keyManager: FocusKeyManager<DataTableRowComponent>;
|
||||
private clickObserver: Observer<DataRowEvent>;
|
||||
@ -342,7 +347,13 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
this.keyManager.onKeydown(event);
|
||||
}
|
||||
|
||||
constructor(private elementRef: ElementRef, differs: IterableDiffers, private matIconRegistry: MatIconRegistry, private sanitizer: DomSanitizer) {
|
||||
constructor(
|
||||
private readonly elementRef: ElementRef,
|
||||
differs: IterableDiffers,
|
||||
private readonly matIconRegistry: MatIconRegistry,
|
||||
private readonly sanitizer: DomSanitizer,
|
||||
private readonly focusTrapFactory: ConfigurableFocusTrapFactory
|
||||
) {
|
||||
if (differs) {
|
||||
this.differ = differs.find([]).create(null);
|
||||
}
|
||||
@ -465,6 +476,20 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
return null;
|
||||
}
|
||||
|
||||
onMainMenuOpen() {
|
||||
if (this.mainMenuTemplate && !this.focusTrap) {
|
||||
this.focusTrap = this.focusTrapFactory.create(this.mainMenuTemplate.nativeElement);
|
||||
this.focusTrap.focusInitialElement();
|
||||
}
|
||||
}
|
||||
|
||||
onMainMenuClosed() {
|
||||
if (this.focusTrap) {
|
||||
this.focusTrap.destroy();
|
||||
this.focusTrap = null;
|
||||
}
|
||||
}
|
||||
|
||||
private initAndSubscribeClickStream() {
|
||||
this.unsubscribeClickStream();
|
||||
const singleClickStream = this.click$.pipe(
|
||||
|
Loading…
x
Reference in New Issue
Block a user