Этот коммит содержится в:
Mario Vitale
2023-03-27 16:28:42 +02:00
родитель da7a6825ce
Коммит ba6b97fb62
1142 изменённых файлов: 44 добавлений и 44 удалений

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

@@ -0,0 +1,131 @@
// 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 @account_setting
describe('Settings > Display > Channel Display Mode', () => {
before(() => {
// # Login as new user, visit off-topic and post a message
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
cy.postMessage('Test for channel display mode');
});
});
beforeEach(() => {
cy.viewport(1500, 660);
});
it('should render in min setting view', () => {
// # Go to Settings modal - Display section
cy.uiOpenSettingsModal('Display');
// * Check that the Display tab is loaded
cy.get('#displayButton').should('be.visible');
// # Click the Display tab
cy.get('#displayButton').click();
// * Check that it changed into the Display section
cy.get('#displaySettingsTitle').should('contain', 'Display Settings');
// # Scroll up to bring Channel Display setting in viewable area.
cy.get('#channel_display_modeTitle').scrollIntoView();
// * Check the min setting view if each element is present and contains expected text values
cy.get('#channel_display_modeTitle').should('contain', 'Channel Display');
cy.get('#channel_display_modeDesc').should('contain', 'Full width');
cy.get('#channel_display_modeEdit').should('contain', 'Edit');
cy.get('#accountSettingsHeader > .close').should('be.visible');
});
it('should render in max setting view', () => {
// # Click "Edit" to the right of "Channel Display"
cy.get('#channel_display_modeEdit').click();
// # Scroll a bit to show the "Save" button
cy.get('.section-max').scrollIntoView();
// * Check that it changed into the Channel Display section
// * Check the max setting view if each element is present and contains expected text values
cy.get('#channel_display_modeFormatA').should('be.visible');
cy.get('#channel_display_modeFormatB').should('be.visible');
cy.get('#saveSetting').should('contain', 'Save');
cy.get('#cancelSetting').should('contain', 'Cancel');
cy.get('#accountSettingsHeader > .close').should('be.visible');
});
it('MM-T296 change channel display mode setting to "Full width"', () => {
// # Click the radio button for "Full width"
cy.get('#channel_display_modeFormatA').click();
// # Click "Save"
cy.uiSave();
// * Check that it changed into min setting view
// * Check if element is present and contains expected text values
cy.get('#channel_display_modeDesc').
should('be.visible').
and('contain', 'Full width');
// # Click "x" button to close Settings modal
cy.uiClose();
// * Validate if the post content in center channel is full width
// by checking the exact class name.
cy.get('#postListContent').should('be.visible');
cy.findAllByTestId('postContent').
first().
should('have.class', 'post__content').
and('not.have.class', 'center');
});
it('MM-T295 Channel display mode setting to "Fixed width, centered"', () => {
// # Go to Settings modal - Display section
cy.uiOpenSettingsModal('Display');
// * Check that the Sidebar tab is loaded
cy.get('#displayButton').should('be.visible');
// # Click the display tab
cy.get('#displayButton').click();
// # Click "Edit" to the right of "Channel Display"
cy.get('#channel_display_modeEdit').click();
// # Scroll a bit to show the "Save" button
cy.get('.section-max').scrollIntoView();
// # Click the radio button for "Fixed width, centered"
cy.get('#channel_display_modeFormatB').click();
// # Click "Save"
cy.uiSave();
// * Check that it changed into min setting view
// * Check if element is present and contains expected text values
cy.get('#channel_display_modeDesc').
should('be.visible').
and('contain', 'Fixed width');
// # Click "x" button to close Settings modal
cy.uiClose();
// # Go to channel which has any posts
cy.get('#sidebarItem_town-square').click({force: true});
// * Validate if the post content in center channel is fixed and centered
// by checking the exact class name.
cy.get('#postListContent').should('be.visible');
cy.findAllByTestId('postContent').
first().
should('have.class', 'post__content center');
});
});

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

