mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-3497] - Fix accessibility issues in ACA personal files (#7833)
This commit is contained in:
@@ -72,7 +72,7 @@
|
||||
role="navigation"
|
||||
[attr.aria-label]="'BREADCRUMB.ARIA-LABEL.BREADCRUMB' | translate"
|
||||
>
|
||||
<div class="adf-breadcrumb-item adf-active" role="listitem">
|
||||
<div class="adf-breadcrumb-item adf-active" role="group">
|
||||
<div class="adf-breadcrumb-item-current" role="heading" aria-level="2">
|
||||
{{ root | translate }}
|
||||
</div>
|
||||
|
@@ -63,7 +63,7 @@ describe('UserIconColumnComponent', () => {
|
||||
};
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[id="user-initials-image"]').textContent).toContain('fu');
|
||||
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('fu');
|
||||
});
|
||||
|
||||
it('should render person value from node', () => {
|
||||
@@ -80,7 +80,7 @@ describe('UserIconColumnComponent', () => {
|
||||
} as NodeEntry;
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[id="user-initials-image"]').textContent).toContain('FU');
|
||||
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('FU');
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
class="adf-filter">
|
||||
<button mat-icon-button
|
||||
[matMenuTriggerFor]="filter"
|
||||
id="filter-menu-button"
|
||||
data-automation-id="filter-menu-button"
|
||||
#menuTrigger="matMenuTrigger"
|
||||
(click)="$event.stopPropagation()"
|
||||
(menuOpened)="onMenuOpen()"
|
||||
@@ -22,6 +22,7 @@
|
||||
class="adf-filter-menu"
|
||||
(closed)="onClosed()">
|
||||
<div #filterContainer
|
||||
role="menuitem"
|
||||
(keydown.tab)="$event.stopPropagation();">
|
||||
<div (click)="$event.stopPropagation()"
|
||||
class="adf-filter-container">
|
||||
|
@@ -86,7 +86,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
});
|
||||
|
||||
it('should set/update the active filter after the Apply button is clicked', async () => {
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('#filter-menu-button');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
|
||||
menuButton.click();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -113,7 +113,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
|
||||
it('should remove active filter after the Clear button is clicked', async () => {
|
||||
queryBuilder.setActiveFilter('name', 'searchText');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('#filter-menu-button');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
|
||||
menuButton.click();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -133,7 +133,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
component.filterChange.subscribe(() => {
|
||||
eventRaised = true;
|
||||
});
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('#filter-menu-button');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
|
||||
menuButton.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -154,7 +154,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
it('should set up a focus trap on the filter when the menu is opened', async () => {
|
||||
expect(component.focusTrap).toBeUndefined();
|
||||
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('#filter-menu-button');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
|
||||
menuButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -164,7 +164,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
});
|
||||
|
||||
it('should focus the input element when the menu is opened', async () => {
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('#filter-menu-button');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
|
||||
menuButton.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -176,7 +176,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
});
|
||||
|
||||
it('should focus the menu trigger when the menu is closed', async () => {
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('#filter-menu-button');
|
||||
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
|
||||
menuButton.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -188,7 +188,7 @@ describe('SearchFilterContainerComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const matMenuButton = fixture.debugElement.query(By.css('#filter-menu-button'));
|
||||
const matMenuButton = fixture.debugElement.query(By.css('[data-automation-id="filter-menu-button"]'));
|
||||
expect(document.activeElement).toBe(matMenuButton.nativeElement);
|
||||
});
|
||||
});
|
||||
|
@@ -67,7 +67,6 @@ describe('DateCellComponent', () => {
|
||||
const tooltipValue = dateCellValue.attributes['title'].value;
|
||||
|
||||
expect(dateCellValue.textContent.trim()).toEqual('Jul 14, 2022');
|
||||
expect(dateCellValue.attributes['aria-label'].value).toEqual('Jul 14, 2022');
|
||||
expect(tooltipValue).toEqual('Jul 14, 2022, 11:50:45 AM');
|
||||
});
|
||||
});
|
||||
|
@@ -45,7 +45,6 @@ import { takeUntil } from 'rxjs/operators';
|
||||
</ng-container>
|
||||
<ng-template #defaultCell>
|
||||
<span
|
||||
[attr.aria-label]="value$ | async"
|
||||
[title]="tooltip"
|
||||
class="adf-datatable-cell-value"
|
||||
>{{ value$ | async }}</span>
|
||||
|
@@ -31,7 +31,6 @@ import { takeUntil } from 'rxjs/operators';
|
||||
template: `
|
||||
<ng-container>
|
||||
<span
|
||||
[attr.aria-label]="value$ | async | adfTimeAgo: currentLocale"
|
||||
title="{{ tooltip | adfLocalizedDate: 'medium' }}"
|
||||
class="adf-datatable-cell-value"
|
||||
*ngIf="format === 'timeAgo'; else standard_date">
|
||||
@@ -41,8 +40,7 @@ import { takeUntil } from 'rxjs/operators';
|
||||
<ng-template #standard_date>
|
||||
<span
|
||||
class="adf-datatable-cell-value"
|
||||
title="{{ tooltip | adfLocalizedDate: tooltipDateFormat }}"
|
||||
[attr.aria-label]="value$ | async | adfLocalizedDate: format">
|
||||
title="{{ tooltip | adfLocalizedDate: tooltipDateFormat }}">
|
||||
{{ value$ | async | adfLocalizedDate: format }}
|
||||
</span>
|
||||
</ng-template>
|
||||
|
@@ -25,7 +25,6 @@ import { AlfrescoApiService } from '../../../services/alfresco-api.service';
|
||||
<ng-container *ngIf="(value$ | async | adfFileSize) as fileSize">
|
||||
<span
|
||||
[title]="tooltip"
|
||||
[attr.aria-label]="fileSize"
|
||||
>{{ fileSize }}</span
|
||||
>
|
||||
</ng-container>
|
||||
|
@@ -25,7 +25,8 @@
|
||||
"TITLE": "Notifications",
|
||||
"MARK_AS_READ": "Mark all as read",
|
||||
"SYSTEM": "System",
|
||||
"LOAD_MORE": "Load more"
|
||||
"LOAD_MORE": "Load more",
|
||||
"OPEN_HISTORY": "Open notification history"
|
||||
},
|
||||
"FORM": {
|
||||
"START_FORM": {
|
||||
|
@@ -1,6 +1,8 @@
|
||||
<div (keyup)="onKeyPress($event)">
|
||||
<button mat-button
|
||||
[matMenuTriggerFor]="menu"
|
||||
[attr.aria-label]="'NOTIFICATIONS.OPEN_HISTORY' | translate"
|
||||
title="{{ 'NOTIFICATIONS.OPEN_HISTORY' | translate }}"
|
||||
class="adf-notification-history-menu_button"
|
||||
id="adf-notification-history-open-button"
|
||||
(menuOpened)="onMenuOpened()">
|
||||
@@ -17,7 +19,7 @@
|
||||
|
||||
<div class="adf-notification-history-list"
|
||||
(click)="$event.stopPropagation()">
|
||||
<div mat-subheader>
|
||||
<div mat-subheader role="menuitem">
|
||||
<span>{{ 'NOTIFICATIONS.TITLE' | translate }}</span>
|
||||
<button (click)="markAsRead()"
|
||||
id="adf-notification-history-mark-as-read"
|
||||
@@ -30,7 +32,7 @@
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list>
|
||||
<mat-list role="menuitem">
|
||||
<ng-container *ngIf="notifications.length; else empty_list_template">
|
||||
<mat-list-item *ngFor="let notification of paginatedNotifications"
|
||||
class="adf-notification-history-menu-item"
|
||||
@@ -54,7 +56,7 @@
|
||||
<ng-template #empty_list_template>
|
||||
<mat-list-item id="adf-notification-history-component-no-message"
|
||||
class="adf-notification-history-menu-no-message">
|
||||
<h4 mat-line>{{ 'NOTIFICATIONS.NO_MESSAGE' | translate }}</h4>
|
||||
<p mat-line>{{ 'NOTIFICATIONS.NO_MESSAGE' | translate }}</p>
|
||||
</mat-list-item>
|
||||
</ng-template>
|
||||
</mat-list>
|
||||
@@ -62,6 +64,7 @@
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div class="adf-notification-history-load-more"
|
||||
role="menuitem"
|
||||
*ngIf="hasMoreNotifications()">
|
||||
<button mat-button
|
||||
(click)="loadMore()">
|
||||
|
@@ -64,28 +64,28 @@ describe('UserInitialPipe', () => {
|
||||
fakeUser.firstName = 'FAKE-NAME';
|
||||
fakeUser.lastName = 'FAKE-SURNAME';
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">FF</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">FF</div>');
|
||||
});
|
||||
|
||||
it('should apply the style class passed in input', () => {
|
||||
fakeUser.firstName = 'FAKE-NAME';
|
||||
fakeUser.lastName = 'FAKE-SURNAME';
|
||||
const result = pipe.transform(fakeUser, 'fake-class-to-check');
|
||||
expect(result).toBe('<div id="user-initials-image" class="fake-class-to-check">FF</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="fake-class-to-check">FF</div>');
|
||||
});
|
||||
|
||||
it('should return a single letter into div when lastName is undefined', () => {
|
||||
fakeUser.firstName = 'FAKE-NAME';
|
||||
fakeUser.lastName = undefined;
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">F</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">F</div>');
|
||||
});
|
||||
|
||||
it('should return a single letter into div when firstname is null', () => {
|
||||
fakeUser.firstName = undefined;
|
||||
fakeUser.lastName = 'FAKE-SURNAME';
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">F</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">F</div>');
|
||||
});
|
||||
|
||||
it('should return a single letter into div when only username is defined', () => {
|
||||
@@ -93,7 +93,7 @@ describe('UserInitialPipe', () => {
|
||||
fakeUser.lastName = undefined;
|
||||
fakeUser.username = 'USERNAME-FAKE';
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">U</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">U</div>');
|
||||
});
|
||||
|
||||
it('should return a single letter into div of firstName when only firstName and username is defined', () => {
|
||||
@@ -101,7 +101,7 @@ describe('UserInitialPipe', () => {
|
||||
fakeUser.lastName = undefined;
|
||||
fakeUser.username = 'USERNAME-FAKE';
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">F</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">F</div>');
|
||||
});
|
||||
|
||||
it('should return two letter into div of username and lastName when firstName is undefined', () => {
|
||||
@@ -109,7 +109,7 @@ describe('UserInitialPipe', () => {
|
||||
fakeUser.lastName = 'FAKE-SURNAME';
|
||||
fakeUser.username = 'USERNAME-FAKE';
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">UF</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">UF</div>');
|
||||
});
|
||||
|
||||
it('should return a div with the user initials when firstName, lastName and username is defined', () => {
|
||||
@@ -117,7 +117,7 @@ describe('UserInitialPipe', () => {
|
||||
fakeUser.lastName = 'FAKE-SURNAME';
|
||||
fakeUser.username = 'USERNAME-FAKE';
|
||||
const result = pipe.transform(fakeUser);
|
||||
expect(result).toBe('<div id="user-initials-image" class="">FF</div>');
|
||||
expect(result).toBe('<div data-automation-id="user-initials-image" class="">FF</div>');
|
||||
});
|
||||
|
||||
it('should return an empty string when user is null', () => {
|
||||
|
@@ -31,7 +31,7 @@ export class InitialUsernamePipe implements PipeTransform {
|
||||
let safeHtml: SafeHtml = '';
|
||||
if (user) {
|
||||
const initialResult = this.getInitialUserName(user.firstName || user.displayName || user.username, user.lastName, delimiter);
|
||||
safeHtml = this.sanitized.bypassSecurityTrustHtml(`<div id="user-initials-image" class="${className}">${initialResult}</div>`);
|
||||
safeHtml = this.sanitized.bypassSecurityTrustHtml(`<div data-automation-id="user-initials-image" class="${className}">${initialResult}</div>`);
|
||||
}
|
||||
return safeHtml;
|
||||
}
|
||||
|
@@ -55,9 +55,9 @@
|
||||
</button>
|
||||
<mat-menu #menu="matMenu" id="user-profile-lists" [xPosition]="menuPositionX" [yPosition]="menuPositionY"
|
||||
[overlapTrigger]="false" class="adf-userinfo-menu">
|
||||
<mat-tab-group id="tab-group-env" (click)="stopClosing($event)" selectedIndex="0"
|
||||
<mat-tab-group id="tab-group-env" (click)="stopClosing($event)" selectedIndex="0" role="menuitem"
|
||||
class="adf-userinfo-tab" [class.adf-hide-tab]="!(bpmUser$ | async) || !(ecmUser$ | async)">
|
||||
<mat-tab id="ecm-panel" label="{{ 'USER_PROFILE.TAB.CS' | translate }}"
|
||||
<mat-tab id="ecm-panel" label="{{ 'USER_PROFILE.TAB.CS' | translate }}" role="dialog"
|
||||
*ngIf="mode==='CONTENT' || mode==='ALL'">
|
||||
<mat-card class="adf-userinfo-card" *ngIf="ecmUser$ | async as ecmUser">
|
||||
<mat-card-header class="adf-userinfo-card-header"
|
||||
@@ -94,7 +94,7 @@
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</mat-tab>
|
||||
<mat-tab id="bpm-panel" label="{{ 'USER_PROFILE.TAB.PS' | translate }}"
|
||||
<mat-tab id="bpm-panel" label="{{ 'USER_PROFILE.TAB.PS' | translate }}" role="dialog"
|
||||
*ngIf="mode==='PROCESS' || mode==='ALL'">
|
||||
<mat-card class="adf-userinfo-card" *ngIf="bpmUser$ | async as bpmUser">
|
||||
<mat-card-header class="adf-userinfo-card-header"
|
||||
@@ -126,7 +126,7 @@
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</mat-tab>
|
||||
<mat-tab id="identity-panel" *ngIf="mode==='SSO'">
|
||||
<mat-tab id="identity-panel" role="dialog" *ngIf="mode==='SSO'">
|
||||
<mat-card class="adf-userinfo-card" *ngIf="identityUser$ | async as identityUser">
|
||||
<mat-card-header class="adf-userinfo-card-header"
|
||||
[style.background-image]="'url(' + bpmBackgroundImage + ')'">
|
||||
|
@@ -258,7 +258,7 @@ describe('User info component', () => {
|
||||
});
|
||||
|
||||
it('should show N/A when the job title is null', () => {
|
||||
const imageButton = element.querySelector<HTMLButtonElement>('#user-initials-image');
|
||||
const imageButton = element.querySelector<HTMLButtonElement>('[data-automation-id="user-initials-image"]');
|
||||
imageButton.click();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('#userinfo_container')).not.toBeNull();
|
||||
@@ -269,7 +269,7 @@ describe('User info component', () => {
|
||||
});
|
||||
|
||||
it('should not show the tabs', () => {
|
||||
const imageButton = element.querySelector<HTMLButtonElement>('#user-initials-image');
|
||||
const imageButton = element.querySelector<HTMLButtonElement>('[data-automation-id="user-initials-image"]');
|
||||
imageButton.click();
|
||||
fixture.detectChanges();
|
||||
const tabHeader = fixture.debugElement.query(By.css('#tab-group-env'));
|
||||
@@ -285,7 +285,7 @@ describe('User info component', () => {
|
||||
lastName: 'Adams',
|
||||
email: 'wilbur@app.com'
|
||||
});
|
||||
expect(expected).toBe('<div id="user-initials-image" class="">WA</div>');
|
||||
expect(expected).toBe('<div data-automation-id="user-initials-image" class="">WA</div>');
|
||||
component.ecmUser$.subscribe((response: EcmUserModel) => {
|
||||
expect(response).toBeDefined();
|
||||
expect(response.avatarId).toBeNull();
|
||||
@@ -421,7 +421,7 @@ describe('User info component', () => {
|
||||
await whenFixtureReady();
|
||||
|
||||
expect(element.querySelector('#userinfo_container')).toBeDefined();
|
||||
expect(element.querySelector('#user-initials-image').textContent).toContain('ff');
|
||||
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('ff');
|
||||
});
|
||||
|
||||
it('should show the tabs for the env', async () => {
|
||||
@@ -462,7 +462,7 @@ describe('User info component', () => {
|
||||
it('should show the identity user initials if is not ecm user', async () => {
|
||||
await whenFixtureReady();
|
||||
expect(element.querySelector('#userinfo_container')).toBeDefined();
|
||||
expect(element.querySelector('#user-initials-image').textContent).toContain('ff');
|
||||
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('ff');
|
||||
});
|
||||
|
||||
it('should able to fetch identity userInfo', (done) => {
|
||||
|
@@ -34,7 +34,7 @@ export class UserInfoPage {
|
||||
processTenant = $('.detail-profile');
|
||||
apsImage = $('img[id="bpm-user-detail-image"]');
|
||||
acsImage = $('img[id="ecm-user-detail-image"]');
|
||||
initialImage = $$('div[id="user-initials-image"]').first();
|
||||
initialImage = $$('div[data-automation-id="user-initials-image"]').first();
|
||||
userInfoSsoHeaderTitle = this.dialog.$('div[id="identity-username"]');
|
||||
userInfoSsoTitle = $('.adf-userinfo__detail-title');
|
||||
ssoEmail = $('#identity-email');
|
||||
|
Reference in New Issue
Block a user