fix(accessibility): tab support at login, reset and signup pages, buttons at ATE and app bar (#24214)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
45a14e23a9
Коммит
ecf7cdbdea
@@ -45,10 +45,12 @@ describe('Signup Email page', () => {
|
||||
|
||||
it('should match elements, back button', () => {
|
||||
// * Check elements in the header with back button
|
||||
cy.get('#back_button').should('be.visible');
|
||||
cy.get('#back_button').should('contain', 'Back');
|
||||
cy.get('#back_button_icon').should('be.visible');
|
||||
cy.get('#back_button_icon').should('have.attr', 'title', 'Back Icon');
|
||||
cy.findByTestId('back_button').
|
||||
should('be.visible').
|
||||
and('have.text', 'Back');
|
||||
cy.get('#back_button_icon').
|
||||
should('be.visible').
|
||||
and('have.attr', 'title', 'Back Icon');
|
||||
});
|
||||
|
||||
it('should match elements, body', () => {
|
||||
@@ -94,20 +96,20 @@ describe('Signup Email page', () => {
|
||||
// * Check elements in the footer
|
||||
cy.get('.hfroute-footer').scrollIntoView().should('be.visible').within(() => {
|
||||
// * Check if about footer link is present
|
||||
cy.findByText('About').should('exist').
|
||||
and('have.attr', 'href', config.SupportSettings.AboutLink || ABOUT_LINK);
|
||||
cy.findByText('About').should('be.visible').
|
||||
should('have.attr', 'href').and('match', new RegExp(`${config.SupportSettings.AboutLink || ABOUT_LINK}/*`));
|
||||
|
||||
// * Check if privacy footer link is present
|
||||
cy.findByText('Privacy Policy').should('exist').
|
||||
and('have.attr', 'href', config.SupportSettings.PrivacyPolicyLink || PRIVACY_POLICY_LINK);
|
||||
cy.findByText('Privacy Policy').should('be.visible').
|
||||
should('have.attr', 'href').and('match', new RegExp(`${config.SupportSettings.PrivacyPolicyLink || PRIVACY_POLICY_LINK}/*`));
|
||||
|
||||
// * Check if terms footer link is present
|
||||
cy.findByText('Terms').should('exist').
|
||||
and('have.attr', 'href', config.SupportSettings.TermsOfServiceLink || TERMS_OF_SERVICE_LINK);
|
||||
cy.findByText('Terms').should('be.visible').
|
||||
should('have.attr', 'href').and('match', new RegExp(`${config.SupportSettings.TermsOfServiceLink || TERMS_OF_SERVICE_LINK}/*`));
|
||||
|
||||
// * Check if help footer link is present
|
||||
cy.findByText('Help').should('exist').
|
||||
and('have.attr', 'href', config.SupportSettings.HelpLink || HELP_LINK);
|
||||
cy.findByText('Help').should('be.visible').
|
||||
should('have.attr', 'href').and('match', new RegExp(`${config.SupportSettings.HelpLink || HELP_LINK}/*`));
|
||||
|
||||
const todaysDate = new Date();
|
||||
const currentYear = todaysDate.getFullYear();
|
||||
|
||||
@@ -18,6 +18,11 @@ type ExtendedFixtures = {
|
||||
pages: typeof pages;
|
||||
};
|
||||
|
||||
type AxeBuilderOptions = {
|
||||
disableColorContrast?: boolean;
|
||||
disableLinkInTextBlock?: boolean;
|
||||
};
|
||||
|
||||
export const test = base.extend<ExtendedFixtures>({
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
axe: async ({}, use) => {
|
||||
@@ -94,15 +99,29 @@ class PlaywrightExtended {
|
||||
}
|
||||
|
||||
class AxeBuilderExtended {
|
||||
readonly builder: (page: Page, disableRules?: string[]) => AxeBuilder;
|
||||
readonly builder: (page: Page, options?: AxeBuilderOptions) => AxeBuilder;
|
||||
|
||||
// See https://github.com/dequelabs/axe-core/blob/master/doc/API.md#axe-core-tags
|
||||
readonly tags: string[] = ['wcag2a', 'wcag2aa'];
|
||||
|
||||
constructor() {
|
||||
// See https://github.com/dequelabs/axe-core/blob/master/doc/rule-descriptions.md#wcag-20-level-a--aa-rules
|
||||
this.builder = (page: Page, disableRules?: string[]) => {
|
||||
return new AxeBuilder({page}).withTags(this.tags).disableRules(disableRules || []);
|
||||
this.builder = (page: Page, options: AxeBuilderOptions = {}) => {
|
||||
// See https://github.com/dequelabs/axe-core/blob/master/doc/rule-descriptions.md#wcag-20-level-a--aa-rules
|
||||
const disabledRules: string[] = [];
|
||||
|
||||
if (options.disableColorContrast) {
|
||||
// Disabled in pages due to impact to overall theme of Mattermost.
|
||||
// Option: make use of custom theme to improve color contrast.
|
||||
disabledRules.push('color-contrast');
|
||||
}
|
||||
|
||||
if (options.disableLinkInTextBlock) {
|
||||
// Disabled in pages due to impact to overall theme of Mattermost.
|
||||
// Option: make use of custom theme to improve color contrast.
|
||||
disabledRules.push('link-in-text-block');
|
||||
}
|
||||
|
||||
return new AxeBuilder({page}).withTags(this.tags).disableRules(disabledRules);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
30
e2e-tests/playwright/support/ui/components/footer.ts
Обычный файл
30
e2e-tests/playwright/support/ui/components/footer.ts
Обычный файл
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class Footer {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly copyright;
|
||||
readonly aboutLink;
|
||||
readonly privacyPolicyLink;
|
||||
readonly termsLink;
|
||||
readonly helpLink;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.copyright = container.locator('.footer-copyright');
|
||||
this.aboutLink = container.locator('text=About');
|
||||
this.privacyPolicyLink = container.locator('text=Privacy Policy');
|
||||
this.termsLink = container.locator('text=Terms');
|
||||
this.helpLink = container.locator('text=Help');
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.copyright).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {Footer};
|
||||
@@ -10,7 +10,9 @@ import {ChannelsPost} from './channels/post';
|
||||
import {ChannelsSidebarLeft} from './channels/sidebar_left';
|
||||
import {ChannelsSidebarRight} from './channels/sidebar_right';
|
||||
import {FindChannelsModal} from './channels/find_channels_modal';
|
||||
import {Footer} from './footer';
|
||||
import {GlobalHeader} from './global_header';
|
||||
import {MainHeader} from './main_header';
|
||||
import {PostDotMenu} from './channels/post_dot_menu';
|
||||
import {DeletePostModal} from './channels/delete_post_modal';
|
||||
import {PostMenu} from './channels/post_menu';
|
||||
@@ -26,7 +28,9 @@ const components = {
|
||||
ChannelsSidebarLeft,
|
||||
ChannelsSidebarRight,
|
||||
FindChannelsModal,
|
||||
Footer,
|
||||
GlobalHeader,
|
||||
MainHeader,
|
||||
PostDotMenu,
|
||||
DeletePostModal,
|
||||
PostMenu,
|
||||
|
||||
24
e2e-tests/playwright/support/ui/components/main_header.ts
Обычный файл
24
e2e-tests/playwright/support/ui/components/main_header.ts
Обычный файл
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class MainHeader {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly logo;
|
||||
readonly backButton;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.logo = container.locator('.header-logo-link');
|
||||
this.backButton = container.getByTestId('back_button');
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.container).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {MainHeader};
|
||||
@@ -6,6 +6,7 @@ import {BoardsViewPage} from './boards_view';
|
||||
import {ChannelsPage} from './channels';
|
||||
import {LandingLoginPage} from './landing_login';
|
||||
import {LoginPage} from './login';
|
||||
import {ResetPasswordPage} from './reset_password';
|
||||
import {SignupPage} from './signup';
|
||||
|
||||
const pages = {
|
||||
@@ -14,6 +15,7 @@ const pages = {
|
||||
ChannelsPage,
|
||||
LandingLoginPage,
|
||||
LoginPage,
|
||||
ResetPasswordPage,
|
||||
SignupPage,
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import {expect, Page} from '@playwright/test';
|
||||
import {AdminConfig} from '@mattermost/types/config';
|
||||
import {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {components} from '@e2e-support/ui/components';
|
||||
|
||||
export default class LoginPage {
|
||||
readonly adminConfig: AdminConfig;
|
||||
|
||||
@@ -17,6 +19,7 @@ export default class LoginPage {
|
||||
readonly loginInput;
|
||||
readonly loginPlaceholder;
|
||||
readonly passwordInput;
|
||||
readonly passwordToggleButton;
|
||||
readonly signInButton;
|
||||
readonly createAccountLink;
|
||||
readonly forgotPasswordLink;
|
||||
@@ -24,6 +27,9 @@ export default class LoginPage {
|
||||
readonly fieldWithError;
|
||||
readonly formContainer;
|
||||
|
||||
readonly header;
|
||||
readonly footer;
|
||||
|
||||
constructor(page: Page, adminConfig: AdminConfig) {
|
||||
this.page = page;
|
||||
this.adminConfig = adminConfig;
|
||||
@@ -34,16 +40,20 @@ export default class LoginPage {
|
||||
|
||||
this.title = page.locator('h1:has-text("Log in to your account")');
|
||||
this.subtitle = page.locator('text=Collaborate with your team in real-time');
|
||||
this.bodyCard = page.locator('.login-body-card');
|
||||
this.bodyCard = page.locator('.login-body-card-content');
|
||||
this.loginInput = page.locator('#input_loginId');
|
||||
this.loginPlaceholder = page.locator(`[placeholder="${loginInputPlaceholder}"]`);
|
||||
this.passwordInput = page.locator('#input_password-input');
|
||||
this.passwordToggleButton = page.getByRole('button', {name: 'Show or hide password'});
|
||||
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?');
|
||||
this.userErrorLabel = page.locator('text=Please enter your email or username');
|
||||
this.fieldWithError = page.locator('.with-error');
|
||||
this.formContainer = page.locator('.signup-team__container');
|
||||
|
||||
this.header = new components.MainHeader(page.locator('.hfroute-header'));
|
||||
this.footer = new components.Footer(page.locator('.hfroute-footer'));
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
|
||||
51
e2e-tests/playwright/support/ui/pages/reset_password.ts
Обычный файл
51
e2e-tests/playwright/support/ui/pages/reset_password.ts
Обычный файл
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
import {components} from '@e2e-support/ui/components';
|
||||
|
||||
export default class ResetPasswordPage {
|
||||
readonly page: Page;
|
||||
|
||||
readonly title;
|
||||
readonly subtitle;
|
||||
readonly emailInput;
|
||||
readonly resetButton;
|
||||
readonly formContainer;
|
||||
|
||||
readonly header;
|
||||
readonly footer;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
|
||||
this.title = page.locator('h1:has-text("Password Reset")');
|
||||
this.subtitle = page.locator('text=To reset your password, enter the email address you used to sign up');
|
||||
this.emailInput = page.locator(`[placeholder="Email"]`);
|
||||
this.resetButton = page.locator('#passwordResetButton');
|
||||
this.formContainer = page.locator('.signup-team__container');
|
||||
|
||||
this.header = new components.MainHeader(page.locator('.signup-header'));
|
||||
this.footer = new components.Footer(page.locator('#footer_section'));
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
await expect(this.title).toBeVisible();
|
||||
await expect(this.subtitle).toBeVisible();
|
||||
await expect(this.emailInput).toBeVisible();
|
||||
await expect(this.resetButton).toBeVisible();
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/reset_password');
|
||||
}
|
||||
|
||||
async reset(email: string) {
|
||||
await this.emailInput.fill(email);
|
||||
await Promise.all([this.page.waitForNavigation(), this.resetButton.click()]);
|
||||
}
|
||||
}
|
||||
|
||||
export {ResetPasswordPage};
|
||||
@@ -4,6 +4,7 @@
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
import {duration, wait} from '@e2e-support/util';
|
||||
import {components} from '@e2e-support/ui/components';
|
||||
|
||||
export default class SignupPage {
|
||||
readonly page: Page;
|
||||
@@ -14,28 +15,50 @@ export default class SignupPage {
|
||||
readonly emailInput;
|
||||
readonly usernameInput;
|
||||
readonly passwordInput;
|
||||
readonly passwordToggleButton;
|
||||
readonly newsLetterCheckBox;
|
||||
readonly newsLetterPrivacyPolicyLink;
|
||||
readonly newsLetterUnsubscribeLink;
|
||||
readonly agreementTermsOfUseLink;
|
||||
readonly agreementPrivacyPolicyLink;
|
||||
readonly createAccountButton;
|
||||
readonly loginLink;
|
||||
readonly emailError;
|
||||
readonly usernameError;
|
||||
readonly passwordError;
|
||||
|
||||
readonly header;
|
||||
readonly footer;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
|
||||
this.title = page.locator('h1:has-text("Let’s get started")');
|
||||
this.subtitle = page.locator('text=Create your Mattermost account to start collaborating with your team');
|
||||
this.bodyCard = page.locator('.signup-body-card');
|
||||
this.bodyCard = page.locator('.signup-body-card-content');
|
||||
this.loginLink = page.locator('text=Log in');
|
||||
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.createAccountButton = page.locator('button:has-text("Create Account")');
|
||||
this.loginLink = page.locator('text=Click here to sign in.');
|
||||
this.emailError = page.locator('text=Please enter a valid email address');
|
||||
this.usernameError = page.locator(
|
||||
'text=Usernames have to begin with a lowercase letter and be 3-22 characters long. You can use lowercase letters, numbers, periods, dashes, and underscores.'
|
||||
);
|
||||
this.passwordError = page.locator('text=Must be 5-64 characters long.');
|
||||
|
||||
const newsletterBlock = page.locator('.check-input');
|
||||
this.newsLetterCheckBox = newsletterBlock.getByRole('checkbox', {name: 'newsletter checkbox'});
|
||||
this.newsLetterPrivacyPolicyLink = newsletterBlock.locator('text=Privacy Policy');
|
||||
this.newsLetterUnsubscribeLink = newsletterBlock.locator('text=unsubscribe');
|
||||
|
||||
const agreementBlock = page.locator('.signup-body-card-agreement');
|
||||
this.agreementTermsOfUseLink = agreementBlock.locator('text=Terms of Use');
|
||||
this.agreementPrivacyPolicyLink = agreementBlock.locator('text=Privacy Policy');
|
||||
|
||||
this.header = new components.MainHeader(page.locator('.hfroute-header'));
|
||||
this.footer = new components.Footer(page.locator('.hfroute-footer'));
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
@@ -49,7 +72,7 @@ export default class SignupPage {
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/signup_email');
|
||||
await this.page.goto('/signup_user_complete');
|
||||
}
|
||||
|
||||
async create(user: {email: string; username: string; password: string}, waitForRedirect = true) {
|
||||
|
||||
@@ -19,7 +19,7 @@ test('Intro to channel', async ({pw, pages, axe}) => {
|
||||
|
||||
// # Analyze the page
|
||||
// Disable 'color-contrast' to be addressed by MM-53814
|
||||
const accessibilityScanResults = await axe.builder(page, ['color-contrast']).analyze();
|
||||
const accessibilityScanResults = await axe.builder(page, {disableColorContrast: true}).analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import {expect, test} from '@e2e-support/test_fixture';
|
||||
|
||||
test('/login', async ({pw, pages, page, axe}) => {
|
||||
test('/login accessibility quick check', async ({pw, pages, page, axe}) => {
|
||||
// # Go to login page
|
||||
const {adminClient} = await pw.getAdminClient();
|
||||
const adminConfig = await adminClient.getConfig();
|
||||
@@ -17,3 +17,63 @@ test('/login', async ({pw, pages, page, axe}) => {
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('/login accessibility tab support', async ({pw, pages, page}) => {
|
||||
// # Go to login page
|
||||
const {adminClient} = await pw.getAdminClient();
|
||||
const adminConfig = await adminClient.getConfig();
|
||||
const loginPage = new pages.LoginPage(page, adminConfig);
|
||||
await loginPage.goto();
|
||||
await loginPage.toBeVisible();
|
||||
|
||||
// * Should have focused at login input on page load
|
||||
expect(await loginPage.loginInput).toBeFocused();
|
||||
|
||||
// * Should move focus to password input after tab
|
||||
await loginPage.loginInput.press('Tab');
|
||||
expect(await loginPage.passwordInput).toBeFocused();
|
||||
|
||||
// * Should move focus to password toggle button after tab
|
||||
await loginPage.passwordInput.press('Tab');
|
||||
expect(await loginPage.passwordToggleButton).toBeFocused();
|
||||
|
||||
// * Should move focus to forgot password link after tab
|
||||
await loginPage.passwordToggleButton.press('Tab');
|
||||
expect(await loginPage.forgotPasswordLink).toBeFocused();
|
||||
|
||||
// * Should move focus to forgot password link after tab
|
||||
await loginPage.forgotPasswordLink.press('Tab');
|
||||
expect(await loginPage.signInButton).toBeFocused();
|
||||
|
||||
// * Should move focus to about link after tab
|
||||
await loginPage.signInButton.press('Tab');
|
||||
expect(await loginPage.footer.aboutLink).toBeFocused();
|
||||
|
||||
// * Should move focus to privacy policy link after tab
|
||||
await loginPage.footer.aboutLink.press('Tab');
|
||||
expect(await loginPage.footer.privacyPolicyLink).toBeFocused();
|
||||
|
||||
// * Should move focus to terms link after tab
|
||||
await loginPage.footer.privacyPolicyLink.press('Tab');
|
||||
expect(await loginPage.footer.termsLink).toBeFocused();
|
||||
|
||||
// * Should move focus to help link after tab
|
||||
await loginPage.footer.termsLink.press('Tab');
|
||||
expect(await loginPage.footer.helpLink).toBeFocused();
|
||||
|
||||
// * Should move focus to header logo after tab
|
||||
await loginPage.footer.helpLink.press('Tab');
|
||||
expect(await loginPage.header.logo).toBeFocused();
|
||||
|
||||
// * Should move focus to create account link after tab
|
||||
await loginPage.header.logo.press('Tab');
|
||||
expect(await loginPage.createAccountLink).toBeFocused();
|
||||
|
||||
// * Should move focus to create account link after tab
|
||||
await loginPage.createAccountLink.press('Tab');
|
||||
expect(await loginPage.bodyCard).toBeFocused();
|
||||
|
||||
// * Then, should move focus to login body after tab
|
||||
await loginPage.bodyCard.press('Tab');
|
||||
expect(await loginPage.loginInput).toBeFocused();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, test} from '@e2e-support/test_fixture';
|
||||
|
||||
test('/reset_password accessibility quick check', async ({pages, page, axe}) => {
|
||||
// # Go to reset password page
|
||||
const resetPasswordPage = new pages.ResetPasswordPage(page);
|
||||
await resetPasswordPage.goto();
|
||||
await resetPasswordPage.toBeVisible();
|
||||
|
||||
// # Analyze the page
|
||||
const accessibilityScanResults = await axe.builder(resetPasswordPage.page, {disableColorContrast: true}).analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('/reset_password accessibility tab support', async ({pages, page}) => {
|
||||
// # Go to reset password page
|
||||
const resetPasswordPage = new pages.ResetPasswordPage(page);
|
||||
await resetPasswordPage.goto();
|
||||
await resetPasswordPage.toBeVisible();
|
||||
|
||||
// * Should have focused at email input on page load
|
||||
expect(await resetPasswordPage.emailInput).toBeFocused();
|
||||
|
||||
// * Should move focus to reset button after tab
|
||||
await resetPasswordPage.emailInput.press('Tab');
|
||||
expect(await resetPasswordPage.resetButton).toBeFocused();
|
||||
|
||||
// * Should move focus to about link after tab
|
||||
await resetPasswordPage.resetButton.press('Tab');
|
||||
expect(await resetPasswordPage.footer.aboutLink).toBeFocused();
|
||||
|
||||
// * Should move focus to privacy policy link after tab
|
||||
await resetPasswordPage.footer.aboutLink.press('Tab');
|
||||
expect(await resetPasswordPage.footer.privacyPolicyLink).toBeFocused();
|
||||
|
||||
// * Should move focus to terms link after tab
|
||||
await resetPasswordPage.footer.privacyPolicyLink.press('Tab');
|
||||
expect(await resetPasswordPage.footer.termsLink).toBeFocused();
|
||||
|
||||
// * Should move focus to help link after tab
|
||||
await resetPasswordPage.footer.termsLink.press('Tab');
|
||||
expect(await resetPasswordPage.footer.helpLink).toBeFocused();
|
||||
|
||||
// * Should move focus to header logo after tab
|
||||
await resetPasswordPage.footer.helpLink.press('Tab');
|
||||
expect(await resetPasswordPage.header.backButton).toBeFocused();
|
||||
|
||||
// * Then, should move focus to email input after tab
|
||||
await resetPasswordPage.header.backButton.press('Tab');
|
||||
expect(await resetPasswordPage.emailInput).toBeFocused();
|
||||
});
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, test} from '@e2e-support/test_fixture';
|
||||
|
||||
test('/signup_user_complete accessibility quick check', async ({pages, page, axe}) => {
|
||||
// # Go to reset password page
|
||||
const signupPage = new pages.SignupPage(page);
|
||||
await signupPage.goto();
|
||||
await signupPage.toBeVisible();
|
||||
|
||||
// # Analyze the page
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(signupPage.page, {disableColorContrast: true, disableLinkInTextBlock: true})
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('/signup_user_complete accessibility tab support', async ({pages, page}) => {
|
||||
// # Go to reset password page
|
||||
const signupPage = new pages.SignupPage(page);
|
||||
await signupPage.goto();
|
||||
await signupPage.toBeVisible();
|
||||
|
||||
// * Should have focused at email input on page load
|
||||
expect(await signupPage.emailInput).toBeFocused();
|
||||
|
||||
// * Should move focus to username input after tab
|
||||
await signupPage.emailInput.press('Tab');
|
||||
expect(await signupPage.usernameInput).toBeFocused();
|
||||
|
||||
// * Should move focus to password input after tab
|
||||
await signupPage.usernameInput.press('Tab');
|
||||
expect(await signupPage.passwordInput).toBeFocused();
|
||||
|
||||
// * Should move focus to password toggle button after tab
|
||||
await signupPage.passwordInput.press('Tab');
|
||||
expect(await signupPage.passwordToggleButton).toBeFocused();
|
||||
|
||||
// * Should move focus to newsletter checkbox after tab
|
||||
await signupPage.passwordToggleButton.press('Tab');
|
||||
expect(await signupPage.newsLetterCheckBox).toBeFocused();
|
||||
|
||||
// * Should move focus to newsletter privacy policy link after tab
|
||||
await signupPage.newsLetterCheckBox.press('Tab');
|
||||
expect(await signupPage.newsLetterPrivacyPolicyLink).toBeFocused();
|
||||
|
||||
// * Should move focus to newsletter unsubscribe link after tab
|
||||
await signupPage.newsLetterPrivacyPolicyLink.press('Tab');
|
||||
expect(await signupPage.newsLetterUnsubscribeLink).toBeFocused();
|
||||
|
||||
// * Should move focus to agreement terms of use link after tab
|
||||
await signupPage.newsLetterUnsubscribeLink.press('Tab');
|
||||
expect(await signupPage.agreementTermsOfUseLink).toBeFocused();
|
||||
|
||||
// * Should move focus to agreement privacy policy link after tab
|
||||
await signupPage.agreementTermsOfUseLink.press('Tab');
|
||||
expect(await signupPage.agreementPrivacyPolicyLink).toBeFocused();
|
||||
|
||||
// * Should move focus to privacy policy link after tab
|
||||
await signupPage.footer.aboutLink.press('Tab');
|
||||
expect(await signupPage.footer.privacyPolicyLink).toBeFocused();
|
||||
|
||||
// * Should move focus to terms link after tab
|
||||
await signupPage.footer.privacyPolicyLink.press('Tab');
|
||||
expect(await signupPage.footer.termsLink).toBeFocused();
|
||||
|
||||
// * Should move focus to help link after tab
|
||||
await signupPage.footer.termsLink.press('Tab');
|
||||
expect(await signupPage.footer.helpLink).toBeFocused();
|
||||
|
||||
// * Should move focus to header logo after tab
|
||||
await signupPage.footer.helpLink.press('Tab');
|
||||
expect(await signupPage.header.logo).toBeFocused();
|
||||
|
||||
// * Should move focus to header back button after tab
|
||||
await signupPage.header.logo.press('Tab');
|
||||
expect(await signupPage.header.backButton).toBeFocused();
|
||||
|
||||
// * Should move focus to log in link after tab
|
||||
await signupPage.header.backButton.press('Tab');
|
||||
expect(await signupPage.loginLink).toBeFocused();
|
||||
|
||||
// * Should move focus to sign up body after tab
|
||||
await signupPage.loginLink.press('Tab');
|
||||
expect(await signupPage.bodyCard).toBeFocused();
|
||||
|
||||
// * Then, should move focus to email input after tab
|
||||
await signupPage.bodyCard.press('Tab');
|
||||
expect(await signupPage.emailInput).toBeFocused();
|
||||
});
|
||||
Ссылка в новой задаче
Block a user