@@ -0,0 +1,205 @@
// 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 @account_setting
import moment from 'moment-timezone';
import * as DATE_TIME_FORMAT from '../../../../fixtures/date_time_format';
describe('Settings > Display > Clock Display Mode', () => {
const mainMessage = 'Test for clock display mode';
const replyMessage1 = 'Reply 1 for clock display mode';
const replyMessage2 = 'Reply 2 for clock display mode';
let testTeam;
let testChannel;
before(() => {
// # Enable Timezone
cy.apiUpdateConfig({
DisplaySettings: {
ExperimentalTimezone: true,
},
});
// # Login as new user, visit off-topic and post a message
cy.apiInitSetup({loginAfter: true}).then(({team, channel, offTopicUrl}) => {
testTeam = team;
testChannel = channel;
cy.visit(offTopicUrl);
cy.postMessage(mainMessage);
// # Open RHS and post two consecutive replies
cy.clickPostCommentIcon();
[replyMessage1, replyMessage2].forEach((message) => {
cy.postMessageReplyInRHS(message);
});
});
});
it('MM-T2098 Clock display mode setting to "12-hour clock"', () => {
// # Set clock display to 12-hour
setClockDisplayTo12Hour();
// * Verify clock format is 12-hour for main message
cy.getNthPostId(1).then((postId) => {
verifyClockFormatIs12HourForPostWithMessage(postId, mainMessage, true);
});
// * Verify clock format is 12-hour for reply message 1
cy.getNthPostId(-2).then((postId) => {
verifyClockFormatIs12HourForPostWithMessage(postId, replyMessage1, false);
});
// * Verify clock format is 12-hour for reply message 2
cy.getNthPostId(-1).then((postId) => {
verifyClockFormatIs12HourForPostWithMessage(postId, replyMessage2, false);
});
});
it('MM-T2096_1 Clock Display - Can switch from 12-hr to 24-hr', () => {
// # Set clock display to 24-hour
setClockDisplayTo24Hour();
// * Verify clock format is 24-hour for main message
cy.getNthPostId(1).then((postId) => {
verifyClockFormatIs24HourForPostWithMessage(postId, mainMessage);
});
// * Verify clock format is 24-hour for reply message 1
cy.getNthPostId(-2).then((postId) => {
verifyClockFormatIs24HourForPostWithMessage(postId, replyMessage1);
});
// * Verify clock format is 24-hour for reply message 2
cy.getNthPostId(-1).then((postId) => {
verifyClockFormatIs24HourForPostWithMessage(postId, replyMessage2);
});
});
it('MM-T2096_2 Clock Display - 24-hr - post message after 1pm', () => {
cy.apiAdminLogin().then(({user}) => {
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
// # Set clock display to 24-hour
setClockDisplayTo24Hour();
// # Post a message with time after 1pm
const now = new Date();
const nextYear = now.getFullYear() + 1;
const futureDate = Date.UTC(nextYear, 0, 5, 14, 37); // Jan 5, 2:37pm
cy.postMessageAs({sender: user, message: 'Hello from Jan 5, 2:37pm', channelId: testChannel.id, createAt: futureDate});
// * Message posted shows timestamp in 24-hour format, e.g. 14:37
cy.getLastPost().
find('time').
should('contain', '14:37').
and('have.attr', 'datetime', `${nextYear}-01-05T14:37:00.000`);
});
});
});
function navigateToClockDisplaySettings() {
// # Go to Settings modal - Display section
cy.uiOpenSettingsModal('Display');
// # Click the display tab
cy.get('#displayButton').should('be.visible').click();
// # Click "Edit" to the right of "Clock Display"
cy.get('#clockEdit').
scrollIntoView().
should('be.visible').
click();
// # Scroll a bit to show the "Save" button
cy.get('.section-max').
should('be.visible').
scrollIntoView();
}
function setClockDisplayTo(clockFormat) {
// # Navigate to Clock Display Settings
navigateToClockDisplaySettings();
// # Click the radio button and verify checked
cy.get(`#${clockFormat}`).
should('be.visible').
click({force: true}).
should('be.checked');
// # Click Save button
cy.uiSave();
// * Verify clock description
if (clockFormat === 'clockFormatA') {
cy.get('#clockDesc').should('have.text', '12-hour clock (example: 4:00 PM)');
} else {
cy.get('#clockDesc').should('have.text', '24-hour clock (example: 16:00)');
}
// # Close Settings modal
cy.uiClose();
}
function setClockDisplayTo12Hour() {
setClockDisplayTo('clockFormatA');
}
function setClockDisplayTo24Hour() {
setClockDisplayTo('clockFormatB');
}
function verifyClockFormat(timeFormat, isVisible) {
cy.get('time').first().then(($timeEl) => {
cy.wrap($timeEl).invoke('attr', 'datetime').then((dateTimeString) => {
const formattedTime = moment(dateTimeString).format(timeFormat);
cy.wrap($timeEl).should(isVisible ? 'be.visible' : 'exist').and('have.text', formattedTime);
});
});
}
function verifyClockFormatIs12Hour(isVisible) {
verifyClockFormat(DATE_TIME_FORMAT.TIME_12_HOUR, isVisible);
}
function verifyClockFormatIs24Hour(isVisible) {
verifyClockFormat(DATE_TIME_FORMAT.TIME_24_HOUR, isVisible);
}
function verifyClockFormatIs12HourForPostWithMessage(postId, message, isVisible) {
// * Verify clock format is 12-hour in center channel within the post
cy.get(`#post_${postId}`).within(() => {
cy.get('.post-message__text').should('have.text', message);
verifyClockFormatIs12Hour(isVisible);
});
// * Verify clock format is 12-hour in RHS within the RHS post
cy.get(`#rhsPost_${postId}`).within(() => {
cy.get('.post-message__text').should('have.text', message);
verifyClockFormatIs12Hour(isVisible);
});
}
function verifyClockFormatIs24HourForPostWithMessage(postId, message, isVisible) {
// * Verify clock format is 24-hour in center channel within the post
cy.get(`#post_${postId}`).within(() => {
cy.get('.post-message__text').should('have.text', message);
verifyClockFormatIs24Hour(isVisible);
});
// * Verify clock format is 24-hour in RHS within the RHS post
cy.get(`#rhsPost_${postId}`).within(() => {
cy.get('.post-message__text').should('have.text', message);
verifyClockFormatIs24Hour(isVisible);
});
}

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

