[ADF-4802] Login accessibility (#4988)

* login button aria label

* password toggle accessibility

* translation

* fix test

* fix automation if
This commit is contained in:
Cilibiu Bogdan
2019-08-12 18:41:32 +03:00
committed by Denys Vuika
parent b176a43fba
commit 3453cacaea
5 changed files with 42 additions and 23 deletions

View File

@@ -5,8 +5,8 @@
"CLAIM": "CLAIM", "CLAIM": "CLAIM",
"UNCLAIM": "RELEASE", "UNCLAIM": "RELEASE",
"START PROCESS": "START PROCESS", "START PROCESS": "START PROCESS",
"NOTIFICATION_HISTORY":{ "NOTIFICATION_HISTORY": {
"NO_MESSAGE" : "No messages", "NO_MESSAGE": "No messages",
"NOTIFICATIONS": "Notifications", "NOTIFICATIONS": "Notifications",
"MARK_AS_READ": "Mark all as read" "MARK_AS_READ": "Mark all as read"
}, },
@@ -208,13 +208,17 @@
} }
}, },
"LOGIN": { "LOGIN": {
"LOGO": "Alfresco", "LOGO": "Alfresco, make business flow",
"LABEL": { "LABEL": {
"LOGIN": "Sign in", "LOGIN": "Sign in",
"USERNAME": "Username", "USERNAME": "Username",
"PASSWORD": "Password", "PASSWORD": "Password",
"REMEMBER": "Remember me" "REMEMBER": "Remember me"
}, },
"ARIA-LABEL": {
"SHOW-PASSWORD": "Show password",
"HIDE-PASSWORD": "Hide password"
},
"MESSAGES": { "MESSAGES": {
"USERNAME-REQUIRED": "Required", "USERNAME-REQUIRED": "Required",
"USERNAME-MIN": "Your username needs to be at least {{ minLength }} characters.", "USERNAME-MIN": "Your username needs to be at least {{ minLength }} characters.",
@@ -253,8 +257,8 @@
"TOOLTIP": "Content actions" "TOOLTIP": "Content actions"
}, },
"ACCESSIBILITY": { "ACCESSIBILITY": {
"SELECT_ALL": "Select all", "SELECT_ALL": "Select all",
"SELECT_FILE": "Select file" "SELECT_FILE": "Select file"
} }
}, },
"USER_PROFILE": { "USER_PROFILE": {

View File

@@ -58,14 +58,21 @@
[formControl]="form.controls['password']" [formControl]="form.controls['password']"
id="password" id="password"
data-automation-id="password"> data-automation-id="password">
<mat-icon *ngIf="isPasswordShow" matSuffix class="adf-login-password-icon" <button
data-automation-id="hide_password" (click)="toggleShowPassword()" (keyup.enter)="toggleShowPassword()"> matSuffix
visibility mat-icon-button
</mat-icon> type="button"
<mat-icon *ngIf="!isPasswordShow" matSuffix class="adf-login-password-icon" [attr.aria-label]="(isPasswordShow ?
data-automation-id="show_password" (click)="toggleShowPassword()" (keyup.enter)="toggleShowPassword()"> 'LOGIN.ARIA-LABEL.HIDE-PASSWORD':
visibility_off 'LOGIN.ARIA-LABEL.SHOW-PASSWORD'
</mat-icon> ) | translate"
(click)="toggleShowPassword($event)"
(keyup.enter)="toggleShowPassword($event)"
[attr.data-automation-id]="isPasswordShow ? 'hide_password':'show_password'">
<mat-icon class="adf-login-password-icon">
{{ isPasswordShow ? 'visibility':'visibility_off' }}
</mat-icon>
</button>
</mat-form-field> </mat-form-field>
<span class="adf-login-validation" for="password" *ngIf="formError['password']"> <span class="adf-login-validation" for="password" *ngIf="formError['password']">
<span id="password-required" class="adf-login-error" <span id="password-required" class="adf-login-error"
@@ -82,7 +89,8 @@
mat-raised-button color="primary" mat-raised-button color="primary"
[class.adf-isChecking]="actualLoginStep === LoginSteps.Checking" [class.adf-isChecking]="actualLoginStep === LoginSteps.Checking"
[class.adf-isWelcome]="actualLoginStep === LoginSteps.Welcome" [class.adf-isWelcome]="actualLoginStep === LoginSteps.Welcome"
data-automation-id="login-button" [disabled]="!form.valid"> data-automation-id="login-button" [disabled]="!form.valid"
[attr.aria-label]="'LOGIN.BUTTON.LOGIN' | translate">
<span *ngIf="actualLoginStep === LoginSteps.Landing" class="adf-login-button-label">{{ 'LOGIN.BUTTON.LOGIN' | translate }}</span> <span *ngIf="actualLoginStep === LoginSteps.Landing" class="adf-login-button-label">{{ 'LOGIN.BUTTON.LOGIN' | translate }}</span>
@@ -113,6 +121,7 @@
<div *ngIf="implicitFlow"> <div *ngIf="implicitFlow">
<button type="button" (click)="implicitLogin()" id="login-button-sso" <button type="button" (click)="implicitLogin()" id="login-button-sso"
[attr.aria-label]="'LOGIN.BUTTON.SSO' | translate"
class="adf-login-button" class="adf-login-button"
mat-raised-button color="primary" mat-raised-button color="primary"
data-automation-id="login-button-sso"> data-automation-id="login-button-sso">

View File

@@ -98,16 +98,22 @@ describe('LoginComponent', () => {
passwordInput.dispatchEvent(new Event('input')); passwordInput.dispatchEvent(new Event('input'));
fixture.detectChanges(); fixture.detectChanges();
element.querySelector('button').click(); element.querySelector('.adf-login-button').click();
fixture.detectChanges(); fixture.detectChanges();
} }
it('should be autocomplete off', () => { it('should be autocomplete off', () => {
expect(element.querySelector('#adf-login-form').getAttribute('autocomplete')).toBe('off'); expect(
element
.querySelector('#adf-login-form')
.getAttribute('autocomplete')
).toBe('off');
}); });
it('should redirect to route on successful login', () => { it('should redirect to route on successful login', () => {
spyOn(authService, 'login').and.returnValue(of({ type: 'type', ticket: 'ticket' })); spyOn(authService, 'login').and.returnValue(
of({ type: 'type', ticket: 'ticket' })
);
const redirect = '/home'; const redirect = '/home';
component.successRoute = redirect; component.successRoute = redirect;
spyOn(router, 'navigate'); spyOn(router, 'navigate');
@@ -572,7 +578,7 @@ describe('LoginComponent', () => {
it('should render the password in clear when the toggleShowPassword is call', () => { it('should render the password in clear when the toggleShowPassword is call', () => {
component.isPasswordShow = false; component.isPasswordShow = false;
component.toggleShowPassword(); component.toggleShowPassword(new MouseEvent('click'));
fixture.detectChanges(); fixture.detectChanges();
@@ -582,7 +588,7 @@ describe('LoginComponent', () => {
it('should render the hide password when the password is in clear and the toggleShowPassword is call', () => { it('should render the hide password when the password is in clear and the toggleShowPassword is call', () => {
component.isPasswordShow = true; component.isPasswordShow = true;
component.toggleShowPassword(); component.toggleShowPassword(new MouseEvent('click'));
fixture.detectChanges(); fixture.detectChanges();

View File

@@ -342,7 +342,8 @@ export class LoginComponent implements OnInit, OnDestroy {
/** /**
* Display and hide the password value. * Display and hide the password value.
*/ */
toggleShowPassword() { toggleShowPassword(event: MouseEvent | KeyboardEvent) {
event.stopPropagation();
this.isPasswordShow = !this.isPasswordShow; this.isPasswordShow = !this.isPasswordShow;
} }

View File

@@ -22,7 +22,6 @@ import { LocalStorageUtil } from '../utils/local-storage.util';
import { BrowserActions } from '../utils/browser-actions'; import { BrowserActions } from '../utils/browser-actions';
export class LoginPage { export class LoginPage {
loginURL = browser.baseUrl + '/login'; loginURL = browser.baseUrl + '/login';
formControllersPage = new FormControllersPage(); formControllersPage = new FormControllersPage();
@@ -55,10 +54,10 @@ export class LoginPage {
); );
signInButton = element(by.id('login-button')); signInButton = element(by.id('login-button'));
showPasswordElement = element( showPasswordElement = element(
by.css('mat-icon[data-automation-id="show_password"]') by.css('button[data-automation-id="show_password"]')
); );
hidePasswordElement = element( hidePasswordElement = element(
by.css('mat-icon[data-automation-id="hide_password"]') by.css('button[data-automation-id="hide_password"]')
); );
rememberMe = element(by.css('mat-checkbox[id="adf-login-remember"]')); rememberMe = element(by.css('mat-checkbox[id="adf-login-remember"]'));
needHelp = element(by.css('div[id="adf-login-action-left"]')); needHelp = element(by.css('div[id="adf-login-action-left"]'));