Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -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');
|
||||
});
|
||||
});
|
||||
Ссылка в новой задаче
Block a user