@@ -0,0 +1,147 @@
// 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 @account_setting
describe('Settings > Display > Message Display: Colorize username', () => {
let testTeam;
let firstUser;
let otherUser;
let testChannel;
const colors = {};
let defaultTextColor = '';
before(() => {
// # Login as new user and visit off-topic
cy.apiInitSetup().then(({channel, user, team}) => {
testTeam = team;
firstUser = user;
testChannel = channel;
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
otherUser = user1;
// # Add user to team and channel
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
// # Post some messages
cy.postMessageAs({
sender: otherUser,
message: 'Other message',
channelId: testChannel.id,
});
cy.postMessageAs({
sender: firstUser,
message: 'Test message',
channelId: testChannel.id,
});
});
});
},
);
});
beforeEach(() => {
// # Visit related channel
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
});
it('MM-T4984_1 Message Display: colorize usernames option should not exist in Standard mode', () => {
// # Select 'Standard' option
cy.uiChangeMessageDisplaySetting();
// # Set the default text color
cy.findByText(firstUser.username).then((elements) => {
cy.window().then((win) => {
defaultTextColor = win.getComputedStyle(elements[0]).color;
});
});
// # Go to Settings modal - Display section - Message Display
goToMessageDisplaySetting();
// * Verify Colorize usernames option doesn't exist;
cy.findByRole('checkbox', {
name: 'Colorize usernames: Use colors to distinguish users in compact mode',
}).should('not.exist');
// # Save and close the modal
cy.uiSaveAndClose();
});
it('MM-T4984_2 Message Display: colorize usernames option should exist in Compact mode and function as expected', () => {
// # Select 'Compact' option
cy.uiChangeMessageDisplaySetting('COMPACT');
// # Go to Settings modal - Display section - Message Display
goToMessageDisplaySetting();
// * Verify Colorize usernames option exists and checked by default
cy.findByRole('checkbox', {name: 'Colorize usernames: Use colors to distinguish users in compact mode'}).should('exist');
cy.findByRole('checkbox', {name: 'Colorize usernames: Use colors to distinguish users in compact mode'}).should('be.checked');
// # Save and close the modal
cy.uiSaveAndClose();
// # Save the color of the buttons
cy.findByText(firstUser.username).then((elements) => {
colors[firstUser.username] = elements[0].attributes.style.value;
});
cy.findByText(otherUser.username).then((elements) => {
colors[otherUser.username] = elements[0].attributes.style.value;
}).then(() => {
// * Verify that colors are different
expect(colors[firstUser.username]).to.not.equal(colors[otherUser.username]);
});
cy.reload();
// * Verify that after reload colors are the same
cy.findByText(firstUser.username).then((elements) => {
cy.wrap(elements[0]).should('have.attr', 'style', colors[firstUser.username]);
});
cy.findByText(otherUser.username).then((elements) => {
cy.wrap(elements[0]).should('have.attr', 'style', colors[otherUser.username]);
});
});
it('MM-T4984_3 Message Display: disabling colorize should revert colors to normal color', () => {
// # Select 'Compact' option
cy.uiChangeMessageDisplaySetting('COMPACT');
// # Go to Settings modal - Display section - Message Display
goToMessageDisplaySetting();
// # Verify Colorize usernames option exists and make it unchecked
cy.findByRole('checkbox', {name: 'Colorize usernames: Use colors to distinguish users in compact mode'}).should('exist');
cy.findByRole('checkbox', {name: 'Colorize usernames: Use colors to distinguish users in compact mode'}).uncheck().should('not.be.checked');
// # Save and close the modal
cy.uiSaveAndClose();
// * Verify that colors are reverted to normal
cy.findByText(firstUser.username).then((elements) => {
cy.wrap(elements[0]).should('have.css', 'color', defaultTextColor);
});
cy.findByText(otherUser.username).then((elements) => {
cy.wrap(elements[0]).should('have.css', 'color', defaultTextColor);
});
});
});
function goToMessageDisplaySetting() {
// # Go to Settings modal - Display section - Message Display
cy.uiOpenSettingsModal('Display').within(() => {
cy.get('#displayButton').scrollIntoView().click();
cy.get('#message_displayEdit').should('be.visible');
cy.get('#message_displayEdit').click();
});
}

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

@@ -0,0 +1,75 @@
// 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 @account_setting
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Settings > Display > Message Display', () => {
before(() => {
// # Login as new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T103_1 Compact view: Line breaks remain intact after editing', () => {
// * Verify line breaks do not change and blank line is still there in compact view.
verifyLineBreaksRemainIntact('COMPACT');
});
it('MM-T103_2 Standard view: Line breaks remain intact after editing', () => {
// * Verify line breaks do not change and blank line is still there in standard view.
verifyLineBreaksRemainIntact('STANDARD');
});
});
function verifyLineBreaksRemainIntact(display) {
cy.uiChangeMessageDisplaySetting(display);
const firstLine = 'First line';
const secondLine = 'Second line';
// # Enter in text
cy.uiGetPostTextBox().
clear().
type(firstLine).
type('{shift}{enter}{enter}').
type(`${secondLine}{enter}`);
// # Get last postId
cy.getLastPostId().then((postId) => {
const postMessageTextId = `#postMessageText_${postId}`;
// * Verify text still includes new line
cy.get(postMessageTextId).should('have.text', `${firstLine}\n${secondLine}`);
// # click dot menu button
cy.clickPostDotMenu(postId);
// # click edit post
cy.get(`#edit_post_${postId}`).scrollIntoView().should('be.visible').click();
// # Add ",edited" to the text
const editMessage = ',edited';
cy.get('#edit_textbox').type(editMessage);
// # finish editing
cy.get('#edit_textbox').wait(TIMEOUTS.HALF_SEC).type('{enter}');
// * Verify posted message includes newline, edit message and "Edited" indicator
cy.get(postMessageTextId).should('have.text', `${firstLine}\n${secondLine}${editMessage} Edited`);
// * Post should have "Edited"
cy.get(`#postEdited_${postId}`).
should('be.visible').
should('contain', 'Edited');
});
}

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

