[ADF-4958] [ADF-4959] Info Drawer - Buttons don't have role and accessible by keyboard alone (#5161)

* actions accessibility

* lint

* access setEditMode by keyboard

* fix test

* update action automation id reference

* update element finder reference

* update automation id reference
This commit is contained in:
Cilibiu Bogdan 2019-10-17 13:18:15 +03:00 committed by Denys Vuika
parent d7ab0417b8
commit ee5c90871a
6 changed files with 68 additions and 54 deletions

View File

@ -287,9 +287,9 @@ describe('CardView Component', () => {
it('[C279936] Should not be possible edit any parameter when editable property is false', async () => {
await cardViewPageComponent.disableEdit();
const editIconText = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-name"]'));
const editIconInt = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-int"]'));
const editIconFloat = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-float"]'));
const editIconText = element(by.css('button[data-automation-id="card-textitem-edit-icon-name"]'));
const editIconInt = element(by.css('button[data-automation-id="card-textitem-edit-icon-int"]'));
const editIconFloat = element(by.css('button[data-automation-id="card-textitem-edit-icon-float"]'));
const editIconKey = element(by.css('mat-icon[data-automation-id="card-key-value-pairs-button-key-value-pairs"]'));
const editIconData = element(by.css('mat-datetimepicker-toggle'));

View File

@ -52,12 +52,12 @@ export class CardViewComponentPage {
}
async clickOnTextClearIcon(): Promise<void> {
const clearIcon: ElementFinder = element(by.css(`mat-icon[data-automation-id="card-textitem-reset-name"]`));
const clearIcon: ElementFinder = element(by.css(`button[data-automation-id="card-textitem-reset-name"]`));
await BrowserActions.click(clearIcon);
}
async clickOnTextSaveIcon(): Promise<void> {
const saveIcon: ElementFinder = element(by.css(`mat-icon[data-automation-id="card-textitem-update-name"]`));
const saveIcon: ElementFinder = element(by.css(`button[data-automation-id="card-textitem-update-name"]`));
await BrowserActions.click(saveIcon);
}
@ -78,12 +78,12 @@ export class CardViewComponentPage {
}
async clickOnIntClearIcon(): Promise<void> {
const clearIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-reset-int"]'));
const clearIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-reset-int"]'));
await BrowserActions.click(clearIcon);
}
async clickOnIntSaveIcon(): Promise<void> {
const saveIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-update-int"]'));
const saveIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-update-int"]'));
await BrowserActions.click(saveIcon);
}
@ -109,12 +109,12 @@ export class CardViewComponentPage {
}
async clickOnFloatClearIcon(): Promise<void> {
const clearIcon: ElementFinder = element(by.css(`mat-icon[data-automation-id="card-textitem-reset-float"]`));
const clearIcon: ElementFinder = element(by.css(`button[data-automation-id="card-textitem-reset-float"]`));
await BrowserActions.click(clearIcon);
}
async clickOnFloatSaveIcon(): Promise<void> {
const saveIcon: ElementFinder = element(by.css(`mat-icon[data-automation-id="card-textitem-update-float"]`));
const saveIcon: ElementFinder = element(by.css(`button[data-automation-id="card-textitem-update-float"]`));
await BrowserActions.click(saveIcon);
}

View File

@ -136,22 +136,22 @@ export class MetadataViewPage {
}
async editPropertyIconIsDisplayed(propertyName: string) {
const editPropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-' + propertyName + '"]'));
const editPropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-edit-icon-' + propertyName + '"]'));
await BrowserVisibility.waitUntilElementIsPresent(editPropertyIcon);
}
async updatePropertyIconIsDisplayed(propertyName: string) {
const updatePropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-update-' + propertyName + '"]'));
const updatePropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-update-' + propertyName + '"]'));
await BrowserVisibility.waitUntilElementIsVisible(updatePropertyIcon);
}
async clickUpdatePropertyIcon(propertyName: string): Promise<void> {
const updatePropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-update-' + propertyName + '"]'));
const updatePropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-update-' + propertyName + '"]'));
await BrowserActions.click(updatePropertyIcon);
}
async clickClearPropertyIcon(propertyName: string): Promise<void> {
const clearPropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-reset-' + propertyName + '"]'));
const clearPropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-reset-' + propertyName + '"]'));
await BrowserActions.click(clearPropertyIcon);
}
@ -183,17 +183,17 @@ export class MetadataViewPage {
}
async clearPropertyIconIsDisplayed(propertyName: string): Promise<void> {
const clearPropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-reset-' + propertyName + '"]'));
const clearPropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-reset-' + propertyName + '"]'));
await BrowserVisibility.waitUntilElementIsVisible(clearPropertyIcon);
}
async clickEditPropertyIcons(propertyName: string): Promise<void> {
const editPropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-' + propertyName + '"]'));
const editPropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-edit-icon-' + propertyName + '"]'));
await BrowserActions.click(editPropertyIcon);
}
async getPropertyIconTooltip(propertyName: string): Promise<string> {
const editPropertyIcon: ElementFinder = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-' + propertyName + '"]'));
const editPropertyIcon: ElementFinder = element(by.css('button[data-automation-id="card-textitem-edit-icon-' + propertyName + '"]'));
return await editPropertyIcon.getAttribute('title');
}

View File

@ -75,12 +75,12 @@ export class TaskDetailsPage {
}
async checkEditDescriptionButtonIsNotDisplayed(): Promise<void> {
const editDescriptionButton = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-description"]'));
const editDescriptionButton = element(by.css('button[data-automation-id="card-textitem-edit-icon-description"]'));
await BrowserVisibility.waitUntilElementIsNotVisible(editDescriptionButton);
}
async checkEditPriorityButtonIsNotDisplayed(): Promise<void> {
const editPriorityButton = element(by.css('mat-icon[data-automation-id="card-textitem-edit-icon-priority"]'));
const editPriorityButton = element(by.css('button[data-automation-id="card-textitem-edit-icon-priority"]'));
await BrowserVisibility.waitUntilElementIsNotVisible(editPriorityButton);
}

View File

@ -5,7 +5,7 @@
<span *ngIf="showProperty()" class="adf-textitem-ellipsis">{{ property.displayValue }}</span>
</span>
<ng-template #elseBlock>
<div class="adf-textitem-clickable" (click)="clicked()" fxLayout="row" fxLayoutAlign="space-between center">
<div role="button" class="adf-textitem-clickable" (click)="clicked()" fxLayout="row" fxLayoutAlign="space-between center">
<span class="adf-textitem-clickable-value" [attr.data-automation-id]="'card-textitem-value-' + property.key">
<span *ngIf="showProperty(); else elseEmptyValueBlock">{{ property.displayValue }}</span>
</span>
@ -13,14 +13,26 @@
</ng-template>
</span>
<span *ngIf="isEditable()">
<div *ngIf="!inEdit" (click)="setEditMode(true)" class="adf-textitem-readonly" [attr.data-automation-id]="'card-textitem-edit-toggle-' + property.key" fxLayout="row" fxLayoutAlign="space-between center">
<div *ngIf="!inEdit" role="button"
tabindex="0"
[attr.aria-label]="'CORE.METADATA.ACTIONS.EDIT' | translate"
(click)="setEditMode(true)"
(keydown.enter)="setEditMode(true)"
class="adf-textitem-readonly"
[attr.data-automation-id]="'card-textitem-edit-toggle-' + property.key"
fxLayout="row" fxLayoutAlign="space-between center">
<span [attr.data-automation-id]="'card-textitem-value-' + property.key">
<span *ngIf="showProperty(); else elseEmptyValueBlock">{{ property.displayValue }}</span>
</span>
<mat-icon fxFlex="0 0 auto"
[attr.data-automation-id]="'card-textitem-edit-icon-' + property.key"
<button mat-icon-button fxFlex="0 0 auto"
class="adf-textitem-action"
[attr.aria-label]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
class="adf-textitem-icon">create</mat-icon>
[attr.data-automation-id]="'card-textitem-edit-icon-' + property.key">
<mat-icon class="adf-textitem-icon"> create</mat-icon>
</button>
</div>
<div *ngIf="inEdit" class="adf-textitem-editable">
<div class="adf-textitem-editable-controls">
@ -42,21 +54,24 @@
(input)="onTextAreaInputChange()"
[attr.data-automation-id]="'card-textitem-edittextarea-' + property.key"></textarea>
</mat-form-field>
<mat-icon
[ngClass]="{'disable': hasErrors()}"
(click)="update()"
[attr.data-automation-id]="'card-textitem-update-' + property.key"
class="adf-textitem-icon adf-update-icon"
[class.adf-button-disabled]="hasErrors()"
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate">done</mat-icon>
<mat-icon
class="adf-textitem-icon adf-reset-icon"
(click)="reset()"
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
[attr.data-automation-id]="'card-textitem-reset-' + property.key">clear</mat-icon>
<button mat-icon-button class="adf-textitem-action" (click)="update()"
[attr.aria-label]="'CORE.METADATA.ACTIONS.SAVE' | translate"
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
[disabled]="hasErrors()"
[attr.data-automation-id]="'card-textitem-update-' + property.key">
<mat-icon class="adf-textitem-icon">done</mat-icon>
</button>
<button mat-icon-button (click)="reset()" class="adf-textitem-action"
[attr.aria-label]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
[attr.data-automation-id]="'card-textitem-reset-' + property.key">
<mat-icon>clear</mat-icon>
</button>
</div>
<mat-error [attr.data-automation-id]="'card-textitem-error-' + property.key" class="adf-textitem-editable-error" *ngIf="hasErrors()">
<mat-error [attr.data-automation-id]="'card-textitem-error-' + property.key" class="adf-textitem-editable-error" *ngIf="hasErrors()">
<ul>
<li *ngFor="let errorMessage of errorMessages">{{ errorMessage | translate }}</li>
</ul>

View File

@ -1,15 +1,20 @@
@mixin adf-card-view-textitem-theme($theme) {
$foreground: map-get($theme, foreground);
$outline: 1px solid mat-color($alfresco-ecm-blue, A200) !default;
.adf {
&-textitem-icon {
font-size: 16px;
width: 16px;
height: 16px;
position: relative;
top: 4px;
padding-left: 8px;
opacity: 0.3;
}
&-textitem-action {
color: mat-color($foreground, text, 0.25);
}
&-textitem-action:hover, &-textitem-action:focus {
color: mat-color($foreground, text);
}
&-update-icon {
@ -19,14 +24,15 @@
&-textitem-readonly {
cursor: pointer !important;
&:hover mat-icon {
opacity: 1;
&:hover .adf-textitem-action,
&:focus .adf-textitem-action {
color: mat-color($foreground, text);
}
}
&-textitem-clickable {
&:hover mat-icon {
opacity: 1;
&:hover .adf-textitem-action {
color: mat-color($foreground, text);
}
}
@ -39,9 +45,10 @@
&-controls {
display: flex;
align-items: center;
mat-icon:not(.adf-button-disabled):hover {
opacity: 1;
color: mat-color($foreground, text);
cursor: pointer !important;;
}
@ -51,7 +58,7 @@
input:focus,
textarea:focus {
border: 1px solid mat-color($foreground, text, 0.15);
border: $outline;
}
}
@ -126,12 +133,4 @@
display: block;
}
}
.mat-button.adf-update-icon {
min-width: 40px;
line-height: 0;
margin-top: -4px;
padding: 0;
}
}