Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,301 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility @mfa
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {isMac} from '../../../utils';
|
||||
|
||||
describe('Verify Accessibility Support in different sections in Settings and Profile Dialog', () => {
|
||||
const accountSettings = {
|
||||
profile: [
|
||||
{key: 'name', label: 'Full Name', type: 'text'},
|
||||
{key: 'username', label: 'Username', type: 'text'},
|
||||
{key: 'nickname', label: 'Nickname', type: 'text'},
|
||||
{key: 'position', label: 'Position', type: 'text'},
|
||||
{key: 'email', label: 'Email', type: 'text'},
|
||||
{key: 'picture', label: 'Profile Picture', type: 'image'},
|
||||
],
|
||||
security: [
|
||||
{key: 'password', label: 'Password', type: 'text'},
|
||||
{key: 'mfa', label: 'Multi-factor Authentication', type: 'optional'},
|
||||
],
|
||||
};
|
||||
|
||||
const settings = {
|
||||
notifications: [
|
||||
{key: 'desktop', label: 'Desktop Notifications', type: 'radio'},
|
||||
{key: 'email', label: 'Email Notifications', type: 'radio'},
|
||||
{key: 'push', label: 'Mobile Push Notifications', type: 'radio'},
|
||||
{key: 'keys', label: 'Words That Trigger Mentions', type: 'checkbox'},
|
||||
{key: 'comments', label: 'Reply notifications', type: 'radio'},
|
||||
],
|
||||
display: [
|
||||
{key: 'theme', label: 'Theme', type: 'radio'},
|
||||
{key: 'clock', label: 'Clock Display', type: 'radio'},
|
||||
{key: 'name_format', label: 'Teammate Name Display', type: 'none'},
|
||||
{key: 'availabilityStatus', label: 'Show online availability on profile images', type: 'radio'},
|
||||
{key: 'lastactive', label: 'Share last active time', type: 'radio'},
|
||||
{key: 'timezone', label: 'Timezone', type: 'none'},
|
||||
{key: 'collapse', label: 'Default Appearance of Image Previews', type: 'radio'},
|
||||
{key: 'message_display', label: 'Message Display', type: 'radio'},
|
||||
{key: 'click_to_reply', label: 'Click to open threads', type: 'radio'},
|
||||
{key: 'channel_display_mode', label: 'Channel Display', type: 'radio'},
|
||||
{key: 'one_click_reactions_enabled', label: 'Quick reactions on messages', type: 'radio'},
|
||||
{key: 'languages', label: 'Language', type: 'dropdown'},
|
||||
],
|
||||
sidebar: [
|
||||
{key: 'showUnreadsCategory', label: 'Group unread channels separately', type: 'multiple'},
|
||||
{key: 'limitVisibleGMsDMs', label: 'Number of direct messages to show', type: 'radio'},
|
||||
],
|
||||
advanced: [
|
||||
{key: 'advancedCtrlSend', label: `Send Messages on ${isMac() ? '⌘+ENTER' : 'CTRL+ENTER'}`, type: 'radio'},
|
||||
{key: 'formatting', label: 'Enable Post Formatting', type: 'radio'},
|
||||
{key: 'joinLeave', label: 'Enable Join/Leave Messages', type: 'radio'},
|
||||
|
||||
// As only setting in advancedPreviewFeatures was related to editor preview this isn't required at the moment,
|
||||
// may later on we can add it if we add more settings inside it
|
||||
// {key: 'advancedPreviewFeatures', label: 'Preview Pre-release Features', type: 'checkbox'},
|
||||
],
|
||||
};
|
||||
let url;
|
||||
before(() => {
|
||||
// # Update Configs
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableMultifactorAuthentication: true,
|
||||
},
|
||||
DisplaySettings: {
|
||||
ExperimentalTimezone: true,
|
||||
},
|
||||
SamlSettings: {
|
||||
Enable: false,
|
||||
},
|
||||
});
|
||||
|
||||
// # Login as test user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
url = offTopicUrl;
|
||||
cy.visit(offTopicUrl);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// # Close the modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T1465_1 Verify Label & Tab behavior in section links', () => {
|
||||
// * Verify aria-label and tab support in section of Account settings modal
|
||||
cy.uiOpenProfileModal();
|
||||
cy.findByRole('tab', {name: 'profile settings'}).should('be.visible').focus().should('be.focused');
|
||||
['profile settings', 'security'].forEach((text) => {
|
||||
// * Verify aria-label on each tab and it supports navigating to the next tab with arrow keys
|
||||
cy.focused().should('have.attr', 'aria-label', text).type('{downarrow}');
|
||||
});
|
||||
cy.uiClose();
|
||||
|
||||
// * Verify aria-label and tab support in section of Settings modal
|
||||
cy.uiOpenSettingsModal();
|
||||
cy.findByRole('tab', {name: 'notifications'}).should('be.visible').focus().should('be.focused');
|
||||
['notifications', 'display', 'sidebar', 'advanced'].forEach((text) => {
|
||||
// * Verify aria-label on each tab and it supports navigating to the next tab with arrow keys
|
||||
cy.focused().should('have.attr', 'aria-label', text).type('{downarrow}');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1465_2 Verify Accessibility Support in each section in Settings and Profile Dialog', () => {
|
||||
cy.visit(url);
|
||||
|
||||
// # Open account settings modal
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// * Verify if the focus goes to the individual fields in Profile section
|
||||
cy.findByRole('tab', {name: 'profile settings'}).click().tab();
|
||||
verifySettings(accountSettings.profile);
|
||||
|
||||
// * Verify if the focus goes to the individual fields in Security section
|
||||
cy.findByRole('tab', {name: 'security'}).click().tab();
|
||||
verifySettings(accountSettings.security);
|
||||
cy.uiClose();
|
||||
|
||||
// # Open settings modal
|
||||
cy.uiOpenSettingsModal();
|
||||
|
||||
// * Verify if the focus goes to the individual fields in Notifications section
|
||||
cy.findByRole('tab', {name: 'notifications'}).click().tab();
|
||||
verifySettings(settings.notifications);
|
||||
|
||||
// // * Verify if the focus goes to the individual fields in Display section
|
||||
cy.findByRole('tab', {name: 'display'}).click().tab();
|
||||
verifySettings(settings.display);
|
||||
|
||||
// // * Verify if the focus goes to the individual fields in Sidebar section
|
||||
cy.findByRole('tab', {name: 'sidebar'}).click().tab();
|
||||
verifySettings(settings.sidebar);
|
||||
|
||||
// // * Verify if the focus goes to the individual fields in Advanced section
|
||||
cy.findByRole('tab', {name: 'advanced'}).click().tab();
|
||||
verifySettings(settings.advanced);
|
||||
});
|
||||
|
||||
it('MM-T1481 Verify Correct Radio button behavior in Settings and Profile', () => {
|
||||
cy.visit(url);
|
||||
cy.uiOpenSettingsModal();
|
||||
|
||||
cy.get('#notificationsButton').click();
|
||||
cy.get('#desktopEdit').click();
|
||||
cy.get('#desktopNotificationAllActivity').check().should('be.checked').tab().check();
|
||||
cy.get('#desktopNotificationMentions').should('be.checked').tab().check();
|
||||
cy.get('#desktopNotificationNever').should('be.checked');
|
||||
});
|
||||
|
||||
it('MM-T1482 Input fields in Settings and Profile should read labels', () => {
|
||||
cy.visit(url);
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
accountSettings.profile.forEach((section) => {
|
||||
if (section.type === 'text') {
|
||||
cy.get(`#${section.key}Edit`).click();
|
||||
cy.get('.setting-list-item .form-group').each(($el) => {
|
||||
if ($el.find('input').length) {
|
||||
cy.wrap($el).find('.control-label').invoke('text').then((label) => {
|
||||
cy.wrap($el).find('input').should('have.attr', 'aria-label', label);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1485 Language dropdown should read labels', () => {
|
||||
cy.visit(url);
|
||||
cy.uiOpenSettingsModal();
|
||||
|
||||
cy.get('#displayButton').click();
|
||||
cy.get('#languagesEdit').click();
|
||||
cy.get('#displayLanguage').within(() => {
|
||||
cy.get('input').should('have.attr', 'aria-autocomplete', 'list').and('have.attr', 'aria-labelledby', 'changeInterfaceLanguageLabel').as('inputEl');
|
||||
});
|
||||
cy.get('#changeInterfaceLanguageLabel').should('be.visible').and('have.text', 'Change interface language');
|
||||
|
||||
// # When enter key is pressed on dropdown, it should expand and collapse
|
||||
cy.get('@inputEl').typeWithForce('{enter}');
|
||||
cy.get('#displayLanguage>div').should('have.class', 'react-select__control--menu-is-open');
|
||||
cy.get('@inputEl').typeWithForce('{enter}');
|
||||
cy.get('#displayLanguage>div').should('not.have.class', 'react-select__control--menu-is-open');
|
||||
|
||||
// # Press down arrow twice and check aria label
|
||||
cy.get('@inputEl').typeWithForce('{enter}');
|
||||
cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}');
|
||||
cy.get('#displayLanguage>span').as('ariaEl').within(($el) => {
|
||||
cy.wrap($el).should('have.attr', 'aria-live', 'assertive');
|
||||
cy.get('#aria-context').should('contain', 'option English (Australia) focused').and('contain', 'Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu, press Tab to select the option and exit the menu.');
|
||||
});
|
||||
|
||||
// # Check if language setting gets changed after user presses enter
|
||||
cy.get('@inputEl').typeWithForce('{enter}');
|
||||
cy.get('#displayLanguage').should('contain', 'English (Australia)');
|
||||
cy.get('@ariaEl').get('#aria-selection-event').should('contain', 'option English (Australia), selected');
|
||||
|
||||
// # Press down arrow, then up arrow and press enter
|
||||
cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}{downarrow}{uparrow}');
|
||||
cy.get('@ariaEl').get('#aria-context').should('contain', 'option English (US) focused');
|
||||
cy.get('@inputEl').typeWithForce('{enter}');
|
||||
cy.get('#displayLanguage').should('contain', 'English (US)');
|
||||
cy.get('@ariaEl').get('#aria-selection-event').should('contain', 'option English (US), selected');
|
||||
});
|
||||
|
||||
it('MM-T1488 Profile Picture should read labels', () => {
|
||||
cy.visit(url);
|
||||
|
||||
// # Go to Edit Profile picture
|
||||
cy.uiOpenProfileModal();
|
||||
cy.get('#pictureEdit').click();
|
||||
|
||||
// * Verify image alt in profile image
|
||||
cy.get('.profile-img').should('have.attr', 'alt', 'profile image');
|
||||
|
||||
cy.get('#generalSettings').then((el) => {
|
||||
if (el.find('.profile-img__remove').length > 0) {
|
||||
cy.findByTestId('removeSettingPicture').click();
|
||||
cy.uiSave();
|
||||
cy.get('#pictureEdit').click();
|
||||
}
|
||||
});
|
||||
|
||||
// * Check Labels in different buttons
|
||||
cy.findByTestId('inputSettingPictureButton').should('have.attr', 'aria-label', 'Select');
|
||||
cy.uiSaveButton().should('have.attr', 'disabled');
|
||||
cy.findByTestId('cancelSettingPicture').should('have.attr', 'aria-label', 'Cancel');
|
||||
|
||||
// # Upload a pic and save
|
||||
cy.findByTestId('uploadPicture').attachFile('mattermost-icon.png');
|
||||
cy.uiSave();
|
||||
|
||||
// # Click on Edit Profile Picture
|
||||
cy.get('#pictureEdit').click();
|
||||
|
||||
// * Verify image alt in profile image
|
||||
cy.get('.profile-img').should('have.attr', 'alt', 'profile image');
|
||||
|
||||
// # Option to Remove Profile picture should be present
|
||||
cy.findByTestId('removeSettingPicture').within(() => {
|
||||
cy.get('.sr-only').should('have.text', 'Remove Profile Picture');
|
||||
});
|
||||
|
||||
// # Check tab behavior
|
||||
cy.findByTestId('removeSettingPicture').focus().tab({shift: true}).tab();
|
||||
cy.findByTestId('removeSettingPicture').should('have.class', 'a11y--active a11y--focused').tab();
|
||||
cy.findByTestId('inputSettingPictureButton').should('have.class', 'a11y--active a11y--focused').tab();
|
||||
cy.findByTestId('cancelSettingPicture').should('have.class', 'a11y--active a11y--focused');
|
||||
|
||||
// # Remove the profile picture and check the tab behavior
|
||||
cy.findByTestId('removeSettingPicture').click().wait(TIMEOUTS.HALF_SEC);
|
||||
cy.findByTestId('inputSettingPictureButton').focus().tab({shift: true}).tab();
|
||||
cy.findByTestId('inputSettingPictureButton').should('have.class', 'a11y--active a11y--focused').tab();
|
||||
cy.uiSaveButton().should('be.focused').tab();
|
||||
cy.findByTestId('cancelSettingPicture').should('have.class', 'a11y--active a11y--focused');
|
||||
cy.uiSave();
|
||||
});
|
||||
|
||||
it('MM-T1496 Security Settings screen should read labels', () => {
|
||||
cy.visit(url);
|
||||
|
||||
// # Go to Security Settings
|
||||
cy.uiOpenProfileModal();
|
||||
cy.get('#securityButton').click();
|
||||
|
||||
// * Check Tab behavior in MFA section
|
||||
cy.get('#mfaEdit').click();
|
||||
cy.get('#passwordEdit').focus().tab({shift: true}).tab().tab();
|
||||
cy.get('.setting-list a.btn').should('have.class', 'a11y--active a11y--focused').tab();
|
||||
cy.get('#cancelSetting').should('have.class', 'a11y--active a11y--focused');
|
||||
|
||||
// * Check Tab behavior in Sign-In Method if its available
|
||||
cy.get('.user-settings').then((el) => {
|
||||
if (el.find('#signinEdit').length) {
|
||||
cy.get('#signinEdit').click();
|
||||
cy.get('#mfaEdit').focus().tab({shift: true}).tab().tab();
|
||||
cy.get('.setting-list a.btn').should('have.class', 'a11y--active a11y--focused').tab();
|
||||
cy.get('#cancelSetting').should('have.class', 'a11y--active a11y--focused');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verifySettings(settings) {
|
||||
settings.forEach((setting) => {
|
||||
cy.focused().should('have.id', `${setting.key}Edit`);
|
||||
cy.findByText(setting.label);
|
||||
cy.focused().tab();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility
|
||||
|
||||
describe('Verify Accessibility Support in different Buttons', () => {
|
||||
before(() => {
|
||||
// # Login as test user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Post a message
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1459 Accessibility Support in RHS expand and close icons', () => {
|
||||
cy.clickPostCommentIcon();
|
||||
cy.get('#rhsContainer').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
// * Verify accessibility support in Sidebar Expand and Shrink icon
|
||||
cy.get('button.sidebar--right__expand').
|
||||
should('have.attr', 'aria-label', 'Expand').
|
||||
within(() => {
|
||||
cy.get('.icon-arrow-expand').should('have.attr', 'aria-label', 'Expand Sidebar Icon');
|
||||
cy.get('.icon-arrow-collapse').should('have.attr', 'aria-label', 'Collapse Sidebar Icon');
|
||||
});
|
||||
|
||||
// * Verify accessibility support in Close icon
|
||||
cy.get('#rhsCloseButton').
|
||||
should('have.attr', 'aria-label', 'Close').
|
||||
within(() => {
|
||||
cy.get('.icon-close').should('have.attr', 'aria-label', 'Close Sidebar Icon');
|
||||
});
|
||||
|
||||
// # Close the sidebar
|
||||
cy.get('#rhsCloseButton').click();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1461 Accessibility Support in different buttons in Channel Header', () => {
|
||||
// # Ensure the focus is on the Toggle Favorites button
|
||||
cy.uiGetChannelFavoriteButton().
|
||||
focus().
|
||||
tab({shift: true}).
|
||||
tab();
|
||||
|
||||
// * Verify accessibility support in Favorites button
|
||||
cy.uiGetChannelFavoriteButton().
|
||||
should('be.focused').
|
||||
and('have.attr', 'aria-label', 'add to favorites').
|
||||
click();
|
||||
|
||||
// * Verify accessibility support if Channel is added to Favorites
|
||||
cy.uiGetChannelFavoriteButton().
|
||||
should('have.attr', 'aria-label', 'remove from favorites');
|
||||
|
||||
// # Ensure the focus is on the Toggle Favorites button
|
||||
cy.uiGetChannelFavoriteButton().
|
||||
focus().
|
||||
tab({shift: true}).
|
||||
tab();
|
||||
|
||||
// # Press tab until the focus is on the Pinned posts button
|
||||
cy.focused().tab().tab();
|
||||
|
||||
// * Verify accessibility support in Pinned Posts button
|
||||
cy.uiGetChannelPinButton().
|
||||
should('be.focused').
|
||||
and('have.attr', 'aria-label', 'Pinned posts').
|
||||
tab().tab().tab().tab();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,189 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @accessibility
|
||||
|
||||
describe('Verify Accessibility Support in Dropdown Menus', () => {
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
cy.apiLogin(sysadmin);
|
||||
|
||||
cy.apiInitSetup().then(({offTopicUrl: url}) => {
|
||||
offTopicUrl = url;
|
||||
});
|
||||
|
||||
cy.apiCreateTeam('other-team', 'Other Team');
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// Visit the Off Topic channel
|
||||
cy.visit(offTopicUrl);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
|
||||
it('MM-T1464 Accessibility Support in Channel Menu Dropdown', () => {
|
||||
// # Press tab from the Channel Favorite button
|
||||
cy.uiGetChannelFavoriteButton().
|
||||
focus().
|
||||
tab({shift: true}).
|
||||
tab().
|
||||
tab({shift: true});
|
||||
|
||||
// * Verify the aria-label in channel menu button
|
||||
cy.uiGetChannelHeaderButton().
|
||||
findByLabelText('channel menu').
|
||||
should('be.focused').click();
|
||||
|
||||
// * Verify the accessibility support in the Channel Dropdown menu
|
||||
cy.uiGetChannelMenu().
|
||||
parent().
|
||||
should('have.attr', 'aria-label', 'channel menu').
|
||||
and('have.attr', 'role', 'menu');
|
||||
|
||||
// * Verify the first option is not selected by default
|
||||
cy.uiGetChannelMenu().children().eq(0).should('not.be.focused');
|
||||
|
||||
// # Press tab
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify the accessibility support in the Channel Dropdown menu items
|
||||
const menuItems = [
|
||||
'View Info',
|
||||
'Move to...',
|
||||
'Notification Preferences',
|
||||
'Mute Channel',
|
||||
'Add Members',
|
||||
'Manage Members',
|
||||
'Edit Channel Header',
|
||||
'Edit Channel Purpose',
|
||||
'Rename Channel',
|
||||
'Convert to Private Channel',
|
||||
'Archive Channel',
|
||||
'Leave Channel',
|
||||
];
|
||||
|
||||
menuItems.forEach((item) => {
|
||||
// * Verify that the menu item is focused
|
||||
cy.uiGetChannelMenu().findByText(item).parent().should('be.focused');
|
||||
|
||||
// # Press tab for next item
|
||||
cy.focused().tab();
|
||||
});
|
||||
|
||||
// * Verify if menu is closed when we press Escape
|
||||
cy.get('body').typeWithForce('{esc}');
|
||||
cy.uiGetChannelMenu({exist: false});
|
||||
});
|
||||
|
||||
it('MM-T1476 Accessibility Support in Team Menu Dropdown', () => {
|
||||
// # Open team menu
|
||||
cy.uiGetLHSHeader().click();
|
||||
|
||||
// * Verify the accessibility support in the Main Menu Dropdown
|
||||
cy.findByRole('menu').
|
||||
should('exist').
|
||||
and('have.attr', 'aria-label', 'team menu').
|
||||
and('have.class', 'a11y__popup');
|
||||
|
||||
// * Verify the first option is not selected by default
|
||||
cy.uiGetLHSTeamMenu().find('.MenuItem').
|
||||
children().eq(0).
|
||||
should('not.be.focused').
|
||||
focus();
|
||||
|
||||
// * Verify the accessibility support in the Main Menu Dropdown items
|
||||
const menuItems = [
|
||||
{id: 'invitePeople', label: 'Invite People dialog'},
|
||||
{id: 'teamSettings', label: 'Team Settings dialog'},
|
||||
{id: 'manageMembers', label: 'Manage Members dialog'},
|
||||
{id: 'joinTeam', text: 'Join Another Team'},
|
||||
{id: 'leaveTeam', label: 'Leave Team dialog'},
|
||||
{id: 'createTeam', text: 'Create a Team'},
|
||||
];
|
||||
|
||||
menuItems.forEach((item) => {
|
||||
// * Verify that the menu item is focused
|
||||
if (item.label) {
|
||||
cy.focused().should('have.attr', 'aria-label', item.label);
|
||||
} else {
|
||||
cy.focused().should('have.text', item.text);
|
||||
}
|
||||
|
||||
// # Press tab for next item
|
||||
cy.focused().tab();
|
||||
});
|
||||
|
||||
cy.uiGetLHSTeamMenu().find('.MenuItem').each((el) => {
|
||||
cy.wrap(el).should('have.attr', 'role', 'menuitem');
|
||||
});
|
||||
|
||||
// * Verify if menu is closed when we press Escape
|
||||
cy.get('body').typeWithForce('{esc}');
|
||||
cy.uiGetLHSTeamMenu().should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1477 Accessibility Support in Status Dropdown - KNOWN ISSUE: MM-45716', () => {
|
||||
// # Focus to set status button
|
||||
cy.uiGetSetStatusButton().focus().tab({shift: true}).tab();
|
||||
|
||||
// * Verify the aria-label in status menu button
|
||||
cy.uiGetSetStatusButton().
|
||||
should('be.focused').
|
||||
click();
|
||||
|
||||
// * Verify the accessibility support in the Status Dropdown
|
||||
cy.uiGetStatusMenuContainer().
|
||||
should('have.attr', 'aria-label', 'set status').
|
||||
and('have.class', 'a11y__popup').
|
||||
and('have.attr', 'role', 'menu');
|
||||
|
||||
// * Verify the first option is not selected by default
|
||||
cy.uiGetStatusMenuContainer().find('.dropdown-menu').children().eq(0).should('not.be.focused');
|
||||
|
||||
// # Press tab
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify first focus is on menu header which is the profile image
|
||||
cy.uiGetStatusMenuContainer().within(() => {
|
||||
cy.findByAltText('user profile image').should('be.focused');
|
||||
});
|
||||
|
||||
// # Press tab
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify the accessibility support in the Status Dropdown menu items
|
||||
const menuItems = [
|
||||
{id: 'status-menu-custom-status', label: 'Set a Custom Status dialog'},
|
||||
{id: 'status-menu-online', label: 'online'},
|
||||
{id: 'status-menu-away', label: 'away'},
|
||||
{id: 'status-menu-dnd_menuitem', label: 'do not disturb. disables all notifications'},
|
||||
{id: 'status-menu-offline', label: 'offline'},
|
||||
{id: 'accountSettings', label: 'Profile dialog'},
|
||||
{id: 'logout', label: 'Log Out'},
|
||||
];
|
||||
|
||||
menuItems.forEach((item) => {
|
||||
// * Verify that the menu item is focused
|
||||
cy.uiGetStatusMenuContainer().find(`#${item.id}`).
|
||||
should('be.visible').
|
||||
findAllByLabelText(item.label).first().
|
||||
should('be.focused');
|
||||
|
||||
// # Press tab for next item
|
||||
cy.focused().tab();
|
||||
});
|
||||
|
||||
// * Verify if menu is closed when we press Escape
|
||||
cy.get('body').typeWithForce('{esc}');
|
||||
cy.uiGetStatusMenuContainer({exist: false});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility
|
||||
|
||||
// * Verify the accessibility support in the different images
|
||||
|
||||
describe('Verify Accessibility Support in Different Images', () => {
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({offTopicUrl, user}) => {
|
||||
otherUser = user;
|
||||
|
||||
// Visit the Off Topic channel
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1508 Accessibility support in different images', () => {
|
||||
// * Verify image alt in profile image
|
||||
cy.uiGetProfileHeader().
|
||||
find('.Avatar').
|
||||
should('have.attr', 'alt', 'user profile image');
|
||||
|
||||
// # Upload an image in the post
|
||||
cy.get('#fileUploadInput').attachFile('small-image.png');
|
||||
cy.postMessage('Image upload');
|
||||
|
||||
// * Verify accessibility in images uploaded in a post
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#${postId}_message`).within(() => {
|
||||
cy.get('img').should('be.visible').should('have.attr', 'aria-label', 'file thumbnail small-image.png');
|
||||
});
|
||||
});
|
||||
|
||||
// # Post a message as a different user
|
||||
cy.getCurrentChannelId().then((channelId) => {
|
||||
const message = `hello from ${otherUser.username}: ${Date.now()}`;
|
||||
cy.postMessageAs({sender: otherUser, message, channelId});
|
||||
});
|
||||
|
||||
// # Open profile popover
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).within(() => {
|
||||
cy.get('.user-popover').click();
|
||||
});
|
||||
|
||||
// * Verify image alt in profile popover
|
||||
cy.get('#user-profile-popover').within(() => {
|
||||
cy.get('.Avatar').should('have.attr', 'alt', `${otherUser.username} profile image`);
|
||||
});
|
||||
});
|
||||
|
||||
// # Open Settings > Display > Themes
|
||||
cy.uiOpenSettingsModal('Display').within(() => {
|
||||
cy.get('#displayButton').click();
|
||||
cy.get('#displaySettingsTitle').should('exist');
|
||||
cy.get('#themeTitle').scrollIntoView().should('be.visible');
|
||||
cy.get('#themeEdit').click();
|
||||
|
||||
// * Verify image alt in Theme Images
|
||||
cy.get('#displaySettings').within(() => {
|
||||
cy.get('.appearance-section>div').children().each(($el) => {
|
||||
cy.wrap($el).get('#denim-theme-icon').should('have.text', 'Denim theme icon');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility
|
||||
|
||||
import {getRandomId} from '../../../utils';
|
||||
|
||||
function postMessages(testChannel, otherUser, count) {
|
||||
for (let index = 0; index < count; index++) {
|
||||
// # Post Message as Current user
|
||||
const message = `hello from current user: ${getRandomId()}`;
|
||||
cy.postMessage(message);
|
||||
const otherMessage = `hello from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message: otherMessage, channelId: testChannel.id});
|
||||
}
|
||||
}
|
||||
|
||||
describe('Verify Accessibility keyboard usability across different regions in the app', () => {
|
||||
const count = 5;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let testChannel;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testUser = user;
|
||||
testChannel = channel;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(team.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id).then(() => {
|
||||
// # Login as test user, visit test channel and post few messages
|
||||
cy.apiLogin(user);
|
||||
cy.visit(`/${team.name}/channels/${testChannel.name}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1513_2 Verify Keyboard support in Search Results', () => {
|
||||
// # Post few messages
|
||||
postMessages(testChannel, otherUser, count);
|
||||
|
||||
// # Search for a term
|
||||
cy.get('#searchBox').typeWithForce('hello').typeWithForce('{enter}');
|
||||
|
||||
// # Change the focus to search results
|
||||
cy.get('#searchContainer').within(() => {
|
||||
cy.get('button.sidebar--right__expand').focus().tab({shift: true}).tab();
|
||||
cy.focused().tab().tab().tab().tab();
|
||||
});
|
||||
cy.get('body').type('{downarrow}{uparrow}');
|
||||
|
||||
// # Use down arrow keys and verify if results are highlighted sequentially
|
||||
for (let index = 0; index < count; index++) {
|
||||
cy.get('#search-items-container').children('.search-item__container').eq(index).then(($el) => {
|
||||
// * Verify search result is highlighted
|
||||
cy.get($el).find('.post').should('have.class', 'a11y--active a11y--focused');
|
||||
cy.get('body').type('{downarrow}');
|
||||
});
|
||||
}
|
||||
|
||||
// # Use up arrow keys and verify if results are highlighted sequentially
|
||||
for (let index = count; index > 0; index--) {
|
||||
cy.get('#search-items-container').children('.search-item__container').eq(index).then(($el) => {
|
||||
// * Verify search result is highlighted
|
||||
cy.get($el).find('.post').should('have.class', 'a11y--active a11y--focused');
|
||||
cy.get('body').type('{uparrow}');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('MM-T1513_1 Verify Keyboard support in RHS', () => {
|
||||
// # Post Message as Current user
|
||||
const message = `hello from ${testUser.username}: ${getRandomId()}`;
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Post few replies on RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
for (let index = 0; index < count; index++) {
|
||||
const replyMessage = `A reply ${getRandomId()}`;
|
||||
cy.postMessageReplyInRHS(replyMessage);
|
||||
const messageFromOther = `reply from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message: messageFromOther, channelId: testChannel.id, rootId: postId});
|
||||
}
|
||||
});
|
||||
|
||||
// * Verify that the highlight order is in the reverse direction in RHS
|
||||
cy.get('#rhsContainer .post-right__content').should('have.attr', 'data-a11y-order-reversed', 'true').and('have.attr', 'data-a11y-focus-child', 'true');
|
||||
|
||||
// # Change the focus to the last post
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
cy.uiGetReplyTextBox().focus().tab({shift: true});
|
||||
});
|
||||
cy.get('body').type('{uparrow}{downarrow}');
|
||||
|
||||
// # Use up arrow keys and verify if results are highlighted sequentially
|
||||
const total = (count * 2) + 1; // # total number of expected posts in RHS
|
||||
let row = total - 1; // # the row index which should be focused
|
||||
|
||||
for (let index = count; index > 0; index--) {
|
||||
cy.get('#rhsContainer .post-right-comments-container .post').eq(row).then(($el) => {
|
||||
// * Verify search result is highlighted
|
||||
cy.get($el).should('have.class', 'a11y--active a11y--focused');
|
||||
cy.get('body').type('{uparrow}');
|
||||
});
|
||||
row--;
|
||||
}
|
||||
|
||||
// # Use down arrow keys and verify if posts are highlighted sequentially
|
||||
for (let index = count; index > 0; index--) {
|
||||
cy.get('#rhsContainer .post-right-comments-container .post').eq(row).then(($el) => {
|
||||
// * Verify search result is highlighted
|
||||
cy.get($el).should('have.class', 'a11y--active a11y--focused');
|
||||
cy.get('body').type('{downarrow}');
|
||||
});
|
||||
row++;
|
||||
}
|
||||
});
|
||||
|
||||
it('MM-T1499 Verify Screen reader should not switch to virtual cursor mode', () => {
|
||||
// # Open RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
|
||||
// * Verify Screen reader should not switch to virtual cursor mode. This is handled by adding a role=application attribute
|
||||
const regions = ['#sidebar-left', '#rhsContainer .post-right__content', '.search__form', '#advancedTextEditorCell'];
|
||||
regions.forEach((region) => {
|
||||
cy.get(region).should('have.attr', 'role', 'application');
|
||||
});
|
||||
cy.get(`#post_${postId}`).children('.post__content').eq(0).should('have.attr', 'role', 'application');
|
||||
cy.get(`#rhsPost_${postId}`).children('.post__content').eq(0).should('have.attr', 'role', 'application');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility
|
||||
|
||||
import {getRandomId} from '../../../utils';
|
||||
|
||||
function postMessages(testChannel, otherUser, count) {
|
||||
for (let index = 0; index < count; index++) {
|
||||
// # Post Message as Current user
|
||||
const message = `hello from current user: ${getRandomId()}`;
|
||||
cy.postMessage(message);
|
||||
const otherMessage = `hello from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message: otherMessage, channelId: testChannel.id});
|
||||
}
|
||||
}
|
||||
|
||||
function verifyNavSupport(element, label, tabOrder) {
|
||||
cy.get(element).
|
||||
should('have.attr', 'aria-label', label).
|
||||
and('have.attr', 'data-a11y-sort-order', tabOrder).
|
||||
and('have.class', 'a11y__region a11y--active');
|
||||
}
|
||||
|
||||
describe('Verify Quick Navigation support across different regions in the app', () => {
|
||||
let otherUser;
|
||||
let testChannel;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testChannel = channel;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(team.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id).then(() => {
|
||||
// # Login as test user, visit test channel and post few messages
|
||||
cy.apiLogin(user);
|
||||
cy.visit(`/${team.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post few messages
|
||||
postMessages(testChannel, otherUser, 5);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1460_1 Verify Navigation Support in Post List & Post Input', () => {
|
||||
// # Shift focus to the last post
|
||||
cy.uiGetPostTextBox().focus().tab({shift: true}).tab({shift: true});
|
||||
cy.get('body').type('{uparrow}{downarrow}');
|
||||
|
||||
// * Verify post region reads out correctly
|
||||
verifyNavSupport('#virtualizedPostListContent > div', 'message list main region', '1');
|
||||
|
||||
// # Shift focus to the post input
|
||||
cy.uiGetPostTextBox().focus().tab().tab({shift: true});
|
||||
|
||||
// * Verify post input region reads out correctly
|
||||
verifyNavSupport('#advancedTextEditorCell', 'Login Successful message input complimentary region', '2');
|
||||
});
|
||||
|
||||
it('MM-T1460_3 Verify Navigation Support in RHS Post List & RHS Post Input', () => {
|
||||
// # Open RHS and reply
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
const replyMessage = 'A reply to an older post';
|
||||
cy.postMessageReplyInRHS(replyMessage);
|
||||
});
|
||||
|
||||
// * Verify post message in RHS
|
||||
cy.uiGetRHS().within(() => {
|
||||
// # Shift the focus to the last post
|
||||
cy.uiGetReplyTextBox().focus().tab({shift: true}).type('{uparrow}');
|
||||
|
||||
// * Verify post region on RHS reads out correctly
|
||||
verifyNavSupport('.post-right__content', 'message details complimentary region', '3');
|
||||
|
||||
// # Shift the focus to the RHS input
|
||||
cy.uiGetReplyTextBox().focus().tab().tab({shift: true});
|
||||
|
||||
// * Verify post input on RHS reads out correctly
|
||||
cy.get('#advancedTextEditorCell').
|
||||
should('have.attr', 'aria-label', 'Login Successful message input complimentary region').
|
||||
and('have.attr', 'data-a11y-sort-order', '2').
|
||||
and('have.class', 'a11y__region');
|
||||
cy.uiGetReplyTextBox().
|
||||
should('have.class', 'a11y--active a11y--focused');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1460_5 Verify Navigation Support in LHS Sidebar', () => {
|
||||
// # Change the focus to Main Menu button
|
||||
cy.uiGetLHSAddChannelButton().focus().tab({shift: true}).tab();
|
||||
|
||||
// # Change the focus to the LHS sidebar
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify nav support in LHS channel navigator
|
||||
verifyNavSupport('#lhsNavigator', 'channel navigator region', '6');
|
||||
|
||||
// # Change the focus to the LHS sidebar
|
||||
cy.focused().tab().tab().tab().tab();
|
||||
|
||||
// * Verify nav support in LHS sidebar
|
||||
verifyNavSupport('#sidebar-left', 'channel sidebar region', '7');
|
||||
});
|
||||
|
||||
it('MM-T1460_6 Verify Navigation Support in Channel Header', () => {
|
||||
// # Change the focus to Main Menu button
|
||||
cy.get('#toggleFavorite').focus().tab({shift: true}).tab();
|
||||
|
||||
// * Verify nav support in LHS sidebar header
|
||||
verifyNavSupport('#channel-header', 'channel header region', '8');
|
||||
});
|
||||
|
||||
it('MM-T1460_8 Verify Navigation Support in Search Results', () => {
|
||||
// # Search for some text
|
||||
cy.get('#searchBox').should('be.visible').type('hello {enter}');
|
||||
|
||||
// # Change the focus to search results
|
||||
cy.get('#searchContainer').within(() => {
|
||||
cy.get('button.sidebar--right__expand').focus().tab({shift: true}).tab();
|
||||
cy.focused().tab().tab().tab().tab();
|
||||
});
|
||||
cy.get('body').type('{downarrow}{uparrow}');
|
||||
|
||||
// * Verify nav support in Search Results Container
|
||||
verifyNavSupport('#search-items-container', 'Search Results complimentary region', '3');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility
|
||||
|
||||
let previousEmoji = 'grinning';
|
||||
|
||||
function verifyArrowKeysEmojiNavigation(arrowKey, count) {
|
||||
for (let index = 0; index < count; index++) {
|
||||
cy.get('body').type(arrowKey);
|
||||
// eslint-disable-next-line no-loop-func
|
||||
cy.get('.emoji-picker__preview-name').invoke('text').then((selectedEmoji) => {
|
||||
expect(selectedEmoji).not.equal(previousEmoji);
|
||||
previousEmoji = selectedEmoji;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
describe('Verify Accessibility Support in Popovers', () => {
|
||||
before(() => {
|
||||
// # Login as test user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Post a message
|
||||
cy.postMessage(`hello from test user: ${Date.now()}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1489 Accessibility Support in Emoji Popover on click of Emoji Reaction button', () => {
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Open the Emoji Popover
|
||||
cy.clickPostReactionIcon(postId);
|
||||
|
||||
// * Verify accessibility support in Emoji Search input
|
||||
cy.get('#emojiPickerSearch').should('have.attr', 'aria-label', 'Search for an emoji');
|
||||
|
||||
// # Focus on the first emoji Category
|
||||
cy.get('#emojiPickerCategories').children().eq(0).focus().tab({shift: true}).tab();
|
||||
|
||||
const categories = [
|
||||
{ariaLabel: 'emoji_picker.smileys-emotion', header: 'Smileys & Emotion'},
|
||||
{ariaLabel: 'emoji_picker.people-body', header: 'People & Body'},
|
||||
{ariaLabel: 'emoji_picker.animals-nature', header: 'Animals & Nature'},
|
||||
{ariaLabel: 'emoji_picker.food-drink', header: 'Food & Drink'},
|
||||
{ariaLabel: 'emoji_picker.travel-places', header: 'Travel Places'},
|
||||
{ariaLabel: 'emoji_picker.activities', header: 'Activities'},
|
||||
{ariaLabel: 'emoji_picker.objects', header: 'Objects'},
|
||||
{ariaLabel: 'emoji_picker.symbols', header: 'Symbols'},
|
||||
{ariaLabel: 'emoji_picker.flags', header: 'Flags'},
|
||||
];
|
||||
|
||||
// * Verify if emoji Categories gets the focus when tab is pressed
|
||||
cy.get('#emojiPickerCategories').children('.emoji-picker__category').each(($el, index) => {
|
||||
// * Verify each category
|
||||
if (index < categories.length) {
|
||||
// * Verify accessibility support in emoji category
|
||||
cy.get($el).should('have.class', 'a11y--active a11y--focused').should('have.attr', 'aria-label', categories[index].ariaLabel);
|
||||
|
||||
// * Verify if corresponding section is displayed when emoji category has focus and clicked
|
||||
cy.get($el).trigger('click').tab();
|
||||
|
||||
// * Verify if corresponding section is displayed
|
||||
cy.findByText(categories[index].header).should('be.visible');
|
||||
|
||||
// * Verify emoji navigation using arrow keys
|
||||
verifyArrowKeysEmojiNavigation('{rightarrow}', 3);
|
||||
verifyArrowKeysEmojiNavigation('{leftarrow}', 2);
|
||||
|
||||
// # Press tab
|
||||
cy.get($el).focus().tab();
|
||||
}
|
||||
});
|
||||
|
||||
// # Close the Emoji Popover
|
||||
cy.get('body').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,363 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {getRandomId} from '../../../utils';
|
||||
|
||||
describe('Verify Accessibility Support in Post', () => {
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let emojiPickerEnabled;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
emojiPickerEnabled = config.ServiceSettings.EnableEmojiPicker;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as test user and visit the test channel
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
cy.get('#postListContent', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1479 Verify Reader reads out the post correctly on Center Channel', () => {
|
||||
const {lastMessage} = postMessages(testChannel, otherUser, 1);
|
||||
performActionsToLastPost();
|
||||
|
||||
// # Shift focus to the last post
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true});
|
||||
cy.get('body').type('{uparrow}{downarrow}');
|
||||
|
||||
// * Verify post message in Center Channel
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Verify reader reads out the post correctly
|
||||
verifyPostLabel(`#post_${postId}`, otherUser.username, `wrote, ${lastMessage}, 2 reactions, message is saved and pinned`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1480 Verify Reader reads out the post correctly on RHS', () => {
|
||||
const {lastMessage} = postMessages(testChannel, otherUser, 1);
|
||||
performActionsToLastPost();
|
||||
|
||||
// # Post a reply on RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
const replyMessage = 'A reply to an older post';
|
||||
cy.postMessageReplyInRHS(replyMessage);
|
||||
|
||||
// * Verify post message in RHS
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
// # Shift the focus to the last post
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).type('{uparrow}');
|
||||
|
||||
// * Verify reader reads out the post correctly
|
||||
verifyPostLabel(`#rhsPost_${postId}`, otherUser.username, `wrote, ${lastMessage}, 2 reactions, message is saved and pinned`);
|
||||
});
|
||||
|
||||
// * Verify reply message in RHS
|
||||
cy.getLastPostId().then((replyId) => {
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
// # Shift the focus to the last reply message
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).type('{uparrow}{downarrow}');
|
||||
|
||||
// * Verify reader reads out the post correctly
|
||||
verifyPostLabel(`#rhsPost_${replyId}`, testUser.username, `replied, ${replyMessage}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1486_1 Verify different Post Focus on Center Channel', () => {
|
||||
postMessages(testChannel, otherUser, 5);
|
||||
|
||||
// # Shift focus to the last post
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).type('{uparrow}');
|
||||
|
||||
// * Verify if focus changes to different posts when we use up arrows
|
||||
for (let index = 1; index < 5; index++) {
|
||||
cy.getNthPostId(-index - 1).then((postId) => {
|
||||
cy.get(`#post_${postId}`).should('be.focused');
|
||||
cy.get('body').type('{uparrow}');
|
||||
});
|
||||
}
|
||||
|
||||
// * Verify if focus changes to different posts when we use down arrows
|
||||
for (let index = 5; index > 0; index--) {
|
||||
cy.getNthPostId(-index - 1).then((postId) => {
|
||||
cy.get(`#post_${postId}`).should('be.focused');
|
||||
cy.get('body').type('{downarrow}');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('MM-T1486_2 Verify different Post Focus on RHS', () => {
|
||||
// # Post Message as Current user
|
||||
const message = `hello from current user: ${getRandomId()}`;
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Post few replies on RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
for (let index = 0; index < 3; index++) {
|
||||
const replyMessage = `A reply ${getRandomId()}`;
|
||||
cy.postMessageReplyInRHS(replyMessage);
|
||||
const otherMessage = `reply from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message: otherMessage, channelId: testChannel.id, rootId: postId});
|
||||
}
|
||||
});
|
||||
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
// # Shift focus to the last post
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).type('{uparrow}');
|
||||
});
|
||||
|
||||
// * Verify if focus changes to different posts when we use up arrows
|
||||
for (let index = 1; index < 5; index++) {
|
||||
cy.getNthPostId(-index - 1).then((postId) => {
|
||||
cy.get(`#rhsPost_${postId}`).should('be.focused');
|
||||
cy.get('body').type('{uparrow}');
|
||||
});
|
||||
}
|
||||
|
||||
// * Verify if focus changes to different posts when we use down arrows
|
||||
for (let index = 5; index > 1; index--) {
|
||||
cy.getNthPostId(-index - 1).then((postId) => {
|
||||
cy.get(`#rhsPost_${postId}`).should('be.focused');
|
||||
cy.get('body').type('{downarrow}');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('MM-T1486_3 Verify Tab support on Post on Center Channel', () => {
|
||||
postMessages(testChannel, otherUser, 1);
|
||||
|
||||
// # Shift focus to the last post
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).type('{uparrow}{downarrow}');
|
||||
cy.focused().tab();
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).within(() => {
|
||||
// * Verify focus is on profile image
|
||||
cy.get('.status-wrapper button').first().should('be.focused');
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify focus is on the username
|
||||
cy.get('button.user-popover').should('be.focused').and('have.attr', 'aria-label', otherUser.username);
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify focus is on the time
|
||||
cy.get(`#CENTER_time_${postId}`).should('be.focused');
|
||||
cy.focused().tab();
|
||||
|
||||
// eslint-disable-next-line no-negated-condition
|
||||
if (!emojiPickerEnabled) {
|
||||
// * Verify focus is on the actions button
|
||||
cy.get(`#CENTER_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'more');
|
||||
cy.focused().tab();
|
||||
} else {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
// * Verify focus is on the reactions button
|
||||
cy.get(`#recent_reaction_${i}`).should('have.class', 'emoticon--post-menu').and('have.attr', 'aria-label');
|
||||
cy.focused().tab();
|
||||
}
|
||||
}
|
||||
|
||||
// * Verify focus is on the reactions button
|
||||
cy.get(`#CENTER_reaction_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'add reaction');
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify focus is on the save post button
|
||||
cy.get(`#CENTER_flagIcon_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'save');
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify focus is on the comment button
|
||||
cy.get(`#CENTER_commentIcon_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'reply');
|
||||
cy.focused().tab();
|
||||
|
||||
if (emojiPickerEnabled) {
|
||||
// * Verify focus is on the more button
|
||||
cy.get(`#CENTER_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'More');
|
||||
cy.focused().tab();
|
||||
}
|
||||
|
||||
// * Verify focus is on the post text
|
||||
cy.get(`#postMessageText_${postId}`).should('be.focused').and('have.attr', 'aria-readonly', 'true');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1486_4 Verify Tab support on Post on RHS', () => {
|
||||
// # Post Message as Current user
|
||||
const message = `hello from current user: ${getRandomId()}`;
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Post few replies on RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
const replyMessage = `A reply ${getRandomId()}`;
|
||||
cy.postMessageReplyInRHS(replyMessage);
|
||||
const otherMessage = `reply from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message: otherMessage, channelId: testChannel.id, rootId: postId});
|
||||
});
|
||||
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
// # Shift focus to the last post
|
||||
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true});
|
||||
});
|
||||
|
||||
// * Verify reverse tab on RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#rhsPost_${postId}`).within(() => {
|
||||
// * Verify focus is on the post text
|
||||
cy.get(`#rhsPostMessageText_${postId}`).should('be.focused').and('have.attr', 'aria-readonly', 'true');
|
||||
cy.focused().tab({shift: true});
|
||||
|
||||
if (emojiPickerEnabled) {
|
||||
// * Verify focus is on the actions button
|
||||
cy.get(`#RHS_COMMENT_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'More');
|
||||
cy.focused().tab({shift: true});
|
||||
}
|
||||
|
||||
// * Verify focus is on the save icon
|
||||
cy.get(`#RHS_COMMENT_flagIcon_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'save');
|
||||
cy.focused().tab({shift: true});
|
||||
|
||||
// * Verify focus is on the reactions button
|
||||
cy.get(`#RHS_COMMENT_reaction_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'add reaction');
|
||||
cy.focused().tab({shift: true});
|
||||
|
||||
// eslint-disable-next-line no-negated-condition
|
||||
if (!emojiPickerEnabled) {
|
||||
// * Verify focus is on the actions button
|
||||
cy.get(`#RHS_COMMENT_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'more');
|
||||
cy.focused().tab({shift: true});
|
||||
} else {
|
||||
cy.get('#recent_reaction_0').should('have.class', 'emoticon--post-menu').and('have.attr', 'aria-label');
|
||||
cy.focused().tab({shift: true});
|
||||
}
|
||||
|
||||
// * Verify focus is on the time
|
||||
cy.get(`#RHS_COMMENT_time_${postId}`).should('be.focused');
|
||||
cy.focused().tab({shift: true});
|
||||
|
||||
// * Verify focus is on the username
|
||||
cy.get('button.user-popover').should('be.focused').and('have.attr', 'aria-label', otherUser.username);
|
||||
cy.focused().tab({shift: true});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1462 Verify incoming messages are read', () => {
|
||||
// # Make channel as read by switching back and forth to testChannel
|
||||
cy.uiGetLhsSection('CHANNELS').findByText('Off-Topic').click();
|
||||
cy.get('#postListContent', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
cy.uiGetLhsSection('CHANNELS').findByText(testChannel.display_name).click();
|
||||
cy.get('#postListContent', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
// # Submit a post as another user
|
||||
const message = `verify incoming message from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message, channelId: testChannel.id});
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
|
||||
// # Get the element which stores the incoming messages
|
||||
cy.get('#postListContent').within(() => {
|
||||
cy.get('.sr-only').should('have.attr', 'aria-live', 'polite').as('incomingMessage');
|
||||
});
|
||||
|
||||
// * Verify incoming message is read
|
||||
cy.get('@incomingMessage').invoke('text').then((text) => {
|
||||
expect(text).contain(message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function postMessages(testChannel, otherUser, count) {
|
||||
let lastMessage;
|
||||
|
||||
for (let index = 0; index < count; index++) {
|
||||
// # Post Message as Current user
|
||||
const message = `hello from current user: ${getRandomId()}`;
|
||||
cy.postMessage(message);
|
||||
lastMessage = `hello from ${otherUser.username}: ${getRandomId()}`;
|
||||
cy.postMessageAs({sender: otherUser, message: lastMessage, channelId: testChannel.id});
|
||||
}
|
||||
|
||||
return {lastMessage};
|
||||
}
|
||||
|
||||
function performActionsToLastPost() {
|
||||
// # Take some actions on the last post
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Add grinning reaction
|
||||
cy.clickPostReactionIcon(postId);
|
||||
cy.findAllByTestId('grinning').first().trigger('mouseover', {force: true});
|
||||
cy.get('.sprite-preview').should('be.visible');
|
||||
cy.get('.emoji-picker__preview').should('be.visible').and('have.text', ':grinning:');
|
||||
cy.findAllByTestId('grinning').first().click({force: true});
|
||||
cy.get(`#postReaction-${postId}-grinning`).should('be.visible');
|
||||
|
||||
// # Add smile reaction
|
||||
cy.clickPostReactionIcon(postId);
|
||||
cy.findAllByTestId('smile').first().trigger('mouseover', {force: true});
|
||||
cy.get('.sprite-preview').should('be.visible');
|
||||
cy.get('.emoji-picker__preview').should('be.visible').and('have.text', ':smile:');
|
||||
cy.findAllByTestId('smile').first().click({force: true});
|
||||
cy.get(`#postReaction-${postId}-smile`).should('be.visible');
|
||||
|
||||
// # Save the post
|
||||
cy.clickPostSaveIcon(postId);
|
||||
|
||||
// # Pin the post
|
||||
cy.clickPostDotMenu(postId);
|
||||
cy.get(`#pin_post_${postId}`).click();
|
||||
|
||||
cy.clickPostDotMenu(postId);
|
||||
cy.get('body').type('{esc}');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyPostLabel(elementId, username, labelSuffix) {
|
||||
// # Shift focus to the last post
|
||||
cy.get(elementId).as('lastPost').should('be.focused');
|
||||
|
||||
// * Verify reader reads out the post correctly
|
||||
cy.get('@lastPost').then((el) => {
|
||||
// # Get the post time
|
||||
cy.wrap(el).find('time.post__time').invoke('text').then((time) => {
|
||||
const expectedLabel = `At ${time} ${Cypress.dayjs().format('dddd, MMMM D')}, ${username} ${labelSuffix}`;
|
||||
cy.wrap(el).should('have.attr', 'aria-label', expectedLabel);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @accessibility @smoke
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Verify Accessibility Support in Channel Sidebar Navigation', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
let otherUser;
|
||||
let otherChannel;
|
||||
|
||||
cy.apiInitSetup({promoteNewUserAsAdmin: true}).then(({team, channel, user, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
offTopicUrl = url;
|
||||
|
||||
cy.apiCreateUser().then(({user: regularUser}) => {
|
||||
cy.apiAddUserToTeam(testTeam.id, regularUser.id);
|
||||
});
|
||||
|
||||
return cy.apiCreateChannel(testTeam.id, 'test', 'Test');
|
||||
}).then(({channel}) => {
|
||||
otherChannel = channel;
|
||||
return cy.apiAddUserToChannel(otherChannel.id, testUser.id);
|
||||
}).then(() => {
|
||||
return cy.apiCreateUser({prefix: 'other'});
|
||||
}).then(({user}) => {
|
||||
otherUser = user;
|
||||
return cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
}).then(() => {
|
||||
return cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
}).then(() => {
|
||||
return cy.apiAddUserToChannel(otherChannel.id, otherUser.id);
|
||||
}).then(() => {
|
||||
// # Post messages to have unread messages to test user
|
||||
for (let index = 0; index < 5; index++) {
|
||||
cy.postMessageAs({sender: otherUser, message: 'This is an old message', channelId: otherChannel.id});
|
||||
}
|
||||
|
||||
// # Login as test user and visit the off-topic channel
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1472 Verify Tab Support in Direct Messages section', () => {
|
||||
const usersPrefixes = ['a', 'c', 'd'];
|
||||
usersPrefixes.forEach((prefix) => {
|
||||
//# Create users with prefixes in alphabetical order
|
||||
cy.apiCreateUser({prefix}).then(({user: newUser}) => {
|
||||
cy.apiCreateDirectChannel([testUser.id, newUser.id]).then(({channel}) => {
|
||||
// # Post message in The DM channel
|
||||
cy.postMessageAs({sender: newUser, message: 'test', channelId: channel.id});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// # Trigger DM with a user
|
||||
cy.uiAddDirectMessage().click();
|
||||
searchAndSelectUser('user');
|
||||
searchAndSelectUser('user');
|
||||
cy.uiGetButton('Go').click();
|
||||
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
|
||||
// # Press tab to the Create DM button and verify if the Plus button has focus
|
||||
cy.uiAddDirectMessage().
|
||||
tab({shift: true}).tab().
|
||||
should('be.focused').
|
||||
tab({shift: true}).tab({shift: true});
|
||||
|
||||
cy.focused().parent().parent().next().find('.SidebarChannel').each((el, i) => {
|
||||
if (i === 0) {
|
||||
cy.focused().findByText('DIRECT MESSAGES');
|
||||
cy.focused().tab().tab().tab();
|
||||
}
|
||||
|
||||
// * Verify if focus changes to different channels in Direct Messages section
|
||||
cy.wrap(el).find('.SidebarLink').should('be.focused');
|
||||
cy.focused().tab().tab().tab();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function searchAndSelectUser(text) {
|
||||
cy.findByRole('textbox', {name: 'Search for people'}).
|
||||
typeWithForce(text).
|
||||
wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('.more-modal__row.clickable').
|
||||
first().
|
||||
click();
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @accessibility @smoke
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Verify Accessibility Support in Channel Sidebar Navigation', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
let otherUser;
|
||||
let otherChannel;
|
||||
|
||||
cy.apiInitSetup({promoteNewUserAsAdmin: true}).then(({team, channel, user, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
offTopicUrl = url;
|
||||
return cy.apiCreateChannel(testTeam.id, 'test', 'Test');
|
||||
}).then(({channel}) => {
|
||||
otherChannel = channel;
|
||||
return cy.apiAddUserToChannel(otherChannel.id, testUser.id);
|
||||
}).then(() => {
|
||||
return cy.apiCreateUser({prefix: 'other'});
|
||||
}).then(({user}) => {
|
||||
otherUser = user;
|
||||
return cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
}).then(() => {
|
||||
return cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
}).then(() => {
|
||||
return cy.apiAddUserToChannel(otherChannel.id, otherUser.id);
|
||||
}).then(() => {
|
||||
// # Post messages to have unread messages to test user
|
||||
for (let index = 0; index < 5; index++) {
|
||||
cy.postMessageAs({sender: otherUser, message: 'This is an old message', channelId: otherChannel.id});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as test user and visit the off-topic channel
|
||||
cy.apiLogin(testUser);
|
||||
(cy as any).apiSaveSidebarSettingPreference();
|
||||
cy.visit(offTopicUrl);
|
||||
cy.get('#postListContent').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1470 Verify Tab Support in Channels section', () => {
|
||||
// # Create some Public Channels
|
||||
Cypress._.times(2, () => {
|
||||
cy.apiCreateChannel(testTeam.id, 'public', 'public');
|
||||
});
|
||||
|
||||
// # Wait for few seconds
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Press tab to the Add Public Channel button
|
||||
cy.uiGetLHSAddChannelButton().focus().tab().tab({shift: true});
|
||||
|
||||
// * Verify if the Plus button has focus
|
||||
cy.findByRole('button', {name: 'Add Channel Dropdown'}).should('be.focused');
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify if the Plus button has focus
|
||||
cy.findByRole('button', {name: 'Find Channels'}).should('be.focused');
|
||||
cy.focused().tab();
|
||||
|
||||
// * Verify if Insights has focus
|
||||
cy.focused().should('have.text', 'Insights').tab();
|
||||
|
||||
// * Verify if focus changes to different channels in Unread section
|
||||
cy.get('.SidebarChannel.unread').each((el) => {
|
||||
cy.wrap(el).find('.unread-title').should('be.focused');
|
||||
cy.focused().tab().tab();
|
||||
});
|
||||
|
||||
cy.focused().parent().next().find('.SidebarChannel').each((el, i) => {
|
||||
if (i === 0) {
|
||||
cy.focused().findByText('CHANNELS');
|
||||
cy.focused().tab().tab().tab();
|
||||
}
|
||||
|
||||
// * Verify if focus changes to different channels in Channels section
|
||||
cy.wrap(el).find('.SidebarLink').should('be.focused');
|
||||
cy.focused().tab().tab();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1473 Verify Tab Support in Unreads section', () => {
|
||||
// # Press tab from the Main Menu button
|
||||
cy.uiGetLHSAddChannelButton().focus().tab().tab().tab();
|
||||
|
||||
// * Verify if focus changes to different channels in Unread section
|
||||
cy.get('.SidebarChannel.unread').each((el) => {
|
||||
cy.wrap(el).find('.unread-title').should('be.focused');
|
||||
cy.focused().tab().tab();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1474 Verify Tab Support in Favorites section', () => {
|
||||
// # Mark few channels as Favorites
|
||||
markAsFavorite('off-topic');
|
||||
markAsFavorite(testChannel.name);
|
||||
|
||||
// # Press tab from the add channel button down to all unread channels
|
||||
cy.uiGetLHSAddChannelButton().focus().tab().tab().tab();
|
||||
cy.get('.SidebarChannel.unread').each(() => {
|
||||
cy.focused().tab().tab();
|
||||
});
|
||||
|
||||
// * Verify if focus changes to different channels in Favorite Channels section
|
||||
cy.focused().tab().tab().parent().next().find('.SidebarChannel').each((el, i) => {
|
||||
if (i === 0) {
|
||||
cy.focused().findByText('FAVORITES');
|
||||
cy.focused().tab().tab().tab();
|
||||
}
|
||||
|
||||
cy.wrap(el).find('.SidebarLink').should('be.focused');
|
||||
cy.focused().tab().tab();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1475 Verify Up & Down Arrow support in Channel Sidebar', () => {
|
||||
cy.apiCreateChannel(testTeam.id, 'public', 'Public', 'O');
|
||||
cy.apiCreateChannel(testTeam.id, 'private', 'Private', 'P');
|
||||
|
||||
// # Mark few channels as Favorites
|
||||
markAsFavorite('off-topic');
|
||||
markAsFavorite(testChannel.name);
|
||||
|
||||
// # Press tab from the Main Menu button
|
||||
cy.uiGetLHSAddChannelButton().focus().tab().tab().tab();
|
||||
|
||||
// # Press Down Arrow and then Up Arrow
|
||||
cy.get('body').type('{downarrow}{uparrow}');
|
||||
|
||||
// * Verify if Unread Channels section has focus
|
||||
cy.uiGetLhsSection('UNREADS').should('be.focused');
|
||||
|
||||
// # Press Down Arrow and check the focus
|
||||
cy.get('body').type('{downarrow}');
|
||||
|
||||
// * Verify if Favorite Channels section has focus
|
||||
cy.uiGetLhsSection('FAVORITES').should('be.focused');
|
||||
|
||||
// # Press Down Arrow and check the focus
|
||||
cy.get('body').type('{downarrow}');
|
||||
|
||||
// * Verify if Public Channels section has focus
|
||||
cy.uiGetLhsSection('CHANNELS').should('be.focused');
|
||||
|
||||
// # Press Down Arrow and check the focus
|
||||
cy.get('body').type('{downarrow}');
|
||||
|
||||
// * Verify if Direct Messages section has focus
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').should('be.focused');
|
||||
});
|
||||
});
|
||||
|
||||
function markAsFavorite(channelName) {
|
||||
// # Visit the channel
|
||||
cy.get(`#sidebarItem_${channelName}`).click();
|
||||
cy.get('#postListContent').should('be.visible');
|
||||
|
||||
// # Remove from Favorites if already set
|
||||
cy.get('#channelHeaderInfo').then((el) => {
|
||||
if (el.find('#toggleFavorite.active').length) {
|
||||
cy.get('#toggleFavorite').click();
|
||||
}
|
||||
});
|
||||
|
||||
// # mark it as Favorite
|
||||
cy.get('#toggleFavorite').click();
|
||||
}
|
||||
Ссылка в новой задаче
Block a user