@@ -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 @account_setting
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
describe('Settings > Display > Theme > Custom Theme Colors', () => {
before(() => {
// # Login as new user, visit off-topic and post a message
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
cy.postMessage('```\ncode\n```');
});
});
[
{name: 'github', backgroundColor: 'rgb(255, 255, 255)', color: 'rgb(36, 41, 46)'},
{name: 'monokai', backgroundColor: 'rgb(39, 40, 34)', color: 'rgb(221, 221, 221)'},
{name: 'solarized-light', backgroundColor: 'rgb(253, 246, 227)', color: 'rgb(88, 110, 117)'},
{name: 'solarized-dark', backgroundColor: 'rgb(0, 43, 54)', color: 'rgb(147, 161, 161)'},
].forEach((theme, index) => {
it(`MM-T293_${index + 1} Theme Colors - Code (${theme.name})`, () => {
// # Navigate to the theme settings
navigateToThemeSettings();
// # Check Custom Themes
cy.get('#customThemes').check().should('be.checked');
// # Open Center Channel Styles section
cy.get('#centerChannelStyles').click({force: true});
// # Select custom code theme
cy.get('#codeThemeSelect').scrollIntoView().should('be.visible').select(theme.name);
// * Verify that the setting changes in the background?
verifyLastPostStyle(theme);
// # Save and close settings modal
cy.get('#saveSetting').click().wait(TIMEOUTS.HALF_SEC);
cy.uiClose();
// * Verify that the styles remain after saving and closing modal
verifyLastPostStyle(theme);
// # Reload the browser
cy.reload();
// * Verify the styles are still intact
verifyLastPostStyle(theme);
});
});
});
function verifyLastPostStyle(codeTheme) {
cy.getLastPostId().then((postId) => {
const postCodeBlock = `#postMessageText_${postId} code`;
// * Verify that the code block background color and color match the desired theme
cy.get(postCodeBlock).
should('have.css', 'background-color', codeTheme.backgroundColor).
and('have.css', 'color', codeTheme.color);
});
}
function navigateToThemeSettings() {
// Change theme to desired theme (keeps settings modal open)
cy.uiOpenSettingsModal('Display');
// Open edit theme
cy.get('#themeTitle').should('be.visible');
cy.get('#themeEdit').click();
cy.get('.section-max').scrollIntoView();
}

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

