[MM-62986][MM-63011][MM-63013][MM-63014][MM-63018] Various accessibility fixes around login, account creation and MFA setup (#30847)

* [MM-62986] Ensure focus goes back to the inputs after an error for Login/Create Account/MFA

* [MM-63011] Show outline on Mattermost logo link when focused

* [MM-63018] Remove tabindex from the login/signup cards and use <form> element for submit

* [MM-63014] Toggle aria-label when show/hide password is pressed

* [MM-63013] Mention the field name when showing an error message about the password field

* Fix lint

* Update screenshots and fix tests

* Update screenshots and fix tests

* Fix tests

* Update webapp/channels/src/components/mfa/setup/setup.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

* update screenshots

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Этот коммит содержится в:
Devin Binnie
2025-05-07 15:19:33 -04:00
коммит произвёл GitHub
родитель 92011a6c75
Коммит ee61301b67
36 изменённых файлов: 262 добавлений и 89 удалений

Просмотреть файл

@@ -80,8 +80,8 @@ describe('Profile', () => {
// # Save
cy.uiSave();
// * Verify for error message: "Must be 5-72 characters long."
cy.get('#clientError').should('be.visible').should('have.text', 'Must be 5-72 characters long.');
// * Verify for error message: "Your password must be 5-72 characters long."
cy.get('#clientError').should('be.visible').should('have.text', 'Your password must be 5-72 characters long.');
});
it('MM-T2084 Password: Cancel out of password changes causes no changes to be made', () => {

Просмотреть файл

@@ -49,7 +49,7 @@ describe('Authentication', () => {
cy.uiSave();
cy.findByText('Must be 7-72 characters long.').should('be.visible');
cy.findByText('Your password must be 7-72 characters long.').should('be.visible');
cy.apiLogout();
@@ -65,7 +65,7 @@ describe('Authentication', () => {
cy.findByText('Create Account').click();
// * Assert the error is what is expected;
cy.findByText('Must be 7-72 characters long.').should('be.visible');
cy.findByText('Your password must be 7-72 characters long.').should('be.visible');
cy.get('#input_password-input').clear().type('greaterthan7');
@@ -118,7 +118,7 @@ describe('Authentication', () => {
cy.findByText('Create Account').click();
// * Assert the error is what is expected;
cy.findByText('Must be 5-72 characters long and include both lowercase and uppercase letters, numbers, and special characters.').should('be.visible');
cy.findByText('Your password must be 5-72 characters long and include both lowercase and uppercase letters, numbers, and special characters.').should('be.visible');
});
});

Просмотреть файл

@@ -58,7 +58,7 @@ describe('Authentication', () => {
cy.visit('/login');
// # Remove autofocus from login input
cy.get('.login-body-card-content').should('be.visible').focus();
cy.get('.login-body-card-title').click();
// # Clear email/username field and type username
cy.apiGetClientLicense().then(({isLicensed}) => {

Просмотреть файл

@@ -28,8 +28,8 @@ describe('Managing bot accounts', () => {
cy.apiLogout();
cy.visit('/login');
// # Remove autofocus from login input
cy.get('.login-body-card-content').should('be.visible').focus();
// # Click on card titile to remove auto focus from the email field
cy.get('.login-body-card-title').click();
// # Enter bot name in the email field
cy.findByPlaceholderText('Email, Username or AD/LDAP Username', {timeout: TIMEOUTS.ONE_MIN}).clear().type(botName);

Просмотреть файл

@@ -22,7 +22,7 @@ describe('SignIn Authentication', () => {
cy.visit('/login');
// # Remove autofocus from login input
cy.get('.login-body-card-content').should('be.visible').focus();
cy.get('.login-body-card-title').click();
});
});
@@ -48,7 +48,7 @@ describe('SignIn Authentication', () => {
cy.url().should('include', '/login');
// # Remove autofocus from login input
cy.get('.login-body-card-content').should('be.visible').focus();
cy.get('.login-body-card-title').click();
// # Enter actual user's username in the email field
cy.findByPlaceholderText(loginPlaceholder).clear().type(testUser.username);

Просмотреть файл

@@ -46,8 +46,8 @@ describe('Login page with open server', () => {
// * Verify title of the document is correct
cy.title().should('include', config.TeamSettings.SiteName);
// # Remove autofocus from login id input
cy.get('.login-body-card-content').should('be.visible').focus();
// # Remove autofocus from login input
cy.get('.login-body-card-title').click();
// * Verify email/username field is present
cy.findByPlaceholderText('Email or Username').should('exist').and('be.visible');
@@ -156,6 +156,9 @@ describe('Login page with open server', () => {
it('MM-T3306_7 Should show error with invalid password', () => {
const invalidPassword = `${Date.now()}-password`;
// Remove autofocus from login input
cy.get('.login-body-card-title').click();
// # Lets verify generated password is not an actual password
expect(invalidPassword).to.not.equal(testUser.password);
@@ -173,6 +176,9 @@ describe('Login page with open server', () => {
});
it('MM-T3306_8 Should login with a valid email and password and logout', () => {
// Remove autofocus from login input
cy.get('.login-body-card-title').click();
// # Enter actual users email/username in the email field
cy.findByPlaceholderText('Email or Username').clear().type(testUser.username);
@@ -196,8 +202,8 @@ describe('Login page with open server', () => {
// # Visit login page
cy.visit('/login');
// # Remove autofocus from login id input
cy.get('.login-body-card-content').should('be.visible').focus();
// # Remove autofocus from login input
cy.get('.login-body-card-title').click();
// # Enter actual users email/username in the email field
cy.findByPlaceholderText('Email or Username').clear().type(testUser.username);

Просмотреть файл

@@ -75,7 +75,7 @@ describe('Signup Email page', () => {
cy.findByText('You can use lowercase letters, numbers, periods, dashes, and underscores.').should('be.visible');
cy.get('#input_password-input').should('be.visible').and('have.attr', 'placeholder', 'Choose a Password');
cy.findByText('Must be 5-72 characters long.').should('be.visible');
cy.findByText('Your password must be 5-72 characters long.').should('be.visible');
cy.get('#saveSetting').scrollIntoView().should('be.visible');
cy.get('#saveSetting').should('contain', 'Create Account');

Просмотреть файл

@@ -164,7 +164,7 @@ describe('System Console > User Management > Users', () => {
// * Verify the appropriate error is returned.
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').
and('contain', 'Must be 5-72 characters long.');
and('contain', 'Your password must be 5-72 characters long.');
});
it('MM-T936 Users - System admin changes own password - Blank fields', () => {
@@ -193,7 +193,7 @@ describe('System Console > User Management > Users', () => {
// * Verify the appropriate error is returned.
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').
and('contain', 'Must be 5-72 characters long.');
and('contain', 'Your password must be 5-72 characters long.');
});
it('MM-T937 Users - System admin changes own password - Successfully changed', () => {

Просмотреть файл

@@ -5,7 +5,7 @@ import * as TIMEOUTS from '../fixtures/timeouts';
Cypress.Commands.add('checkLoginPage', (settings = {}) => {
// # Remove autofocus from login input
cy.get('.login-body-card-content').should('be.visible').focus();
cy.get('.login-body-card-title').click();
// * Check elements in the body
cy.get('#input_loginId', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').and(($loginTextbox) => {

Просмотреть файл

@@ -37,7 +37,7 @@ export default class LoginPage {
this.loginPlaceholder = page.locator(`[placeholder="Email or Username"]`);
this.loginWithAdLdapPlaceholder = page.locator(`[placeholder="Email, Username or AD/LDAP Username"]`);
this.passwordInput = page.locator('#input_password-input');
this.passwordToggleButton = page.getByRole('button', {name: 'Show or hide password'});
this.passwordToggleButton = page.locator('#password_toggle');
this.signInButton = page.locator('button:has-text("Log in")');
this.createAccountLink = page.locator("text=Don't have an account?");
this.forgotPasswordLink = page.locator('text=Forgot your password?');

Просмотреть файл

@@ -40,7 +40,7 @@ export default class SignupPage {
this.emailInput = page.locator('#input_email');
this.usernameInput = page.locator('#input_name');
this.passwordInput = page.locator('#input_password-input');
this.passwordToggleButton = page.getByRole('button', {name: 'Show or hide password'});
this.passwordToggleButton = page.locator('#password_toggle');
this.createAccountButton = page.locator('button:has-text("Create Account")');
this.emailError = page.locator('text=Please enter a valid email address');
this.usernameError = page.locator(

Просмотреть файл

@@ -67,10 +67,6 @@ test('/login accessibility tab support', async ({pw}) => {
// * Should move focus to login body after shift+tab
await pw.loginPage.loginInput.press('Shift+Tab');
expect(await pw.loginPage.bodyCard).toBeFocused();
// * Should move focus to create account link after shift+tab
await pw.loginPage.bodyCard.press('Shift+Tab');
expect(await pw.loginPage.createAccountLink).toBeFocused();
// * Should move focus to login body after tab

Просмотреть файл

@@ -79,14 +79,6 @@ test('/signup_user_complete accessibility tab support', async ({pw}, testInfo) =
await pw.signupPage.emailInput.focus();
expect(await pw.signupPage.emailInput).toBeFocused();
// * Should move focus to sign up body after shift+tab
await pw.signupPage.emailInput.press('Shift+Tab');
expect(await pw.signupPage.bodyCard).toBeFocused();
// * Should move focus to sign up body after shift+tab
await pw.signupPage.emailInput.press('Shift+Tab');
expect(await pw.signupPage.bodyCard).toBeFocused();
if (testInfo.project.name === 'ipad') {
// * Should move focus to header back button after shift+tab
await pw.signupPage.bodyCard.press('Shift+Tab');

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 186 KiB

После

Ширина:  |  Высота:  |  Размер: 185 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 488 KiB

После

Ширина:  |  Высота:  |  Размер: 489 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 124 KiB

После

Ширина:  |  Высота:  |  Размер: 138 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 211 KiB

После

Ширина:  |  Высота:  |  Размер: 208 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 219 KiB

После

Ширина:  |  Высота:  |  Размер: 210 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 507 KiB

После

Ширина:  |  Высота:  |  Размер: 508 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 176 KiB

После

Ширина:  |  Высота:  |  Размер: 169 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 507 KiB

После

Ширина:  |  Высота:  |  Размер: 507 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 168 KiB

После

Ширина:  |  Высота:  |  Размер: 166 KiB