@@ -0,0 +1,110 @@
// 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 @account_setting
import {hexToRgbArray, rgbArrayToString} from '../../../../../utils';
describe('Settings > Display > Theme', () => {
before(() => {
// # Login as new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
beforeEach(() => {
cy.reload();
cy.postMessage('hello');
// # Go to Settings modal - Display section, then custom theme
cy.uiOpenSettingsModal('Display');
cy.get('#displayButton').
should('be.visible').
click();
cy.get('#themeTitle').
scrollIntoView().
should('be.visible').
click();
cy.get('#customThemes').
should('be.visible').
click();
});
it('MM-T280_1 Theme Colors - Color Picker (Sidebar styles)', () => {
// # Change "Sidebar BG" and verify color change
verifyColorPickerChange(
'Sidebar Styles',
'#sidebarBg-squareColorIcon',
'#sidebarBg-inputColorValue',
'#sidebarBg-squareColorIconValue',
);
});
it('MM-T280_2 Theme Colors - Color Picker (Center Channel styles)', () => {
// # Change "Center Channel BG" and verify color change
verifyColorPickerChange(
'Center Channel Styles',
'#centerChannelBg-squareColorIcon',
'#centerChannelBg-inputColorValue',
'#centerChannelBg-squareColorIconValue',
);
});
it('MM-T280_3 Theme Colors - Color Picker (Link and Button styles)', () => {
// # Change "Link Color" and verify color change
verifyColorPickerChange(
'Link and Button Styles',
'#linkColor-squareColorIcon',
'#linkColor-inputColorValue',
'#linkColor-squareColorIconValue',
);
});
});
function verifyColorPickerChange(stylesText, iconButtonId, inputId, iconValueId) {
// # Open styles section
cy.findByText(stylesText).scrollIntoView().should('be.visible').click({force: true});
// # Click the Sidebar BG setting
cy.get(iconButtonId).click();
// # Click the 15, 40 coordinate of color popover
cy.get('.color-popover').should('be.visible').click(15, 40);
// # Click the Sidebar BG setting again to close popover
cy.get(iconButtonId).click();
// # Toggle theme colors the custom theme
cy.get('#standardThemes').
scrollIntoView().
should('be.visible').
check();
cy.get('#customThemes').
scrollIntoView().
should('be.visible').
check();
// # Re-open styles section
cy.findByText(stylesText).
scrollIntoView().
should('be.visible').
click({force: true});
// * Verify color change is applied correctly
cy.get(inputId).
scrollIntoView().
should('be.visible').
invoke('attr', 'value').
then((hexColor) => {
const rbgArr = hexToRgbArray(hexColor);
cy.get(iconValueId).should('be.visible').and('have.css', 'background-color', rgbArrayToString(rbgArr));
});
}

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

@@ -0,0 +1,110 @@
// 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 @account_setting
import {hexToRgbArray, rgbArrayToString} from '../../../../../utils';
describe('Custom Theme - Sidebar Styles', () => {
const themeRgbColor = {};
before(() => {
// # Login as new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
// # Go to Theme > Custom > Sidebar Styles
cy.uiOpenSettingsModal('Display');
cy.get('#themeTitle').scrollIntoView().click();
cy.uiGetRadioButton('Custom Theme').click();
cy.findByText('Sidebar Styles').scrollIntoView().click({force: true});
});
});
it('MM-T3853_1 Should change custom sidebar styles on click to color picker', () => {
const testCases = [
{key: 0, name: 'Sidebar BG', themeId: 'sidebarBg'},
{key: 1, name: 'Sidebar Text', themeId: 'sidebarText'},
{key: 2, name: 'Sidebar Header BG', themeId: 'sidebarHeaderBg'},
{key: 3, name: 'Team Sidebar BG', themeId: 'sidebarTeamBarBg'},
{key: 4, name: 'Sidebar Header Text', themeId: 'sidebarHeaderTextColor'},
{key: 5, name: 'Sidebar Unread Text', themeId: 'sidebarUnreadText'},
{key: 6, name: 'Sidebar Text Hover BG', themeId: 'sidebarTextHoverBg'},
{key: 7, name: 'Sidebar Text Active Border', themeId: 'sidebarTextActiveBorder'},
{key: 8, name: 'Sidebar Text Active Color', themeId: 'sidebarTextActiveColor'},
{key: 9, name: 'Online Indicator', themeId: 'onlineIndicator'},
{key: 10, name: 'Away Indicator', themeId: 'awayIndicator'},
{key: 11, name: 'Do Not Disturb Indicator', themeId: 'dndIndicator'},
{key: 12, name: 'Mention Jewel BG', themeId: 'mentionBg'},
{key: 13, name: 'Mention Jewel Text', themeId: 'mentionColor'},
];
Cypress._.forEach(testCases, (testCase) => {
// # Click input color button
cy.get('.input-group-addon').eq(testCase.key).scrollIntoView().click({force: true});
// # Click the 15, 40 plus key coordinate of color popover
cy.get('.color-popover').should('be.visible').click(15, 40 + testCase.key);
cy.get(`#${testCase.themeId}-inputColorValue`).scrollIntoView().should('be.visible').invoke('attr', 'value').then((hexColor) => {
themeRgbColor[testCase.themeId] = hexToRgbArray(hexColor);
// * Check that icon color change
cy.get('.color-icon').eq(testCase.key).should('have.css', 'background-color', rgbArrayToString(themeRgbColor[testCase.themeId]));
// * Check that theme colors for text sharing is updated
cy.get('#pasteBox').scrollIntoView().should('contain', `"${testCase.themeId}":"${hexColor.toLowerCase()}"`);
});
});
});
it('MM-T3853_2 Should observe color change in Settings modal before saving', () => {
// * Check Sidebar BG color change
cy.get('.settings-links').should('have.css', 'background-color', rgbArrayToString(themeRgbColor.sidebarBg));
// * Check Sidebar Text color change
const rgbArr = themeRgbColor.sidebarText;
cy.get('#displayButton').should('have.css', 'color', `rgba(${rgbArr[0]}, ${rgbArr[1]}, ${rgbArr[2]}, 0.6)`);
// * Check Sidebar Header BG color change
cy.get('#accountSettingsHeader').should('have.css', 'background', `${rgbArrayToString(themeRgbColor.sidebarHeaderBg)} none repeat scroll 0% 0% / auto padding-box border-box`);
// * Check Sidebar Header Text color change
cy.get('#accountSettingsModalLabel').should('have.css', 'color', rgbArrayToString(themeRgbColor.sidebarHeaderTextColor));
cy.uiSaveAndClose();
});
it('MM-T3853_3 Should take effect each custom color in Channel View', () => {
// * Check Mention Jewel BG color
cy.get('#unreadIndicatorBottom').should('have.css', 'background-color', rgbArrayToString(themeRgbColor.mentionBg));
// * Check Mention Jewel Text color
cy.get('#unreadIndicatorBottom').should('have.css', 'color', rgbArrayToString(themeRgbColor.mentionColor));
// # Set user status to online
cy.uiOpenUserMenu('Online');
// * Check Online Indicator color
cy.get('.icon-check-circle').should('have.css', 'color', rgbArrayToString(themeRgbColor.onlineIndicator));
// # Set user status to away
cy.uiOpenUserMenu('Away');
// * Check Away Indicator color
cy.get('.icon-clock').should('have.css', 'color', rgbArrayToString(themeRgbColor.awayIndicator));
// # Set user status to do not disturb
cy.uiOpenDndStatusSubMenu().find('#dndTime-thirty_minutes_menuitem').click();
// * Check Do Not Disturb Indicator color
cy.get('.icon-minus-circle').should('have.css', 'color', rgbArrayToString(themeRgbColor.dndIndicator));
});
});

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

@@ -0,0 +1,48 @@
// 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 @account_setting
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
describe('Settings > Display > Theme > Save', () => {
before(() => {
// # Login as new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T2090 Theme Colors: New theme color is saved', () => {
// # Go to Settings modal - Display section
cy.uiOpenSettingsModal('Display');
// # Go to Theme settings tab
cy.get('#displayButton', {timeout: TIMEOUTS.FIVE_SEC}).should('be.visible').click();
cy.get('#themeTitle', {timeout: TIMEOUTS.TWO_SEC}).should('be.visible').click();
// # Change to dark theme
cy.get('#premadeThemeIndigo').should('not.have.class', 'active').click();
cy.get('#premadeThemeIndigo').should('have.class', 'active');
// # Save and close the Settings modal
cy.uiSaveAndClose();
// # Go to Settings modal - Display section
cy.uiOpenSettingsModal('Display');
// # Go to Theme settings tab
cy.get('#displayButton', {timeout: TIMEOUTS.FIVE_SEC}).should('be.visible').click();
cy.get('#themeTitle', {timeout: TIMEOUTS.TWO_SEC}).should('be.visible').click();
// * Verify dark theme is selected
cy.get('#premadeThemeIndigo').should('have.class', 'active');
});
});

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

@@ -0,0 +1,50 @@
// 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 @account_setting
describe('Settings > Display > Theme', () => {
before(() => {
// # Login as new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T3855 Theme Display should render in min setting view', () => {
// # Go to Settings > Display
cy.uiOpenSettingsModal('Display').within(() => {
// * Check the min setting view for each element that is present and contains the expected values
verifyMinDisplayView();
cy.uiClose();
});
});
});
function verifyMinDisplayView() {
cy.get('#themeTitle').should('be.visible', 'contain', 'Theme');
cy.get('#themeEdit').should('be.visible', 'contain', 'Edit');
cy.get('#clockTitle').should('be.visible', 'contain', 'Clock Display');
cy.get('#clockEdit').should('be.visible', 'contain', 'Edit');
cy.get('#name_formatTitle').should('be.visible', 'contain', 'Teammate Name Display');
cy.get('#name_formatEdit').should('be.visible', 'contain', 'Edit');
cy.get('#collapseTitle').should('be.visible', 'contain', 'Default appearance of image previews');
cy.get('#collapseEdit').should('be.visible', 'contain', 'Edit');
cy.get('#message_displayTitle').scrollIntoView().should('be.visible', 'contain', 'Message Display');
cy.get('#message_displayEdit').should('be.visible', 'contain', 'Edit');
cy.get('#languagesTitle').scrollIntoView().should('be.visible', 'contain', 'Language');
cy.get('#languagesEdit').should('be.visible', 'contain', 'Edit');
}

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

@@ -0,0 +1,256 @@
// 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 @account_setting
import moment from 'moment-timezone';
import * as DATE_TIME_FORMAT from '../../../../fixtures/date_time_format';
import * as TIMEOUTS from '../../../../fixtures/timeouts';
import {getTimezoneLabel} from '../../../../utils/timezone';
import {getAdminAccount} from '../../../../support/env';
describe('Profile > Display > Timezone', () => {
const sysadmin = getAdminAccount();
const date1 = Date.UTC(2020, 0, 5, 4, 30); // Jan 5, 2020 04:30
const date2 = Date.UTC(2020, 0, 5, 12, 30); // Jan 5, 2020 12:30
const date3 = Date.UTC(2020, 0, 5, 20, 30); // Jan 5, 2020 20:30
const date4 = Date.UTC(2020, 0, 6, 0, 30); // Jan 6, 2020 00:30
const localTz = moment.tz.guess();
const localTzLabel = getTimezoneLabel(localTz);
const timezoneLocal = {type: 'Canonical', value: localTzLabel};
const canonicalTz = 'Asia/Hong_Kong';
const canonicalTzLabel = getTimezoneLabel(canonicalTz);
const timezoneCanonical = {type: 'Canonical', value: canonicalTzLabel, expectedTz: canonicalTz};
const utcTz = 'Europe/Lisbon';
const utcTzLabel = getTimezoneLabel(utcTz);
const timezoneUTC = {type: 'Default', value: utcTzLabel, expectedTz: 'UTC'};
let userId;
before(() => {
// # Enable Timezone
cy.apiUpdateConfig({
DisplaySettings: {
ExperimentalTimezone: true,
},
});
// # Create and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({user, offTopicUrl}) => {
userId = user.id;
cy.visit(offTopicUrl);
// # Post messages from the past
[date1, date2, date3, date4].forEach((createAt, index) => {
cy.getCurrentChannelId().then((channelId) => {
cy.postMessageAs({sender: sysadmin, message: `Hello from ${index}`, channelId, createAt});
});
});
// # Post messages from now
cy.postMessage('Hello from now');
});
});
beforeEach(() => {
// # Reload to re-arrange posts
cy.reload();
});
it('MM-T301_1 Change timezone automatically', () => {
const automaticTestCases = [
{
timezone: timezoneLocal,
localTimes: [
{postIndex: 0, dateInTimezone: moment(date1).tz(timezoneLocal.value)},
{postIndex: 1, dateInTimezone: moment(date2).tz(timezoneLocal.value)},
{postIndex: 2, dateInTimezone: moment(date3).tz(timezoneLocal.value)},
{postIndex: 3, dateInTimezone: moment(date4).tz(timezoneLocal.value)},
],
},
];
automaticTestCases.forEach((testCase) => {
// # Reset to manual
cy.apiPatchMe({timezone: {automaticTimezone: '', manualTimezone: 'UTC', useAutomaticTimezone: 'false'}});
// # Set timezone display to automatic
setTimezoneDisplayToAutomatic(testCase.timezone.value);
// # Save Clock Display Mode to 12-hour
cy.apiSaveClockDisplayModeTo24HourPreference(false);
// * Verify local time is timezone formatted 12-hour
testCase.localTimes.forEach((localTime) => {
verifyLocalTimeIsTimezoneFormatted12Hour(localTime);
});
// # Save Clock Display Mode to 24-hour
cy.apiSaveClockDisplayModeTo24HourPreference(true);
// * Verify local time is timezone formatted 24-hour
testCase.localTimes.forEach((localTime) => {
verifyLocalTimeIsTimezoneFormatted24Hour(localTime);
});
});
});
it('MM-T301_2 Change timezone manually', () => {
const manualTestCases = [
{
timezone: timezoneCanonical,
localTimes: [
{postIndex: 0, dateInTimezone: moment(date1).tz(timezoneCanonical.expectedTz)},
{postIndex: 1, dateInTimezone: moment(date2).tz(timezoneCanonical.expectedTz)},
{postIndex: 2, dateInTimezone: moment(date3).tz(timezoneCanonical.expectedTz)},
{postIndex: 3, dateInTimezone: moment(date4).tz(timezoneCanonical.expectedTz)},
],
},
{
timezone: timezoneUTC,
localTimes: [
{postIndex: 0, dateInTimezone: moment(date1).tz(timezoneUTC.expectedTz)},
{postIndex: 1, dateInTimezone: moment(date2).tz(timezoneUTC.expectedTz)},
{postIndex: 2, dateInTimezone: moment(date3).tz(timezoneUTC.expectedTz)},
{postIndex: 3, dateInTimezone: moment(date4).tz(timezoneUTC.expectedTz)},
],
},
];
manualTestCases.forEach((testCase) => {
// # Reset to automatic
cy.apiPatchMe({timezone: {automaticTimezone: '', manualTimezone: '', useAutomaticTimezone: 'true'}});
// # Set timezone display to manual
setTimezoneDisplayToManual(testCase.timezone.value);
// # Save Clock Display Mode to 12-hour
cy.apiSaveClockDisplayModeTo24HourPreference(false);
// * Verify local time is timezone formatted 12-hour
testCase.localTimes.forEach((localTime) => {
verifyLocalTimeIsTimezoneFormatted12Hour(localTime);
});
// # Save Clock Display Mode to 24-hour
cy.apiSaveClockDisplayModeTo24HourPreference(true);
// * Verify local time is timezone formatted 24-hour
testCase.localTimes.forEach((localTime) => {
verifyLocalTimeIsTimezoneFormatted24Hour(localTime);
});
});
verifyUnchangedTimezoneOnInvalidInput(userId);
});
});
function navigateToTimezoneDisplaySettings() {
// # Go to Display section of Settings
cy.uiOpenSettingsModal('Display');
// # Click "Edit" to the right of "Timezone"
cy.get('#timezoneEdit').should('be.visible').click();
// # Scroll a bit to show the "Save" button
cy.get('.section-max').should('be.visible').scrollIntoView();
}
function setTimezoneDisplayTo(isAutomatic, value) {
// # Navigate to Timezone Display Settings
navigateToTimezoneDisplaySettings();
// # Uncheck the automatic timezone checkbox and verify unchecked
cy.get('.setting-list-item').as('settingItems');
cy.get('@settingItems').find('#automaticTimezoneInput').should('be.visible').uncheck().should('be.not.checked');
// * Verify Change timezone is enabled
cy.get('@settingItems').find('#displayTimezone').should('be.visible').find('input').as('changeTimezone').should('be.enabled');
if (isAutomatic) {
// # Check automatic timezone checkbox and verify checked
cy.get('@settingItems').find('#automaticTimezoneInput').check().should('be.checked');
// * Verify timezone text is visible
cy.get('@changeTimezone').invoke('text').then((timezoneDesc) => {
expect(value.replace('_', ' ')).to.contain(timezoneDesc);
});
// * Verify Change timezone is disabled
cy.get('@changeTimezone').should('be.disabled');
} else {
// # Manually type new timezone
cy.get('@changeTimezone').typeWithForce(`${value}{enter}`);
}
// # Click Save button
cy.uiSave();
// * Verify timezone description is correct
cy.get('#timezoneDesc').should('be.visible').invoke('text').then((timezoneDesc) => {
expect(value.replace('_', ' ')).to.contain(timezoneDesc);
});
// # Close Settings modal
cy.get('#accountSettingsHeader > .close').should('be.visible').click();
}
function setTimezoneDisplayToAutomatic(value) {
setTimezoneDisplayTo(true, value);
}
function setTimezoneDisplayToManual(value) {
setTimezoneDisplayTo(false, value);
}
function verifyLocalTimeIsTimezoneFormatted(localTime, timeFormat) {
// * Verify that the local time of each post is in timezone format
const formattedTime = localTime.dateInTimezone.format(timeFormat);
cy.findAllByTestId('postView', {timeout: TIMEOUTS.ONE_MIN}).
eq(localTime.postIndex).find('time', {timeout: TIMEOUTS.HALF_SEC}).
should('have.text', formattedTime);
}
function verifyLocalTimeIsTimezoneFormatted12Hour(localTime) {
verifyLocalTimeIsTimezoneFormatted(localTime, DATE_TIME_FORMAT.TIME_12_HOUR);
}
function verifyLocalTimeIsTimezoneFormatted24Hour(localTime) {
verifyLocalTimeIsTimezoneFormatted(localTime, DATE_TIME_FORMAT.TIME_24_HOUR);
}
function verifyUnchangedTimezoneOnInvalidInput(userId) {
// # Get current user's timezone
cy.apiGetMe(userId).then(({user: {timezone}}) => {
// # Navigate to Timezone Display Settings
navigateToTimezoneDisplaySettings();
// # Uncheck the automatic timezone checkbox and verify unchecked
cy.get('.setting-list-item').as('settingItems');
cy.get('@settingItems').find('#automaticTimezoneInput').should('be.visible').uncheck().should('be.not.checked');
// * Enter invalid input as timezone
cy.get('@settingItems').find('#displayTimezone').find('input').
should('be.enabled').
typeWithForce('invalid');
// # Click save
cy.uiSave();
// * Verify that the timezone is unchanged
cy.get('#timezoneDesc').should('be.visible').invoke('text').then((timezoneDesc) => {
expect(getTimezoneLabel(timezone.manualTimezone)).to.equal(timezoneDesc);
});
});
}

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

@@ -0,0 +1,66 @@
// 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 @account_setting
describe('Settings > Sidebar > Channel Switcher', () => {
let testUser;
let testTeam;
before(() => {
// # Login as test user
cy.apiInitSetup({loginAfter: true}).then(({team, user}) => {
testUser = user;
testTeam = team;
});
});
beforeEach(() => {
// # Visit off-topic
cy.visit(`/${testTeam.name}/channels/off-topic`);
cy.get('#channelHeaderTitle').should('be.visible').should('contain', 'Off-Topic');
});
it('Cmd/Ctrl+Shift+L closes Channel Switch modal and sets focus to post textbox', () => {
// # Type CTRL/CMD+K
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K');
// * Channel switcher hint should be visible
cy.get('#quickSwitchHint').should('be.visible').should('contain', 'Type to find a channel. Use UP/DOWN to browse, ENTER to select, ESC to dismiss.');
// # Type CTRL/CMD+shift+L
cy.findByRole('textbox', {name: 'quick switch input'}).cmdOrCtrlShortcut('{shift}L');
// * Suggestion list should not be visible
cy.get('#suggestionList').should('not.exist');
// * focus should be on the input box
cy.uiGetPostTextBox().should('be.focused');
});
it('Cmd/Ctrl+Shift+M closes Channel Switch modal and sets focus to mentions', () => {
// # patch user info
cy.apiPatchMe({notify_props: {first_name: 'false', mention_keys: testUser.username}});
// # Type CTRL/CMD+K
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K');
// * Channel switcher hint should be visible
cy.get('#quickSwitchHint').should('be.visible').should('contain', 'Type to find a channel. Use UP/DOWN to browse, ENTER to select, ESC to dismiss.');
// # Type CTRL/CMD+shift+m
cy.findByRole('textbox', {name: 'quick switch input'}).cmdOrCtrlShortcut('{shift}M');
// * Suggestion list should not be visible
cy.get('#suggestionList').should('not.exist');
cy.get('.sidebar--right__title').should('contain', 'Recent Mentions');
});
});

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

@@ -0,0 +1,68 @@
// 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 @account_setting @not_cloud
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Settings > Sidebar > Channel Switcher', () => {
let testChannel;
let testTeam;
before(() => {
cy.shouldNotRunOnCloudEdition();
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
testChannel = channel;
testTeam = team;
// # Create more test channels
const numberOfChannels = 14;
Cypress._.forEach(Array(numberOfChannels), (_, index) => {
cy.apiCreateChannel(testTeam.id, 'channel-switcher', `Channel Switcher ${index.toString()}`);
});
});
});
beforeEach(() => {
// # Visit off-topic
cy.visit(`/${testTeam.name}/channels/off-topic`);
cy.get('#channelHeaderTitle').should('be.visible').should('contain', 'Off-Topic');
});
it('MM-T266 Using CTRL/CMD+K to show Channel Switcher', () => {
// # Type CTRL/CMD+K
cy.typeCmdOrCtrl().type('K', {release: true});
verifyChannelSwitch(testTeam, testChannel);
});
});
function verifyChannelSwitch(team, channel) {
// * Channel switcher hint should be visible
cy.get('#quickSwitchHint').should('be.visible').should('contain', 'Type to find a channel. Use UP/DOWN to browse, ENTER to select, ESC to dismiss.');
// # Type channel display name on Channel switcher input
cy.findByRole('textbox', {name: 'quick switch input'}).type(channel.display_name);
cy.wait(TIMEOUTS.HALF_SEC);
// * Suggestion list should be visible
cy.get('#suggestionList').should('be.visible');
// # Press enter
cy.findByRole('textbox', {name: 'quick switch input'}).type('{enter}');
// * Verify that it redirected into "channel-switcher" as selected channel
cy.url().should('include', `/${team.name}/channels/${channel.name}`);
cy.get('#channelHeaderTitle').should('be.visible').should('contain', channel.display_name);
// * Channel name should be visible in LHS
cy.get(`#sidebarItem_${channel.name}`).scrollIntoView().should('be.visible');
}

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

@@ -0,0 +1,76 @@
// 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 @account_setting
import {getRandomId} from '../../../../utils';
describe('Settings > Sidebar > General', () => {
const randomId = getRandomId();
const newFirstName = `정트리나${randomId}/trina.jung/집단사무국(CO)`;
let testUser;
let otherUser;
let offTopicUrl;
before(() => {
cy.apiInitSetup().then(({team, user, offTopicUrl: url}) => {
testUser = user;
offTopicUrl = url;
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(team.id, otherUser.id);
});
// # Login as test user, visit off-topic and go to the Profile
cy.apiLogin(testUser);
cy.visit(offTopicUrl);
cy.uiOpenProfileModal();
// # Open Full Name section
cy.get('#nameDesc').click();
// # Set first name value
cy.get('#firstName').clear().type(newFirstName);
// # Save form
cy.uiSave();
});
});
it('MM-T183 Filtering by first name with Korean characters', () => {
const {username} = testUser;
cy.apiLogin(otherUser);
cy.visit(offTopicUrl);
// # Type in user's first name substring
cy.uiGetPostTextBox().clear().type(`@${newFirstName.substring(0, 11)}`);
// * Verify that the testUser is selected from mention autocomplete
cy.uiVerifyAtMentionInSuggestionList({...testUser, first_name: newFirstName}, true);
// # Press tab on text input
cy.uiGetPostTextBox().tab();
// * Verify that after enter user's username match
cy.uiGetPostTextBox().should('have.value', `@${username} `);
// # Click enter in post textbox
cy.uiGetPostTextBox().type('{enter}');
// * Verify that message has been post in chat
cy.get(`[data-mention="${username}"]`).
last().
scrollIntoView().
should('be.visible');
});
});