Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,130 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let sysadmin;
|
||||
let dmWithSysadmin;
|
||||
let townSquare;
|
||||
let offTopic;
|
||||
let testTeam;
|
||||
let publicChannel;
|
||||
let privateChannel;
|
||||
const insights = 'Insights';
|
||||
const insightsSidebar = {name: insights};
|
||||
|
||||
before(() => {
|
||||
cy.apiGetMe().then(({user: adminUser}) => {
|
||||
sysadmin = adminUser;
|
||||
|
||||
// # Create and login as new user
|
||||
// # Create a test team and channel, then visit
|
||||
cy.apiInitSetup({loginAfter: true}).then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
publicChannel = channel;
|
||||
|
||||
cy.apiCreateChannel(testTeam.id, 'private-a', 'Private B', 'P').then((out) => {
|
||||
privateChannel = out.channel;
|
||||
});
|
||||
cy.apiCreateDirectChannel([sysadmin.id, user.id]).then((out) => {
|
||||
dmWithSysadmin = out.channel;
|
||||
dmWithSysadmin.name = sysadmin.username;
|
||||
dmWithSysadmin.display_name = sysadmin.username;
|
||||
});
|
||||
cy.apiGetChannelByName(testTeam.name, 'town-square').then((out) => {
|
||||
townSquare = out.channel;
|
||||
});
|
||||
cy.apiGetChannelByName(testTeam.name, 'off-topic').then((out) => {
|
||||
offTopic = out.channel;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1229 Alt/Option + Up', () => {
|
||||
cy.visit(`/${testTeam.name}/messages/@${sysadmin.username}`);
|
||||
|
||||
// * Verify that the channel is loaded
|
||||
cy.get('#channelHeaderTitle').should('contain', sysadmin.username).wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Switch to channels by Alt+Up/Down keypress and verify
|
||||
verifyChannelSwitch(testTeam.name, townSquare, dmWithSysadmin, '{uparrow}');
|
||||
verifyChannelSwitch(testTeam.name, privateChannel, townSquare, '{uparrow}');
|
||||
verifyChannelSwitch(testTeam.name, offTopic, privateChannel, '{uparrow}');
|
||||
verifyChannelSwitch(testTeam.name, publicChannel, offTopic, '{uparrow}');
|
||||
|
||||
// * Should switch to Insights
|
||||
verifyChannelSwitch(testTeam.name, insightsSidebar, publicChannel, '{uparrow}');
|
||||
|
||||
// * Should switch to bottom of channel list when current channel is at the very top
|
||||
verifyChannelSwitch(testTeam.name, dmWithSysadmin, insightsSidebar, '{uparrow}');
|
||||
});
|
||||
|
||||
it('MM-T1230 Alt/Option + Down', () => {
|
||||
cy.visit(`/${testTeam.name}/channels/${publicChannel.name}`);
|
||||
|
||||
// * Verify that the channel is loaded
|
||||
cy.get('#channelHeaderTitle').should('contain', publicChannel.display_name).wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Switch to channels by Alt+Up/Down keypress and verify
|
||||
verifyChannelSwitch(testTeam.name, offTopic, publicChannel, '{downarrow}');
|
||||
verifyChannelSwitch(testTeam.name, privateChannel, offTopic, '{downarrow}');
|
||||
verifyChannelSwitch(testTeam.name, townSquare, privateChannel, '{downarrow}');
|
||||
verifyChannelSwitch(testTeam.name, dmWithSysadmin, townSquare, '{downarrow}');
|
||||
|
||||
// * Should switch to top (Insights) when current channel is at the very bottom
|
||||
verifyChannelSwitch(testTeam.name, insightsSidebar, dmWithSysadmin, '{downarrow}');
|
||||
verifyChannelSwitch(testTeam.name, publicChannel, insightsSidebar, '{downarrow}');
|
||||
});
|
||||
|
||||
function verifyChannelSwitch(teamName, toChannel, fromChannel, arrowKey) {
|
||||
// # Type Alt+Up/Down
|
||||
cy.get('body').type(`{alt}${arrowKey}`);
|
||||
|
||||
// * Verify that it redirects into expected URL
|
||||
if (toChannel.type === 'D') {
|
||||
cy.url().should('include', `/${teamName}/messages/@${toChannel.name}`);
|
||||
} else if (toChannel.name === insights) {
|
||||
cy.url().should('include', `/${teamName}/activity-and-insights`);
|
||||
} else {
|
||||
cy.url().should('include', `/${teamName}/channels/${toChannel.name}`);
|
||||
}
|
||||
|
||||
cy.get('#SidebarContainer').should('be.visible').within(() => {
|
||||
// * Verify that the toChannel is active in LHS
|
||||
verifyClass(toChannel, 'have.class');
|
||||
|
||||
// * Verify that the fromChannel is not active in LHS
|
||||
verifyClass(fromChannel, 'not.have.class');
|
||||
});
|
||||
|
||||
function verifyClass(channel, assertion) {
|
||||
if (channel.type) {
|
||||
let label;
|
||||
if (channel.type === 'O') {
|
||||
label = channel.display_name.toLowerCase() + ' public channel';
|
||||
} else if (channel.type === 'P') {
|
||||
label = channel.display_name.toLowerCase() + ' private channel';
|
||||
} else if (channel.type === 'D') {
|
||||
label = channel.display_name.toLowerCase();
|
||||
}
|
||||
|
||||
cy.findByLabelText(label).parent().should(assertion, 'active');
|
||||
} else {
|
||||
// For Insights
|
||||
cy.findByText(channel.name).parent().parent().parent().should(assertion, 'active');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
let publicChannel;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({team, channel, user}) => {
|
||||
// # Visit a test channel
|
||||
testTeam = team;
|
||||
publicChannel = channel;
|
||||
testUser = user;
|
||||
|
||||
cy.visit(`/${team.name}/channels/${channel.name}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3421 - Pressing the backspace key without an input focused should not send the browser back in history', () => {
|
||||
// # Navigate to a couple of pages
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
cy.visit(`/${testTeam.name}/channels/off-topic`);
|
||||
cy.visit(`/${testTeam.name}/channels/${publicChannel.name}`);
|
||||
cy.visit(`/${testTeam.name}/channels/off-topic`);
|
||||
|
||||
// # Visit a DM URL
|
||||
cy.visit(`/${testTeam.name}/messages/@${testUser.username}`);
|
||||
cy.url().should('include', `/${testTeam.name}/messages/@${testUser.username}`);
|
||||
|
||||
// # Type/edit some text and remove focus from the input field
|
||||
cy.uiGetPostTextBox().clear().type('This is a normal sentence.').type('{backspace}{backspace}').blur();
|
||||
|
||||
// * Verify that the backspace key presses modified the input correctly
|
||||
cy.uiGetPostTextBox().should('have.value', 'This is a normal sentenc');
|
||||
|
||||
// # Select the body to remove focus from the input field
|
||||
cy.get('body').type('{backspace}');
|
||||
cy.get('body').type('{backspace}');
|
||||
|
||||
// * Verify that the additional backspace key presses on blur doesn't affect the input
|
||||
cy.uiGetPostTextBox().should('have.value', 'This is a normal sentenc');
|
||||
|
||||
// * Verify that the URL doesn't change from the last URL
|
||||
cy.url().should('include', `/${testTeam.name}/messages/@${testUser.username}`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let url;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
url = channelUrl;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4775 CTRL/CMD+ALT+I - Toggle Channel Info RHS', () => {
|
||||
// # Visit a test channel
|
||||
cy.visit(url);
|
||||
|
||||
// # Wait for the page to load
|
||||
cy.get('.channel-intro').should('be.visible');
|
||||
|
||||
// ensure the RHS is not visible
|
||||
cy.contains('#rhsContainer', 'Info').should('not.exist');
|
||||
|
||||
// # Press CTRL/CMD+ALT+I
|
||||
cy.get('body').cmdOrCtrlShortcut('{alt}I');
|
||||
|
||||
// * Ensure RHS is now present
|
||||
cy.contains('#rhsContainer', 'Info').should('be.visible');
|
||||
|
||||
// # Press CTRL/CMD+ALT+I
|
||||
cy.get('body').cmdOrCtrlShortcut('{alt}I');
|
||||
|
||||
// * Ensure RHS is now closed
|
||||
cy.contains('#rhsContainer', 'Info').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1246 CTRL/CMD+K - @ at beginning of username', () => {
|
||||
// # Type CTRL/CMD+K
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('k');
|
||||
|
||||
// # Enter @ followed by the first 2 characters of username of the other user
|
||||
cy.get('#quickSwitchInput').type('@' + otherUser.username.slice(0, 3));
|
||||
|
||||
// # Click on the username in the suggestion list
|
||||
cy.findByTestId(otherUser.username).click();
|
||||
|
||||
// * The direct message channel for the user opens
|
||||
cy.url().should('include', `/${testTeam.name}/messages/@${otherUser.username}`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @keyboard_shortcuts¨
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({channelUrl}) => {
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1242 - CTRL/CMD+K - Typed characters are not lost after switching channels', () => {
|
||||
const message = 'Hello World!';
|
||||
|
||||
// # Type CTRL/CMD+K to open 'Switch Channels'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K');
|
||||
|
||||
// * Verify that the suggestion list is visible
|
||||
cy.get('#suggestionList').should('be.visible');
|
||||
|
||||
// # Type ENTER to switch to new channel
|
||||
cy.get('#quickSwitchInput').type('{enter}');
|
||||
|
||||
// # Typing message
|
||||
cy.get('body').type(message);
|
||||
|
||||
// * Textbox should have text equal to message
|
||||
cy.uiGetPostTextBox().should('have.text', message);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
// # Visit a test channel
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1243 CTRL/CMD+K - Open public channel using arrow keys and Enter, click out of current channel message box first', () => {
|
||||
// # To remove focus from message text box
|
||||
cy.get('#postListContent').click();
|
||||
cy.uiGetPostTextBox().should('not.be.focused');
|
||||
|
||||
// # Press CTRL/CMD+K
|
||||
cy.get('body').cmdOrCtrlShortcut('K');
|
||||
cy.get('#quickSwitchInput').type('T');
|
||||
|
||||
// # Press down arrow
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{downarrow}');
|
||||
cy.get('body').type('{downarrow}');
|
||||
|
||||
// * Confirm the offtopic channel is selected in the suggestion list
|
||||
cy.get('#suggestionList').findByTestId('off-topic').should('be.visible').and('have.class', 'suggestion--selected');
|
||||
|
||||
// # Press ENTER
|
||||
cy.get('body').type('{enter}');
|
||||
|
||||
// * Confirm that channel is open, and post text box has focus
|
||||
cy.contains('#channelHeaderTitle', 'Off-Topic');
|
||||
cy.uiGetPostTextBox().should('be.focused');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let testChannel;
|
||||
|
||||
before(() => {
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
ThreadAutoFollow: true,
|
||||
CollapsedThreads: 'default_off',
|
||||
},
|
||||
});
|
||||
cy.apiInitSetup({loginAfter: true, promoteNewUserAsAdmin: true}).then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
testChannel = channel;
|
||||
|
||||
cy.apiSaveCRTPreference(testUser.id, 'on');
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Visit channel
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
});
|
||||
|
||||
it('MM-T4648 CTRL/CMD+K - Create thread, Open global threads and then from find channels switch channel using arrow keys and Enter', () => {
|
||||
// # Post first message as other user
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: 'First post',
|
||||
channelId: testChannel.id,
|
||||
}).then(({id: rootId}) => {
|
||||
// # Click on post to open RHS
|
||||
cy.get(`#post_${rootId}`).click();
|
||||
|
||||
// # Post a reply as current user
|
||||
cy.postMessageReplyInRHS('Reply!');
|
||||
|
||||
// # Close RHS
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
|
||||
// # Post second message as other user
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: 'Second post',
|
||||
channelId: testChannel.id,
|
||||
}).then(({id: rootId}) => {
|
||||
// # Click on post to open RHS
|
||||
cy.get(`#post_${rootId}`).click();
|
||||
|
||||
// # Post a reply as current user
|
||||
cy.postMessageReplyInRHS('Reply!');
|
||||
|
||||
// # Visit global threads
|
||||
cy.uiClickSidebarItem('threads');
|
||||
|
||||
// * There should be a thread there
|
||||
cy.get('article.ThreadItem').should('have.have.lengthOf', 2);
|
||||
});
|
||||
|
||||
// # Press CTRL/CMD+K
|
||||
cy.get('body').cmdOrCtrlShortcut('K');
|
||||
cy.get('#quickSwitchInput').type('T');
|
||||
|
||||
// # Press down arrow
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{downarrow}');
|
||||
cy.get('body').type('{downarrow}');
|
||||
cy.get('body').type('{downarrow}');
|
||||
|
||||
// * should not select thread and switch thread in background
|
||||
cy.url().should('equal', `${Cypress.config('baseUrl')}/${testTeam.name}/threads`);
|
||||
|
||||
// * Confirm the offtopic channel is selected in the suggestion list
|
||||
cy.get('#suggestionList').findByTestId('off-topic').should('be.visible').and('have.class', 'suggestion--selected');
|
||||
|
||||
// # Press up arrow
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{uparrow}');
|
||||
|
||||
// * should not select thread and switch thread in background
|
||||
cy.url().should('equal', `${Cypress.config('baseUrl')}/${testTeam.name}/threads`);
|
||||
|
||||
// * Confirm the townsquare channel is selected in the suggestion list
|
||||
cy.get('#suggestionList').findByTestId('town-square').should('be.visible').and('have.class', 'suggestion--selected');
|
||||
|
||||
// # Press down arrow
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{downarrow}');
|
||||
|
||||
// * should not select thread and switch thread in background
|
||||
cy.url().should('equal', `${Cypress.config('baseUrl')}/${testTeam.name}/threads`);
|
||||
|
||||
// * Confirm the offtopic channel is selected in the suggestion list
|
||||
cy.get('#suggestionList').findByTestId('off-topic').should('be.visible').and('have.class', 'suggestion--selected');
|
||||
|
||||
// # Press ENTER
|
||||
cy.get('body').type('{enter}');
|
||||
|
||||
// * Confirm that channel is open
|
||||
cy.contains('#channelHeaderTitle', 'Off-Topic');
|
||||
cy.url().should('include', '/channels/off-topic');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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 @messaging
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let firstUser;
|
||||
let secondUser;
|
||||
let thirdUser;
|
||||
|
||||
before(() => {
|
||||
// # Login as test user
|
||||
cy.apiInitSetup().then(({offTopicUrl, team, user: user1}) => {
|
||||
firstUser = user1;
|
||||
testTeam = team;
|
||||
|
||||
// # Create two more users
|
||||
cy.apiCreateUser().then(({user: user2}) => {
|
||||
secondUser = user2;
|
||||
cy.apiAddUserToTeam(testTeam.id, secondUser.id);
|
||||
});
|
||||
|
||||
cy.apiCreateUser().then(({user: user3}) => {
|
||||
thirdUser = user3;
|
||||
cy.apiAddUserToTeam(testTeam.id, thirdUser.id);
|
||||
});
|
||||
|
||||
cy.apiLogin(firstUser);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1245 CTRL/CMD+K - Open GM using mouse', () => {
|
||||
// # Create a GM channel
|
||||
cy.apiCreateGroupChannel([firstUser.id, secondUser.id, thirdUser.id]).then(() => {
|
||||
// # Press Cmd/Ctrl-K to open "Switch Channels" modal
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K');
|
||||
|
||||
// # Click on the GM link to go to channel
|
||||
cy.get('.status--group').click();
|
||||
|
||||
// * Check if channel intro message with usernames is visible
|
||||
cy.findByText(/This is the start/).should('be.visible').contains(secondUser.username).contains(thirdUser.username);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,157 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
const count = 3;
|
||||
const teamAndChannels = [];
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testUser = user;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(team.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
Cypress._.times(2, (i) => {
|
||||
cy.apiCreateTeam(`team${i}`, `Team${i}`).then(({team: testTeam}) => {
|
||||
teamAndChannels.push({team: testTeam, channels: []});
|
||||
const channelName = `channel${i}`;
|
||||
const channelDisplayName = `Channel${i}`;
|
||||
|
||||
Cypress._.times(count, (j) => {
|
||||
cy.apiCreateChannel(testTeam.id, channelName + j, channelDisplayName + j).then(({channel: testChannel}) => {
|
||||
teamAndChannels[i].channels.push(testChannel);
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiLogin(testUser);
|
||||
});
|
||||
|
||||
it('MM-T1241 - CTRL/CMD+K: Unreads', () => {
|
||||
const otherUserMention = `@${otherUser.username}`;
|
||||
|
||||
// # Post messages as testUser to first and second team's channels
|
||||
Cypress._.forEach(teamAndChannels, (teamAndChannel, i) => {
|
||||
cy.visit(`/${teamAndChannel.team.name}/channels/off-topic`);
|
||||
|
||||
Cypress._.forEach(teamAndChannel.channels, (channel, j) => {
|
||||
cy.get('#sidebarItem_' + channel.name).scrollIntoView().click();
|
||||
const message = i === j ? 'without mention' : `mention ${otherUserMention} `;
|
||||
cy.postMessage(message);
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
});
|
||||
});
|
||||
|
||||
// # Login as otherUser
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(otherUser);
|
||||
|
||||
const baseCount = 1;
|
||||
const withMention = 1;
|
||||
|
||||
const team2 = teamAndChannels[1].team;
|
||||
const team2Channels = teamAndChannels[1].channels;
|
||||
|
||||
// # switch to team 2
|
||||
cy.visit(`/${team2.name}/channels/off-topic`);
|
||||
|
||||
// # Type CTRL/CMD+K
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K');
|
||||
|
||||
// # Verify that the mentions in the channels of this team are displayed, channel will come based on recency of post
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#suggestionList').
|
||||
findByTestId(team2Channels[2].name).should('be.visible').and('have.class', 'suggestion--selected').
|
||||
find('.badge').should('be.visible').and('have.text', baseCount + withMention);
|
||||
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).type('{downarrow}');
|
||||
cy.get('#suggestionList').
|
||||
findByTestId(team2Channels[1].name).should('be.visible').and('have.class', 'suggestion--selected').
|
||||
find('.badge').should('be.visible').and('have.text', baseCount);
|
||||
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).type('{downarrow}');
|
||||
cy.get('#suggestionList').
|
||||
findByTestId(team2Channels[0].name).should('be.visible').and('have.class', 'suggestion--selected').
|
||||
find('.badge').should('be.visible').and('have.text', baseCount + withMention);
|
||||
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).type('{downarrow}');
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).type(team2Channels[1].display_name).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Verify that the channels of this team are displayed
|
||||
cy.get('#suggestionList').should('be.visible').children().within((el) => {
|
||||
cy.wrap(el).should('contain', team2Channels[1].display_name);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3002 CTRL/CMD+K - Unread Channels and input field focus', () => {
|
||||
const team1 = teamAndChannels[0].team;
|
||||
|
||||
// # Visit town square channel by teamUser
|
||||
cy.visit(`/${team1.name}/channels/off-topic`);
|
||||
|
||||
// # Post message in other channels by otherUser
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: `Message on the ${teamAndChannels[0].channels[0].display_name}`,
|
||||
channelId: teamAndChannels[0].channels[0].id,
|
||||
}).then(() => {
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: `Message on the ${teamAndChannels[0].channels[1].display_name}`,
|
||||
channelId: teamAndChannels[0].channels[1].id,
|
||||
}).then(() => {
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: `Message on the ${teamAndChannels[0].channels[2].display_name}`,
|
||||
channelId: teamAndChannels[0].channels[2].id,
|
||||
}).then(() => {
|
||||
// # Press keyboard shortcut for channel switcher
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('k');
|
||||
|
||||
// * Verify channel switcher shows up
|
||||
cy.get('.a11y__modal.channel-switcher').should('exist').and('be.visible').as('channelSwitcherDialog');
|
||||
|
||||
// * Verify the focus is on switchers input field
|
||||
cy.focused().should('have.id', 'quickSwitchInput');
|
||||
|
||||
// * Verify all unread channels names are showing up in the dialogs list
|
||||
cy.get('@channelSwitcherDialog').within(() => {
|
||||
// * Verify all unread channels names are showing up in the dialogs list
|
||||
teamAndChannels[0].channels.forEach((channel) => {
|
||||
cy.findByText(channel.display_name).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
|
||||
cy.apiInitSetup().
|
||||
then(({user, team}) => cy.
|
||||
wrap(user).as('mainUser').
|
||||
wrap(team).as('mainTeam'),
|
||||
);
|
||||
cy.apiInitSetup().
|
||||
then(({user, team}) => cy.
|
||||
wrap(user).as('otherUser').
|
||||
wrap(team).as('otherTeam'),
|
||||
);
|
||||
});
|
||||
|
||||
it('MM-T1228_1 CTRL/CMD+K - Open DM with user not on the current team / with ANY', function() {
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictDirectMessage: 'any',
|
||||
},
|
||||
});
|
||||
|
||||
// # Log-in with created user
|
||||
cy.apiLogin(this.mainUser);
|
||||
|
||||
// * User is found and DM channel with the user opens
|
||||
verifyUserIsFoundAndDMOpensOnClick(this.otherUser);
|
||||
});
|
||||
|
||||
it('MM-T1228_2 CTRL/CMD+K - Open DM with user not on the current team / with TEAM', function() {
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictDirectMessage: 'team',
|
||||
},
|
||||
});
|
||||
|
||||
// # Log-in with created user
|
||||
cy.apiLogin(this.mainUser);
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
// # Select CTRL/CMD+K (or ⌘+K) to open the channel switcher
|
||||
cy.typeCmdOrCtrl().type('K', {release: true});
|
||||
|
||||
// # Start typing the name of other user
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).type(this.otherUser.username);
|
||||
|
||||
// # Select other user from the list
|
||||
cy.findByTestId(this.otherUser.username).should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1228_3 CTRL/CMD+K - Open DM with user belonging to both teams / with ANY', function() {
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictDirectMessage: 'any',
|
||||
},
|
||||
});
|
||||
|
||||
// # Add other user to the main team
|
||||
cy.apiAddUserToTeam(this.mainTeam.id, this.otherUser.id);
|
||||
|
||||
// # Log-in with created user
|
||||
cy.apiLogin(this.mainUser);
|
||||
|
||||
// * User is found and DM channel with the user opens
|
||||
verifyUserIsFoundAndDMOpensOnClick(this.otherUser);
|
||||
});
|
||||
|
||||
it('MM-T1228_4 CTRL/CMD+K - Open DM with user belonging to both teams / with TEAM', function() {
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictDirectMessage: 'team',
|
||||
},
|
||||
});
|
||||
|
||||
// # Add other user to the main team
|
||||
cy.apiAddUserToTeam(this.mainTeam.id, this.otherUser.id);
|
||||
|
||||
// # Log-in with created user
|
||||
cy.apiLogin(this.mainUser);
|
||||
|
||||
// * User is found and DM channel with the user opens
|
||||
verifyUserIsFoundAndDMOpensOnClick(this.otherUser);
|
||||
});
|
||||
});
|
||||
|
||||
function verifyUserIsFoundAndDMOpensOnClick(user) {
|
||||
cy.visit('/');
|
||||
|
||||
// # Select CTRL/CMD+K (or ⌘+K) to open the channel switcher
|
||||
cy.typeCmdOrCtrl().type('K', {release: true});
|
||||
|
||||
// # Start typing the name of other user
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).type(user.username);
|
||||
|
||||
// # Select other user from the list
|
||||
cy.findByTestId(user.username).should('be.visible');
|
||||
cy.findByTestId(user.username).click();
|
||||
|
||||
// * Other user name is visible in header
|
||||
cy.get('#channelHeaderTitle').should('contain', user.username);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
// # Visit a test channel
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1249 CTRL/CMD+SHIFT+L - Set focus to center channel message box (with REPLY RHS open)', () => {
|
||||
cy.postMessage('Hello World!');
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Open RHS
|
||||
cy.clickPostDotMenu(postId);
|
||||
cy.findByText('Reply').click();
|
||||
|
||||
// * Confirm that reply text box has focus
|
||||
cy.uiGetReplyTextBox().should('be.focused');
|
||||
|
||||
// * Confirm the RHS is shown
|
||||
cy.get('#rhsCloseButton').should('exist');
|
||||
|
||||
// # Press CTRL/CMD+SHIFT+L
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}L');
|
||||
|
||||
// * Confirm the message box has focus
|
||||
cy.uiGetPostTextBox().should('be.focused');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1250 CTRL/CMD+SHIFT+L - Set focus to center channel message box (with SEARCH RHS open)', () => {
|
||||
// # Search
|
||||
cy.get('#searchBox').click().type('test{enter}');
|
||||
|
||||
// * Wait for the RHS to open and the search results to appear
|
||||
cy.contains('.sidebar--right__header', 'Search Results').should('be.visible');
|
||||
|
||||
// # Press CTRL/CMD+SHIFT+L
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}L');
|
||||
|
||||
// * Confirm the message box has focus
|
||||
cy.uiGetPostTextBox().should('be.focused');
|
||||
});
|
||||
});
|
||||
@@ -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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({channelUrl}) => {
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4441_1 CTRL/CMD+SHIFT+A - Settings should open in desktop view', () => {
|
||||
// # Type CTRL/CMD+SHIFT+A to open 'Settings'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}A');
|
||||
|
||||
// * Ensure account settings modal is open
|
||||
cy.get('#accountSettingsModal').should('be.visible');
|
||||
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T4441_2 CTRL/CMD+SHIFT+A - Settings should open in mobile view view', () => {
|
||||
// # Resize the window to mobile view
|
||||
cy.viewport('iphone-6');
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+A to open 'Settings'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}A');
|
||||
|
||||
// * Ensure Settings modal is open
|
||||
cy.get('#accountSettingsModal').should('be.visible');
|
||||
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('CTRL+A - Should not open Settings', () => {
|
||||
// # Type CTRL/CMD+A to select the text
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('A');
|
||||
|
||||
// * Ensure Settings modal is not open
|
||||
cy.get('#accountSettingsModal').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
// # Visit a test channel
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1251 CTRL/CMD+SHIFT+L - When not to set focus to center channel message box', () => {
|
||||
// # Open settings modal
|
||||
cy.uiOpenSettingsModal();
|
||||
|
||||
// # Press ctrl/cmd+shift+l
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift+l}');
|
||||
|
||||
// * Verify channel message box is not focused
|
||||
cy.uiGetPostTextBox().should('not.be.focused');
|
||||
|
||||
// # Close settings modal
|
||||
cy.uiClose();
|
||||
|
||||
// # Open invite members full-page screen
|
||||
cy.get('#introTextInvite').click();
|
||||
|
||||
// # Press ctrl/cmd+shift+l
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift+l}');
|
||||
|
||||
// * Verify channel message box is not focused
|
||||
cy.uiGetPostTextBox().should('not.be.focused');
|
||||
|
||||
// # Close invite members full-page screen
|
||||
cy.uiClose();
|
||||
});
|
||||
});
|
||||
@@ -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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
testUser = user;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1253 - CTRL/CMD+SHIFT+M', () => {
|
||||
const message1 = ' from DM channel';
|
||||
const message2 = ' from channel';
|
||||
const message3 = ' using suggestion';
|
||||
const messagePrefix = `mention @${testUser.username}`;
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Create DM channel with the second user
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(() => {
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
|
||||
// # Post in DM channel
|
||||
cy.postMessage(messagePrefix + message1);
|
||||
});
|
||||
|
||||
// # Post user name mention in this channel
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
cy.postMessage(messagePrefix + message2);
|
||||
|
||||
// # Type user name mention and post it to the channel
|
||||
cy.uiGetPostTextBox().clear().type(messagePrefix + message3).type('{enter}{enter}');
|
||||
|
||||
// # Type "words that trigger mentions"
|
||||
cy.postMessage('mention @here ');
|
||||
cy.postMessage('mention @all ');
|
||||
cy.postMessage('mention @channel ');
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+M to open search
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}M');
|
||||
|
||||
cy.get('.sidebar--right__title').should('contain', 'Recent Mentions');
|
||||
|
||||
// # Verify that the correct number of mentions are returned
|
||||
cy.findAllByTestId('search-item-container').should('be.visible').should('have.length', 3);
|
||||
cy.get('#search-items-container').within(() => {
|
||||
// * Ensure that the mentions are visible in the RHS
|
||||
cy.findAllByText(`@${testUser.username}`).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
/**
|
||||
* Fires off keyboard shortcut for "React to last message"
|
||||
* @param {String} from CENTER, RHS or body if not provided.
|
||||
*/
|
||||
export function doReactToLastMessageShortcut(from) {
|
||||
if (from === 'CENTER') {
|
||||
cy.uiGetPostTextBox().
|
||||
focus().
|
||||
clear().
|
||||
cmdOrCtrlShortcut('{shift}\\');
|
||||
} else if (from === 'RHS') {
|
||||
cy.uiGetReplyTextBox().
|
||||
focus().
|
||||
clear().
|
||||
cmdOrCtrlShortcut('{shift}\\');
|
||||
} else {
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}\\');
|
||||
}
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an emoji reaction was added to a post, defaults check for 'smile' emoji
|
||||
* @param {String} postId Post ID of the message
|
||||
* @param {String} emoji (Optional) Emoji name
|
||||
*/
|
||||
export function checkReactionFromPost(postId, emoji = 'smile') {
|
||||
if (postId) {
|
||||
cy.get(`#${postId}_message`).within(() => {
|
||||
cy.findByLabelText('reactions').should('exist');
|
||||
cy.findByLabelText(`remove reaction ${emoji}`).should('exist');
|
||||
});
|
||||
} else {
|
||||
cy.findByLabelText('reactions').should('exist');
|
||||
cy.findByLabelText(`remove reaction ${emoji}}`).should('exist');
|
||||
}
|
||||
}
|
||||
|
||||
export function pressEscapeKey() {
|
||||
cy.get('body').type('{esc}');
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
// 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 @emoji @keyboard_shortcuts
|
||||
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
import {
|
||||
doReactToLastMessageShortcut,
|
||||
pressEscapeKey,
|
||||
} from './helpers';
|
||||
|
||||
describe('Keyboard shortcut CTRL/CMD+Shift+\\ for adding reaction to last message', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
let emptyChannel;
|
||||
|
||||
before(() => {
|
||||
// # Enable Experimental View Archived Channels
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
ExperimentalViewArchivedChannels: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
emptyChannel = channel;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as test user and visit off-topic
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/off-topic`);
|
||||
|
||||
// # Post a message without reaction for each test
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
|
||||
it('MM-T4059_1 Do not open if emoji picker is already opened for other message', () => {
|
||||
// # Get post ID of the first post
|
||||
cy.getLastPostId().then((firstPostId) => {
|
||||
// # Post another message
|
||||
cy.postMessage(MESSAGES.MEDIUM);
|
||||
|
||||
// # Click reaction button from the first message
|
||||
cy.clickPostReactionIcon(firstPostId);
|
||||
|
||||
// # Do keyboard shortcut while emoji picker is opened
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// # Add reaction to first post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Verify no reaction is added to last post
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#${lastPostId}_message`).within(() => {
|
||||
cy.findByLabelText('reactions').should('not.exist');
|
||||
cy.findByLabelText('remove reaction smile').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4059_2 Do not open emoji picker if last message is not visible in view', () => {
|
||||
// # Get post ID of the first post
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#${lastPostId}_message`).as('firstPost');
|
||||
});
|
||||
|
||||
// # Make several posts, enough to enable vertical scroll
|
||||
Cypress._.times(5, () => {
|
||||
cy.uiPostMessageQuickly(MESSAGES.HUGE);
|
||||
});
|
||||
|
||||
cy.postMessage(MESSAGES.SMALL);
|
||||
|
||||
// # Get the post id of the last post
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#${lastPostId}_message`).as('lastPost');
|
||||
});
|
||||
|
||||
// # Scroll to top post
|
||||
cy.get('@firstPost').scrollIntoView();
|
||||
|
||||
// # Do keyboard shortcut
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Check that emoji picker is not open
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// * No reaction should be present on the last message
|
||||
cy.get('@lastPost').within(() => {
|
||||
cy.findByLabelText('reactions').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4059_3 Do not open emoji picker if any modal is open', () => {
|
||||
cy.uiOpenProductMenu('About Mattermost');
|
||||
verifyEmojiPickerNotOpen();
|
||||
|
||||
cy.uiOpenTeamMenu('View Members');
|
||||
verifyEmojiPickerNotOpen();
|
||||
|
||||
cy.uiOpenProfileModal();
|
||||
verifyEmojiPickerNotOpen();
|
||||
|
||||
['Edit Channel Header', 'Rename Channel'].forEach((modal) => {
|
||||
// # Open the modal and do keyboard shortcut
|
||||
cy.uiOpenChannelMenu(modal);
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Verify emoji picker is not open
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// # Close the modal
|
||||
pressEscapeKey();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4059_4 Do not open emoji picker if any dropdown is open', () => {
|
||||
// # Open the channel menu dropdown and do keyboard shortcut
|
||||
cy.uiOpenChannelMenu();
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// # Verify emoji picker is not open
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// * Open the main menu dropdown and do keyboard shortcut
|
||||
cy.uiOpenTeamMenu();
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Verify emoji picker is not open
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T4059_5 Do not open emoji picker if RHS is fully expanded for search results, recent mentions and saved posts', () => {
|
||||
// # Open the saved message
|
||||
cy.uiGetSavedPostButton().click();
|
||||
|
||||
// # Expand RHS
|
||||
cy.findByLabelText('Expand Sidebar Icon').click();
|
||||
|
||||
// # Do keyboard shortcut
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Check if emoji picker is opened
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// # Close the expanded RHS
|
||||
cy.findByLabelText('Collapse Sidebar Icon').click();
|
||||
|
||||
// # Open the pinned posts
|
||||
cy.uiGetChannelPinButton().click();
|
||||
|
||||
// # Expand RHS
|
||||
cy.findByLabelText('Expand Sidebar Icon').click();
|
||||
|
||||
// # Do keyboard shortcut
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Check if emoji picker is opened
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// # Close the expanded RHS
|
||||
cy.findByLabelText('Collapse Sidebar Icon').click();
|
||||
});
|
||||
|
||||
it('MM-T4059_6 Do not open emoji picker if last post is a system message', () => {
|
||||
// # Login as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Visit the new empty channel
|
||||
cy.visit(`/${testTeam.name}/channels/${emptyChannel.name}`);
|
||||
|
||||
// * Check that there are no post except you joined message
|
||||
cy.findAllByTestId('postView').should('have.length', 1);
|
||||
|
||||
// # Do keyboard shortcut
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Check that emoji picker is not opened for system joining message
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// # Delete the system message
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.clickPostDotMenu(lastPostId);
|
||||
|
||||
// # Click delete button.
|
||||
cy.get(`#delete_post_${lastPostId}`).click();
|
||||
|
||||
// * Check that confirmation dialog is open.
|
||||
cy.get('#deletePostModal').should('be.visible');
|
||||
|
||||
// # Confirm deletion.
|
||||
cy.get('#deletePostModalButton').click();
|
||||
|
||||
// # Do keyboard shortcut
|
||||
doReactToLastMessageShortcut('CENTER');
|
||||
|
||||
// * Check that emoji picker is not opened for new channel
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
});
|
||||
|
||||
// # Post a message to channel
|
||||
cy.postMessage(MESSAGES.TINY);
|
||||
|
||||
// # Archive the channel after posting a message
|
||||
cy.apiDeleteChannel(emptyChannel.id);
|
||||
|
||||
// # Do keyboard shortcut
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Check that emoji picker is not opened
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
function verifyEmojiPickerNotOpen() {
|
||||
// # Click emoji button
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Verify emoji picker is not open
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
|
||||
// # Close the modal
|
||||
pressEscapeKey();
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
// 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 @emoji @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
import {
|
||||
checkReactionFromPost,
|
||||
doReactToLastMessageShortcut,
|
||||
} from './helpers';
|
||||
|
||||
describe('Keyboard shortcut CTRL/CMD+Shift+\\ for adding reaction to last message', () => {
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let testTeam;
|
||||
let offTopicChannel;
|
||||
|
||||
before(() => {
|
||||
// # Enable Experimental View Archived Channels
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
ExperimentalViewArchivedChannels: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'off-topic').then((out) => {
|
||||
offTopicChannel = out.channel;
|
||||
});
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as test user and visit off-topic
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/off-topic`);
|
||||
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').and('contain', 'Off-Topic');
|
||||
|
||||
// # Post a message without reaction for each test
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
|
||||
it('MM-T4060_1 Open emoji picker on center when focus is neither on center or comment textbox even if RHS is opened', () => {
|
||||
// # Click post comment icon
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// * Check that RHS is open
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
// # Post couple of comments in RHS.
|
||||
cy.postMessageReplyInRHS(MESSAGES.SMALL);
|
||||
cy.postMessageReplyInRHS(MESSAGES.TINY);
|
||||
|
||||
// # Save the post ID where reaction should not be added
|
||||
cy.getLastPostId().as('prevLastPostId');
|
||||
|
||||
// # Have another user post a message
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: MESSAGES.MEDIUM,
|
||||
channelId: offTopicChannel.id,
|
||||
});
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
|
||||
// # Click anywhere to take focus away from RHS text box
|
||||
cy.get('body').click();
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
|
||||
// # Do keyboard shortcut without focus on center
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji reaction is shown in the last message in center
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#post_${lastPostId}`).findByLabelText('remove reaction smile').should('exist');
|
||||
});
|
||||
|
||||
// * Check if no emoji reaction is shown from last comment both in RHS and center
|
||||
cy.get('@prevLastPostId').then((lastPostId) => {
|
||||
cy.get(`#rhsPost_${lastPostId}`).findByLabelText('remove reaction smile').should('not.exist');
|
||||
cy.get(`#post_${lastPostId}`).findByLabelText('remove reaction smile').should('not.exist');
|
||||
});
|
||||
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
|
||||
it('MM-T4060_2 Open emoji picker on center when focus is on center text box even if RHS is opened', () => {
|
||||
// # Click post comment icon
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// * Check that RHS is open
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
// # Post couple of comments in RHS.
|
||||
cy.postMessageReplyInRHS(MESSAGES.SMALL);
|
||||
cy.postMessageReplyInRHS(MESSAGES.TINY);
|
||||
|
||||
// # Get the last post ID in RHS where reaction should not be added
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#${lastPostId}_message`).as('postInRHS');
|
||||
});
|
||||
|
||||
// # Have another user post a message to a channel
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: MESSAGES.MEDIUM,
|
||||
channelId: offTopicChannel.id,
|
||||
});
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
// # Click anywhere to take focus away from RHS text box
|
||||
cy.uiGetLhsSection('CHANNELS').findByText('Off-Topic').click();
|
||||
|
||||
// # Do keyboard shortcut with focus on center
|
||||
doReactToLastMessageShortcut('CENTER');
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// # This post is in Center, where reaction is to be added
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#${lastPostId}_message`).as('postInCenter');
|
||||
});
|
||||
|
||||
// * Check if emoji is shown as reaction to the message in center
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
|
||||
// * Check if no emoji reaction is shown in the last comment at RHS
|
||||
cy.get('@postInRHS').within(() => {
|
||||
cy.findByLabelText('reactions').should('not.exist');
|
||||
cy.findByLabelText('remove reaction smile').should('not.exist');
|
||||
});
|
||||
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
|
||||
it('MM-T1804_1 Open emoji picker for last message when focus is on center textbox', () => {
|
||||
// # Do keyboard shortcut with focus on center
|
||||
doReactToLastMessageShortcut('CENTER');
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to last message
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1804_2 Open emoji picker for last message even when focus is not on center textbox', () => {
|
||||
// # Click anywhere to take focus away from center text box
|
||||
cy.uiGetLhsSection('CHANNELS').findByText('Off-Topic').click();
|
||||
|
||||
// # Do keyboard shortcut without focus on center
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to last message
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1804_3 Should reopen emoji picker even if shortcut is hit repeatedly on center', () => {
|
||||
// # Do keyboard shortcuts then escape multiple times, and
|
||||
// * verify that emoji picker open up each time
|
||||
Cypress._.times(3, () => {
|
||||
doReactToLastMessageShortcut('CENTER');
|
||||
cy.get('#emojiPicker').should('exist');
|
||||
cy.get('body').click();
|
||||
cy.get('#emojiPicker').should('not.exist');
|
||||
});
|
||||
|
||||
// # Do keyboard shortcut with focus on center
|
||||
doReactToLastMessageShortcut('CENTER');
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to last message
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1804_4 Should add reaction to same post on which emoji picker was opened', () => {
|
||||
// # Save the post id which user initially intended to add reaction to, for later use
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.wrap(lastPostId).as('postIdForAddingReaction');
|
||||
});
|
||||
|
||||
// # Do keyboard shortcut without focus
|
||||
doReactToLastMessageShortcut();
|
||||
|
||||
// * Check that emoji picker is open
|
||||
cy.get('#emojiPicker').should('exist');
|
||||
|
||||
// # While open, have another user post a message to a channel
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: MESSAGES.TINY,
|
||||
channelId: offTopicChannel.id,
|
||||
});
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
// * Check if emoji picker is still open and add a reaction
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to the message it initially intended
|
||||
cy.get('@postIdForAddingReaction').then((postIdForAddingReaction) => {
|
||||
checkReactionFromPost(postIdForAddingReaction);
|
||||
});
|
||||
|
||||
// * Check if last message didn't get a reaction
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
cy.get(`#${lastPostId}_message`).within(() => {
|
||||
cy.findByLabelText('reactions').should('not.exist');
|
||||
cy.findByLabelText('remove reaction smile').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,116 @@
|
||||
// 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 @emoji @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
import {
|
||||
checkReactionFromPost,
|
||||
doReactToLastMessageShortcut,
|
||||
} from './helpers';
|
||||
|
||||
describe('Keyboard shortcut CTRL/CMD+Shift+\\ for adding reaction to last message', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
|
||||
before(() => {
|
||||
// # Enable Experimental View Archived Channels
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
ExperimentalViewArchivedChannels: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as test user and visit town-square
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/off-topic`);
|
||||
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').and('contain', 'Off-Topic');
|
||||
|
||||
// # Post a message without reaction for each test
|
||||
cy.postMessage(MESSAGES.TINY);
|
||||
});
|
||||
|
||||
it('MM-T4058_1 Open emoji picker for root post in RHS when focus is on comment textbox', () => {
|
||||
// # Click post comment icon
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// * Check that the RHS is open
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
// # Do keyboard shortcut with focus on RHS
|
||||
doReactToLastMessageShortcut('RHS');
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to the last message (same in RHS)
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
|
||||
it('MM-T4058_2 Open emoji picker for last comment in RHS when focus is on comment textbox', () => {
|
||||
// # Click post comment icon
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// * Check that the RHS is open
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
// # Post few comments in RHS
|
||||
cy.postMessageReplyInRHS(MESSAGES.SMALL);
|
||||
cy.postMessageReplyInRHS(MESSAGES.TINY);
|
||||
|
||||
// # Do keyboard shortcut with focus on RHS
|
||||
doReactToLastMessageShortcut('RHS');
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to the last message (same in RHS)
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
|
||||
it('MM-T4058_3 Open emoji picker for last comment in fully expanded RHS when focus is on comment textbox', () => {
|
||||
// # Click post comment icon
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// * Check that the RHS is open
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
// # Fully expand the RHS
|
||||
cy.uiExpandRHS();
|
||||
|
||||
// # Do keyboard shortcut with focus on RHS
|
||||
doReactToLastMessageShortcut('RHS');
|
||||
|
||||
// # Add reaction to a post
|
||||
cy.clickEmojiInEmojiPicker('smile');
|
||||
|
||||
// * Check if emoji is shown as reaction to the last message (same in RHS)
|
||||
cy.getLastPostId().then((lastPostId) => {
|
||||
checkReactionFromPost(lastPostId);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
// # Visit a test channel
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM - T1257 CTRL / CMD + UP or DOWN in RHS', () => {
|
||||
const firstMessage = 'Hello World!';
|
||||
const messages = ['This', 'is', 'an', 'e2e test', '/shrug'];
|
||||
|
||||
// # Post a message in the central textbox
|
||||
cy.postMessage(firstMessage);
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Open RHS
|
||||
cy.clickPostDotMenu(postId);
|
||||
cy.findByText('Reply').click();
|
||||
|
||||
// * Confirm that reply text box has focus
|
||||
cy.findByTestId('reply_textbox').should('be.focused');
|
||||
|
||||
// * Verify RHS is opened
|
||||
cy.uiGetRHS().within(() => {
|
||||
for (let idx = 0; idx < messages.length; idx++) {
|
||||
// # Post each message as a reply
|
||||
cy.findByTestId('reply_textbox').
|
||||
type(messages[idx]).
|
||||
type('{enter}').
|
||||
clear();
|
||||
}
|
||||
|
||||
// * Confirm that reply textbox has focus
|
||||
cy.findByTestId('reply_textbox').should('be.focused');
|
||||
cy.findByTestId('reply_textbox').clear();
|
||||
|
||||
// # Press CTRL/CMD + uparrow repeatedly
|
||||
let previousMessageIndex = messages.length - 1;
|
||||
for (let idx = 0; idx <= messages.length; idx++) {
|
||||
if (idx === messages.length) {
|
||||
// * Check if the last message is equal to the first message
|
||||
cy.findByTestId('reply_textbox').cmdOrCtrlShortcut('{uparrow}');
|
||||
cy.findByTestId('reply_textbox').should('have.text', firstMessage);
|
||||
break;
|
||||
}
|
||||
if (messages[previousMessageIndex] === '/shrug') {
|
||||
cy.findByTestId('reply_textbox').click();
|
||||
}
|
||||
cy.findByTestId('reply_textbox').cmdOrCtrlShortcut('{uparrow}');
|
||||
|
||||
// * Check if the message is equal to the last message
|
||||
cy.findByTestId('reply_textbox').should('have.text', messages[previousMessageIndex]);
|
||||
|
||||
previousMessageIndex--;
|
||||
}
|
||||
|
||||
// * Press CTRL/CMD + downarrow check if the current text is equal to the second message
|
||||
cy.findByTestId('reply_textbox').cmdOrCtrlShortcut('{downarrow}').should('have.text', messages[0]);
|
||||
|
||||
// # Close the RHS
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
|
||||
// * Press CTRL/CMD + uparrow in central textbox check if the text is equal to the last message
|
||||
cy.findByTestId('post_textbox').cmdOrCtrlShortcut('{uparrow}').should('have.text', messages[messages.length - 1]);
|
||||
|
||||
// * Press CTRL/CMD + downarrow in central textbox check if the text is equal to the last message / there is no change in text
|
||||
cy.findByTestId('post_textbox').cmdOrCtrlShortcut('{downarrow}').should('have.text', messages[messages.length - 1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
// # Visit test channel
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1255 CTRL/CMD+UP or DOWN no action on draft post', () => {
|
||||
const message = 'Test message from User 1';
|
||||
|
||||
// # Type a message in the input box but do not post it
|
||||
cy.uiGetPostTextBox().type(message).wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Press CMD/CTRL+DOWN arrow
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{downarrow}');
|
||||
|
||||
// * Check the focus after pressing CTRL/CMD + DOWN then check match the text and the cursor position respectively
|
||||
cy.uiGetPostTextBox().
|
||||
should('be.focused').
|
||||
and('have.text', message).
|
||||
and('have.prop', 'selectionStart', message.length).
|
||||
and('have.prop', 'selectionEnd', message.length);
|
||||
|
||||
// # Press CMD/CTRL+UP arrow
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{uparrow}');
|
||||
|
||||
// * Check the focus after pressing CTRL/CMD + UP then check match the text and the cursor position respectively
|
||||
cy.uiGetPostTextBox().
|
||||
should('be.focused').
|
||||
and('have.text', message).
|
||||
and('have.prop', 'selectionStart', 0).
|
||||
and('have.prop', 'selectionEnd', 0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import {beUnread} from '../../../support/assertions';
|
||||
import {stubClipboard} from '../../../utils';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
const postMessage = 'test for saved post';
|
||||
const postEditMessage = ' POST EDITED';
|
||||
|
||||
before(() => {
|
||||
// # Login as test user and visit off-topic channel
|
||||
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
});
|
||||
cy.postMessage(postMessage);
|
||||
});
|
||||
|
||||
it('MM-T4801 Dot menu keyboard shortcuts', () => {
|
||||
cy.getLastPostId().then((postId) => {
|
||||
stubClipboard().as('clipboard');
|
||||
const permalink = `${Cypress.config('baseUrl')}/${testTeam.name}/pl/${postId}`;
|
||||
|
||||
// # Reply
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Reply', 'R');
|
||||
|
||||
// * Verify reply text box is focused
|
||||
cy.uiGetReplyTextBox().should('be.focused');
|
||||
|
||||
// # Mark as unread
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Mark as Unread', 'U');
|
||||
|
||||
// * Verify the channel is unread in LHS
|
||||
cy.get(`#sidebarItem_${testChannel.name}`).should(beUnread);
|
||||
|
||||
// # Pin Post
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Pin to Channel', 'P');
|
||||
|
||||
// * Verify post is pinned
|
||||
cy.get(`#post_${postId}`).find('.post-pre-header').should('be.visible').and('have.text', 'Pinned');
|
||||
|
||||
// # Unpin Post
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Unpin from Channel', 'P');
|
||||
|
||||
// * Verify post is unpinned
|
||||
cy.get(`#post_${postId}`).and('not.have.text', 'Pinned');
|
||||
|
||||
// # Copy Link
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Copy Link', 'K');
|
||||
|
||||
// * Verify link is copied to the clipboard
|
||||
cy.get('@clipboard').its('contents').should('eq', permalink);
|
||||
|
||||
// # Edit
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Edit', 'E');
|
||||
|
||||
// # add test to the message
|
||||
cy.get('body').type(postEditMessage);
|
||||
cy.get('body').type('{enter}');
|
||||
|
||||
// * Verify edited message
|
||||
cy.uiWaitUntilMessagePostedIncludes(postMessage + postEditMessage);
|
||||
cy.get(`#postMessageText_${postId}`).
|
||||
and('have.text', postMessage + postEditMessage + ' Edited');
|
||||
|
||||
// # Copy Text
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Copy Text', 'C');
|
||||
|
||||
// * Verify message is copied to the clipboard
|
||||
cy.get('@clipboard').its('contents').should('eq', postMessage + postEditMessage);
|
||||
});
|
||||
|
||||
cy.postMessage('message to delete');
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Delete
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Delete', '{del}');
|
||||
cy.findByText('Delete').click();
|
||||
|
||||
// * Verify message was deleted
|
||||
cy.findByText('message to delete').should('not.exist');
|
||||
});
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * verify Save not shown in webview
|
||||
cy.findByText('Save').should('not.exist');
|
||||
|
||||
cy.viewport('iphone-6');
|
||||
|
||||
// # Save Post
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Save', 'S', 'RHS_ROOT');
|
||||
|
||||
// * Verify post is Saved
|
||||
cy.get(`#post_${postId}`).find('.post-pre-header').should('be.visible').and('have.text', 'Saved');
|
||||
|
||||
// # Unsave Post
|
||||
cy.uiPostDropdownMenuShortcut(postId, 'Remove from Saved', 'S', 'RHS_ROOT');
|
||||
|
||||
// * Verify post is unsaved
|
||||
cy.get(`#post_${postId}`).and('not.have.text', 'Saved');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let channelUrl;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
channelUrl = offTopicUrl;
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1244 CTRL/CMD+K - Esc closes modal', () => {
|
||||
const searchTerm = 'test' + Date.now();
|
||||
|
||||
// # Open Channel switcher modal by click on the button
|
||||
cy.findByRole('button', {name: 'Find Channels'}).click();
|
||||
|
||||
// # Type in the quick switch input box
|
||||
cy.get('#quickSwitchInput').typeWithForce(searchTerm);
|
||||
|
||||
// * Verify that the no search result test is displayed
|
||||
cy.get('.no-results__title').should('be.visible').and('have.text', 'No results for "' + searchTerm + '"');
|
||||
|
||||
// # Press escape key
|
||||
cy.get('#quickSwitchInput').typeWithForce('{esc}');
|
||||
|
||||
// * Verify that the modal is closed
|
||||
cy.get('.modal-content').should('not.exist');
|
||||
|
||||
// * Verify that the user does not leave the off-topic channel
|
||||
cy.url().should('contain', channelUrl);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,469 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as messages from '../../../fixtures/messages';
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
testUser = user;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as admin and visit town-square
|
||||
cy.apiAdminLogin();
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
|
||||
it('MM-T1227 - CTRL/CMD+K - Join public channel', () => {
|
||||
// # Type CTRL/CMD+K
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K');
|
||||
|
||||
cy.apiCreateUser({prefix: 'temp-'}).then(({user: tempUser}) => {
|
||||
// # Add user to team but not to test channel
|
||||
cy.apiAddUserToTeam(testTeam.id, tempUser.id);
|
||||
|
||||
// # In the "Switch Channels" modal type the first chars of the test channel name
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).should('be.focused').type(testChannel.name.substring(0, 3)).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Verify that the list of users and channels suggestions is present
|
||||
cy.get('#suggestionList').should('be.visible').within(() => {
|
||||
// * The channel the current user is not a member of should be there in the search list; click it
|
||||
cy.findByTestId(testChannel.name).scrollIntoView().should('exist').click().wait(TIMEOUTS.HALF_SEC);
|
||||
});
|
||||
|
||||
// # Verify that we are in the test channel
|
||||
cy.get('#channelIntro').contains('.channel-intro__title', `Beginning of ${testChannel.display_name}`).should('be.visible');
|
||||
|
||||
// # Verify that the right channel is displayed in LHS
|
||||
cy.uiGetLhsSection('CHANNELS').findByText(testChannel.display_name).should('be.visible');
|
||||
|
||||
// # Verify that the current user(sysadmin) created the channel
|
||||
cy.get('#channelIntro').contains('.channel-intro__content', `This is the start of the ${testChannel.display_name} channel, created by sysadmin`).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1231 - ALT+SHIFT+UP', () => {
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
cy.apiCreateTeam('team1', 'Team1').then(({team}) => {
|
||||
const privateChannels = [];
|
||||
const publicChannels = [];
|
||||
const dmChannels = [];
|
||||
|
||||
// # Create two public channels
|
||||
for (let index = 0; index < 2; index++) {
|
||||
const otherUserId = otherUser.id;
|
||||
cy.apiCreateChannel(team.id, `a-public-${index}`, `A Public ${index}`).then(({channel}) => {
|
||||
publicChannels.push(channel);
|
||||
cy.apiAddUserToTeam(team.id, otherUserId).then(() => {
|
||||
cy.apiAddUserToChannel(channel.id, otherUserId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// # Create two private channels
|
||||
for (let index = 0; index < 2; index++) {
|
||||
const otherUserId = otherUser.id;
|
||||
cy.apiCreateChannel(team.id, `b-private-${index}`, `B Private ${index}`, 'P').then(({channel}) => {
|
||||
privateChannels.push(channel);
|
||||
cy.apiAddUserToChannel(channel.id, otherUserId);
|
||||
});
|
||||
}
|
||||
|
||||
// # Set up DM channel
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).wait(TIMEOUTS.ONE_SEC).then(({channel}) => {
|
||||
dmChannels.push(channel);
|
||||
cy.visit(`/${team.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
cy.uiGetPostTextBox().clear().type(`message from ${testUser.username}`).type('{enter}');
|
||||
});
|
||||
|
||||
// # Add posts by second user to the newly created channels in the first team
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(otherUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
cy.get('#sidebarItem_' + publicChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to public channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + privateChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to private channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + dmChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type(`direct message from ${otherUser.username}`).type('{enter}');
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(testUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
// # Verify that the channels are unread
|
||||
cy.get(`#sidebarItem_${publicChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${privateChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${dmChannels[0].name}`).should('have.class', 'unread-title');
|
||||
|
||||
// # Navigate to the bottom of the list of channels
|
||||
cy.get('#sidebarItem_' + dmChannels[0].name).scrollIntoView().click();
|
||||
cy.get('.active').find('#sidebarItem_' + dmChannels[0].name).should('exist');
|
||||
|
||||
// # Press alt + shift + up
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + privateChannels[0].name).should('exist');
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + publicChannels[0].name).should('exist');
|
||||
|
||||
// # No navigation - stay in place
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + publicChannels[0].name).should('exist');
|
||||
});
|
||||
|
||||
// # Handle favorite channels
|
||||
const favPrivateChannels = [];
|
||||
const favPublicChannels = [];
|
||||
const favDMChannels = [];
|
||||
|
||||
// # Set up public favorite channel
|
||||
cy.apiCreateChannel(team.id, 'public', 'public').then(({channel}) => {
|
||||
favPublicChannels.push(channel);
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
markAsFavorite(channel.name);
|
||||
});
|
||||
|
||||
// # Set up private favorite channel
|
||||
cy.apiCreateChannel(team.id, 'private', 'private', 'P').then(({channel}) => {
|
||||
favPrivateChannels.push(channel);
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
markAsFavorite(channel.name);
|
||||
});
|
||||
|
||||
// # Set up DM favorite channel
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).wait(TIMEOUTS.ONE_SEC).then(({channel}) => {
|
||||
favDMChannels.push(channel);
|
||||
cy.visit(`/${team.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
cy.uiGetPostTextBox().clear().type(`message from ${testUser.username}`).type('{enter}');
|
||||
markAsFavorite(channel.name);
|
||||
});
|
||||
|
||||
// # Add posts by second user to the newly created channels in the first team
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(otherUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
cy.get('#sidebarItem_' + favPublicChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to public channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + favPrivateChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to private channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + favDMChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type(`direct message from ${otherUser.username}`).type('{enter}');
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(testUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
// # Verify that the channels are unread - in the Favorites tab the unread channels are ordered alphabetically
|
||||
cy.get(`#sidebarItem_${favDMChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${favPrivateChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${favPublicChannels[0].name}`).should('have.class', 'unread-title');
|
||||
|
||||
// # Navigate to the middle of the list of unread favorite channels
|
||||
cy.get('#sidebarItem_' + favPrivateChannels[0].name).scrollIntoView().click();
|
||||
cy.get('.active').find('#sidebarItem_' + favPrivateChannels[0].name).should('exist');
|
||||
|
||||
// # Press alt + shift + up
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + favDMChannels[0].name).should('exist');
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + favPublicChannels[0].name).should('exist');
|
||||
|
||||
// # No navigation - stay in place
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + favPublicChannels[0].name).should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1232 - ALT+SHIFT+DOWN', () => {
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
cy.apiCreateTeam('team2', 'Team2').then(({team}) => {
|
||||
const privateChannels = [];
|
||||
const publicChannels = [];
|
||||
const dmChannels = [];
|
||||
|
||||
// # Create two public channels
|
||||
for (let index = 0; index < 2; index++) {
|
||||
const otherUserId = otherUser.id;
|
||||
cy.apiCreateChannel(team.id, `a-public-${index}`, `A Public ${index}`).then(({channel}) => {
|
||||
publicChannels.push(channel);
|
||||
cy.apiAddUserToTeam(team.id, otherUserId).then(() => {
|
||||
cy.apiAddUserToChannel(channel.id, otherUserId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// # Create two private channels
|
||||
for (let index = 0; index < 2; index++) {
|
||||
const otherUserId = otherUser.id;
|
||||
cy.apiCreateChannel(team.id, `b-private-${index}`, `B Private ${index}`).then(({channel}) => {
|
||||
privateChannels.push(channel);
|
||||
cy.apiAddUserToChannel(channel.id, otherUserId);
|
||||
});
|
||||
}
|
||||
|
||||
// # Set up DM channel
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).wait(TIMEOUTS.ONE_SEC).then(({channel}) => {
|
||||
dmChannels.push(channel);
|
||||
cy.visit(`/${team.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
cy.uiGetPostTextBox().clear().type(`message from ${testUser.username}`).type('{enter}');
|
||||
});
|
||||
|
||||
// # Add posts by second user to the newly created channels in the first team
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(otherUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
cy.get('#sidebarItem_' + publicChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to public channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + privateChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to private channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + dmChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type(`direct message from ${otherUser.username}`).type('{enter}');
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(testUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
// # Verify that the channels are unread
|
||||
cy.get(`#sidebarItem_${publicChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${privateChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${dmChannels[0].name}`).should('have.class', 'unread-title');
|
||||
|
||||
// # Navigate to the top of the list of channels
|
||||
cy.get('#sidebarItem_' + publicChannels[0].name).scrollIntoView().click();
|
||||
cy.get('.active').find('#sidebarItem_' + publicChannels[0].name).should('exist');
|
||||
|
||||
// # Press alt + shift + down
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + privateChannels[0].name).should('exist');
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + dmChannels[0].name).should('exist');
|
||||
|
||||
// # No navigation - stay in place
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + dmChannels[0].name).should('exist');
|
||||
});
|
||||
|
||||
// # Handle favorite channels
|
||||
const favPrivateChannels = [];
|
||||
const favPublicChannels = [];
|
||||
const favDMChannels = [];
|
||||
|
||||
// # Set up public favorite channel
|
||||
cy.apiCreateChannel(team.id, 'public', 'public').then(({channel}) => {
|
||||
favPublicChannels.push(channel);
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
markAsFavorite(channel.name);
|
||||
});
|
||||
|
||||
// # Set up private favorite channel
|
||||
cy.apiCreateChannel(team.id, 'private', 'private', 'P').then(({channel}) => {
|
||||
favPrivateChannels.push(channel);
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
markAsFavorite(channel.name);
|
||||
});
|
||||
|
||||
// # Set up DM favorite channel
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).wait(TIMEOUTS.ONE_SEC).then(({channel}) => {
|
||||
favDMChannels.push(channel);
|
||||
cy.visit(`/${team.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
cy.uiGetPostTextBox().clear().type(`message from ${testUser.username}`).type('{enter}');
|
||||
markAsFavorite(channel.name);
|
||||
});
|
||||
|
||||
// # Add posts by second user to the newly created channels in the first team
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(otherUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
cy.get('#sidebarItem_' + favPublicChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to public channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + favPrivateChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type('message to private channel').type('{enter}');
|
||||
|
||||
cy.get('#sidebarItem_' + favDMChannels[0].name).scrollIntoView().click();
|
||||
cy.uiGetPostTextBox().clear().type(`direct message from ${otherUser.username}`).type('{enter}');
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(testUser).then(() => {
|
||||
cy.visit(`/${team.name}/channels/off-topic`);
|
||||
|
||||
// # Verify that the channels are unread - in the Favorites tab the unread channels are ordered alphabetically
|
||||
cy.get(`#sidebarItem_${favDMChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${favPrivateChannels[0].name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${favPublicChannels[0].name}`).should('have.class', 'unread-title');
|
||||
|
||||
// # Navigate to the middle of the list of unread favorite channels
|
||||
cy.get('#sidebarItem_' + favPrivateChannels[0].name).scrollIntoView().click();
|
||||
cy.get('.active').find('#sidebarItem_' + favPrivateChannels[0].name).should('exist');
|
||||
|
||||
// # Press alt + shift + down
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + favPublicChannels[0].name).should('exist');
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + favDMChannels[0].name).should('exist');
|
||||
|
||||
// # No navigation - stay in place
|
||||
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
|
||||
cy.get('.active').find('#sidebarItem_' + favDMChannels[0].name).should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1240 - CTRL/CMD+K: Open and close', () => {
|
||||
// # Type CTRL/CMD+K to open 'Switch Channels' modal
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('K').then(() => {
|
||||
// * Channel switcher hint should be visible and focused on
|
||||
cy.get('#quickSwitchHint').should('be.visible');
|
||||
cy.findByRole('textbox', {name: 'quick switch input'}).should('be.focused');
|
||||
});
|
||||
|
||||
// # Type CTRL/CMD+K to close 'Switch Channels' modal
|
||||
cy.get('body').cmdOrCtrlShortcut('K');
|
||||
cy.get('#quickSwitchHint').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1248 - CTRL/CMD+SHIFT+L - Set focus to center channel message box', () => {
|
||||
// # Open search box to change focus
|
||||
cy.get('#searchBox').click().should('be.focused').then(() => {
|
||||
// # Type CTRL/CMD+SHIFT+L
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}L');
|
||||
cy.uiGetPostTextBox().should('be.focused');
|
||||
});
|
||||
|
||||
// # Post a message and open RHS
|
||||
const message = `hello${Date.now()}`;
|
||||
cy.postMessage(message);
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Mouseover the post and click post comment icon.
|
||||
cy.clickPostCommentIcon(postId);
|
||||
cy.uiGetReplyTextBox().focus().should('be.focused');
|
||||
}).then(() => {
|
||||
// # Type CTRL/CMD+SHIFT+L
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}L');
|
||||
cy.uiGetPostTextBox().should('be.focused');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1252 - CTRL/CMD+SHIFT+A', () => {
|
||||
// # Type CTRL/CMD+SHIFT+A to open 'Profile' modal
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}A');
|
||||
cy.uiGetSettingsModal().should('be.visible');
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+A to close 'Profile' modal
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}A');
|
||||
cy.uiGetSettingsModal().should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1278 - CTRL/CMD+SHIFT+K', () => {
|
||||
// # Type CTRL/CMD+SHIFT+K to open 'Direct Messages' modal
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}K');
|
||||
cy.get('#moreDmModal').should('be.visible').contains('Direct Messages');
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+K to close 'Direct Messages' modal
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}K');
|
||||
cy.get('#moreDmModal').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T4452 - CTRL/CMD+SHIFT+. Expand or collapse RHS when RHS is already open', () => {
|
||||
// # Post a message in center
|
||||
cy.postMessage(messages.TINY);
|
||||
|
||||
// # Mouseover the post and click post comment icon.
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+. to expand 'RHS'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}.');
|
||||
|
||||
// * Verify RHS is now expanded
|
||||
cy.uiGetRHS().isExpanded();
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+. to collapse 'RHS'
|
||||
cy.get('body').cmdOrCtrlShortcut('{shift}.');
|
||||
|
||||
// * Verify RHS is now in collapsed state
|
||||
cy.get('#sidebar-right').should('be.visible').and('not.have.class', 'sidebar--right--expanded');
|
||||
});
|
||||
|
||||
it('MM-T4452 - CTRL/CMD+SHIFT+. Expand or collapse RHS when RHS is in closed state', () => {
|
||||
// # Type CTRL/CMD+SHIFT+. to open 'RHS'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}.');
|
||||
|
||||
// * Verify RHS is now open and is in collapsed state
|
||||
cy.get('#sidebar-right').should('be.visible').and('not.have.class', 'sidebar--right--expanded');
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+. to expand 'RHS'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}.');
|
||||
|
||||
// * Verify RHS is now fully expanded
|
||||
cy.uiGetRHS().isExpanded();
|
||||
|
||||
// # Type CTRL/CMD+SHIFT+. to collapse 'RHS'
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{shift}.');
|
||||
|
||||
// * Verify RHS is now in collapsed state
|
||||
cy.get('#sidebar-right').should('be.visible').and('not.have.class', 'sidebar--right--expanded');
|
||||
});
|
||||
|
||||
function markAsFavorite(channelName) {
|
||||
// # Visit the channel
|
||||
cy.get(`#sidebarItem_${channelName}`).scrollIntoView().click();
|
||||
|
||||
cy.get('#postListContent').should('be.visible');
|
||||
|
||||
// # Remove from Favorites if already set
|
||||
cy.get('#channelHeaderInfo').then((el) => {
|
||||
if (el.find('#toggleFavorite.active').length) {
|
||||
cy.get('#toggleFavorite').click();
|
||||
}
|
||||
});
|
||||
|
||||
// # Mark it as Favorite
|
||||
cy.get('#toggleFavorite').click();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,206 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {isMac} from '../../../utils';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as admin and visit town-square
|
||||
cy.apiAdminLogin();
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
|
||||
it('MM-T1239 - CTRL+/ and CMD+/ and /shortcuts', () => {
|
||||
// # Type CTRL/CMD+/
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('/');
|
||||
|
||||
// # Verify that the 'Keyboard Shortcuts' modal is open
|
||||
modalShouldOpen();
|
||||
|
||||
// # Verify that the 'Keyboard Shortcuts' modal displays the CTRL/CMD+U shortcut
|
||||
cy.get('.section').eq(2).within(() => {
|
||||
cy.findByText('Files').should('be.visible');
|
||||
cy.get('.shortcut-line').should('be.visible').as('shortcutLine');
|
||||
if (isMac()) {
|
||||
cy.get('@shortcutLine').findByText('⌘').should('be.visible');
|
||||
} else {
|
||||
cy.get('@shortcutLine').findByText('Ctrl').should('be.visible');
|
||||
}
|
||||
cy.get('@shortcutLine').findByText('U').should('be.visible');
|
||||
});
|
||||
|
||||
// # Type CTRL/CMD+/ to close the 'Keyboard Shortcuts' modal
|
||||
cy.get('body').cmdOrCtrlShortcut('/');
|
||||
cy.get('#shortcutsModalLabel').should('not.exist');
|
||||
|
||||
// # Type /shortcuts
|
||||
cy.uiGetPostTextBox().clear().type('/shortcuts{enter}');
|
||||
modalShouldOpen();
|
||||
|
||||
// # Close the 'Keyboard Shortcuts' modal using the x button
|
||||
cy.get('.modal-header button.close').should('have.attr', 'aria-label', 'Close').click();
|
||||
cy.get('#shortcutsModalLabel').should('not.exist');
|
||||
|
||||
// # Type /shortcuts
|
||||
cy.uiGetPostTextBox().clear().type('/shortcuts{enter}');
|
||||
|
||||
// # Close the 'Keyboard Shortcuts' modal by pressing ESC key
|
||||
cy.get('body').type('{esc}');
|
||||
cy.get('#shortcutsModalLabel').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1254 - CTRL/CMD+UP; CTRL/CMD+DOWN', () => {
|
||||
const messagePrefix = 'hello from current user: ';
|
||||
let message;
|
||||
const count = 5;
|
||||
|
||||
// # Post messages to the center channel
|
||||
for (let index = 0; index < count; index++) {
|
||||
message = messagePrefix + index;
|
||||
cy.postMessage(message);
|
||||
}
|
||||
|
||||
for (let index = 0; index < count; index++) {
|
||||
// # Type CTRL/CMD+UP
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{uparrow}');
|
||||
|
||||
// # Verify that the previous message is displayed
|
||||
message = messagePrefix + (4 - index);
|
||||
cy.uiGetPostTextBox().contains(message);
|
||||
}
|
||||
|
||||
// # One extra CTRL/CMD+UP does not change the displayed message
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{uparrow}');
|
||||
message = messagePrefix + '0';
|
||||
cy.uiGetPostTextBox().contains(message);
|
||||
|
||||
for (let index = 1; index < count; index++) {
|
||||
// # Type CTRL/CMD+DOWN
|
||||
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{downarrow}');
|
||||
|
||||
// # Verify that the next message is displayed
|
||||
message = messagePrefix + index;
|
||||
cy.uiGetPostTextBox().contains(message);
|
||||
}
|
||||
});
|
||||
|
||||
it('MM-T1260 - UP arrow', () => {
|
||||
const message = 'Test';
|
||||
const editMessage = 'Edit Test';
|
||||
|
||||
// # Post message text
|
||||
cy.uiGetPostTextBox().clear().type(message).type('{enter}').wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Edit previous post
|
||||
cy.getLastPostId().then(() => {
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
// * Edit Post Input should appear
|
||||
cy.get('#edit_textbox').should('be.visible');
|
||||
|
||||
// * Edit to the post message and type ENTER
|
||||
cy.get('#edit_textbox').invoke('val', '').clear().type(editMessage).type('{enter}').wait(TIMEOUTS.HALF_SEC);
|
||||
});
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Post should have "Edited"
|
||||
cy.get(`#postEdited_${postId}`).
|
||||
should('be.visible').
|
||||
should('contain', 'Edited');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1273 - @[character]+TAB', () => {
|
||||
const userName = `${testUser.username}`;
|
||||
|
||||
// # Enter the first characters of a user name
|
||||
cy.uiGetPostTextBox().clear().type('@' + userName.substring(0, 5)).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Select the focused on user from the list using TAB
|
||||
cy.get('#suggestionList').should('be.visible').focused().tab();
|
||||
|
||||
// # Verify that the correct user name has been selected
|
||||
cy.uiGetPostTextBox().should('contain', userName);
|
||||
|
||||
// # Clear the message box
|
||||
cy.uiGetPostTextBox().clear();
|
||||
});
|
||||
|
||||
it('MM-T1274 - :[character]+TAB', () => {
|
||||
const emojiName = ':tomato';
|
||||
|
||||
// # Enter the first characters of an emoji name
|
||||
cy.uiGetPostTextBox().clear().type(emojiName.substring(0, 3)).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Go down the list of emojis
|
||||
cy.get('body').type('{downarrow}').wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{downarrow}').wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{downarrow}').wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('body').type('{downarrow}').wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Select the fourth emoji from the top using TAB
|
||||
cy.get('#suggestionList').should('be.visible').focused().tab();
|
||||
|
||||
// # Verify that the correct selection has been made
|
||||
cy.uiGetPostTextBox().should('contain', emojiName);
|
||||
});
|
||||
|
||||
it('MM-T1275 - SHIFT+UP', () => {
|
||||
const message = `hello${Date.now()}`;
|
||||
|
||||
// # Post message to center channel
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Press SHIFT+UP
|
||||
cy.uiGetPostTextBox().type('{shift}{uparrow}');
|
||||
|
||||
// # Verify that the RHS reply box is focused
|
||||
cy.uiGetReplyTextBox().should('be.focused');
|
||||
|
||||
// * Verify that the recently posted message is shown in the RHS
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#rhsPostMessageText_${postId}`).should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1279 - Keyboard shortcuts menu item', () => {
|
||||
// # Click "Keyboard shortcuts" at help menu
|
||||
cy.uiOpenHelpMenu('Keyboard shortcuts');
|
||||
|
||||
modalShouldOpen();
|
||||
});
|
||||
});
|
||||
|
||||
function modalShouldOpen() {
|
||||
const name = isMac() ? /Keyboard shortcuts ⌘ \// : /Keyboard shortcuts Ctrl \//;
|
||||
cy.findByRole('dialog', {name}).should('be.visible');
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @keyboard_shortcuts
|
||||
|
||||
import {isMac} from '../../../utils';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
const count = 5;
|
||||
const teams = [];
|
||||
const channels = [];
|
||||
|
||||
before(() => {
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
cy.apiLogin(sysadmin);
|
||||
const prefix = 't0';
|
||||
cy.apiInitSetup({teamPrefix: {name: prefix, displayName: prefix}, channelPrefix: {name: prefix, displayName: prefix}}).then(({team, channel}) => {
|
||||
teams.push(team);
|
||||
channels.push(channel);
|
||||
|
||||
cy.visit(`/${team.name}/channels/${channel.name}`);
|
||||
cy.postMessage('hello');
|
||||
|
||||
for (let index = 1; index < count; index++) {
|
||||
const otherPrefix = `t${index}`;
|
||||
|
||||
cy.apiCreateTeam(otherPrefix, otherPrefix).then(({team: otherTeam}) => {
|
||||
teams.push(otherTeam);
|
||||
cy.apiCreateChannel(otherTeam.id, otherPrefix, otherPrefix).then(({channel: otherChannel}) => {
|
||||
channels.push(otherChannel);
|
||||
cy.visit(`/${otherTeam.name}/channels/${otherChannel.name}`);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1575 - Ability to Switch Teams', () => {
|
||||
for (let index = 0; index < count; index++) {
|
||||
// # Verify that we've switched to the correct team
|
||||
cy.uiGetLHSHeader().findByText(teams[count - index - 1].display_name);
|
||||
|
||||
// # Verify that we've switched to the correct channel
|
||||
cy.get('#channelHeaderTitle').should('be.visible').should('contain', channels[count - index - 1].display_name);
|
||||
|
||||
// # Press CTRL/CMD+SHIFT+UP
|
||||
if (isMac()) {
|
||||
cy.get('body').type('{cmd}{option}', {release: false}).type('{uparrow}').type('{cmd}{option}', {release: true});
|
||||
} else {
|
||||
cy.get('body').type('{ctrl}{shift}', {release: false}).type('{uparrow}').type('{ctrl}{shift}', {release: true});
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < count; index++) {
|
||||
// # Press CTRL/CMD+SHIFT+DOWN
|
||||
if (isMac()) {
|
||||
cy.get('body').type('{cmd}{option}', {release: false}).type('{downarrow}').type('{cmd}{option}', {release: true});
|
||||
} else {
|
||||
cy.get('body').type('{ctrl}{shift}', {release: false}).type('{downarrow}').type('{ctrl}{shift}', {release: true});
|
||||
}
|
||||
|
||||
// # Verify that we've switched to the correct team
|
||||
cy.uiGetLHSHeader().findByText(teams[index].display_name);
|
||||
|
||||
// # Verify that we've switched to the correct channel
|
||||
cy.get('#channelHeaderTitle').should('be.visible').should('contain', channels[index].display_name);
|
||||
}
|
||||
|
||||
for (let index = 1; index <= count; index++) {
|
||||
// # Press CTRL/CMD+SHIFT+index
|
||||
if (isMac()) {
|
||||
cy.get('body').type('{cmd}{option}', {release: false}).type(String(index)).type('{cmd}{option}', {release: true});
|
||||
} else {
|
||||
cy.get('body').type('{ctrl}{shift}', {release: false}).type(String(index)).type('{ctrl}{shift}', {release: true});
|
||||
}
|
||||
|
||||
// # Verify that we've switched to the correct team
|
||||
cy.uiGetLHSHeader().findByText(teams[index - 1].display_name);
|
||||
|
||||
// # Verify that we've switched to the correct channel
|
||||
cy.get('#channelHeaderTitle').should('be.visible').should('contain', channels[index - 1].display_name);
|
||||
}
|
||||
|
||||
// # Verify keyboard shortcuts in Keyboard Shortcuts modal
|
||||
cy.uiOpenHelpMenu('Keyboard shortcuts');
|
||||
const name = isMac() ? /Keyboard Shortcuts ⌘ \// : /Keyboard Shortcuts Ctrl \//;
|
||||
cy.findByRole('dialog', {name}).within(() => {
|
||||
cy.findByText('Navigation').should('be.visible');
|
||||
cy.findByText('Previous team:').should('be.visible');
|
||||
cy.findAllByText('Next team:').should('be.visible');
|
||||
cy.findAllByText('Navigate to a specific team:').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
// # Visit a test channel
|
||||
cy.visit(offTopicUrl);
|
||||
cy.postMessage('Hello World');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1277 SHIFT+UP', () => {
|
||||
// # Press shift+up to open the latest thread in the channel in the RHS
|
||||
cy.uiGetPostTextBox().type('{shift}{uparrow}');
|
||||
|
||||
// * RHS Opens up
|
||||
cy.get('.sidebar--right__header').should('be.visible');
|
||||
|
||||
// * RHS textbox should be focused
|
||||
cy.uiGetReplyTextBox().should('be.focused');
|
||||
|
||||
// # Click into the post textbox in the center channel
|
||||
cy.uiGetPostTextBox().click();
|
||||
|
||||
// # Press shift+up again
|
||||
cy.uiGetPostTextBox().type('{shift}{uparrow}');
|
||||
|
||||
// * RHS textbox should be focused
|
||||
cy.uiGetReplyTextBox().should('be.focused');
|
||||
});
|
||||
});
|
||||
@@ -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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
// # Visit off-topic channel
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1265 UP - System message does not open for edit; opens previous regular message', () => {
|
||||
const message = 'Test message';
|
||||
const newHeader = 'New Header';
|
||||
|
||||
// # Post message in the channel from User
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Open the edit the channel header modal
|
||||
cy.findByRole('button', {name: 'Set a Header dialog'}).click();
|
||||
|
||||
// * Verify modal is open
|
||||
cy.findByRole('dialog', {name: 'Edit Header for Off-Topic'}).within(() => {
|
||||
// # Enter new header and save
|
||||
cy.findByRole('textbox', {name: 'edit the channel header...'}).type(newHeader);
|
||||
cy.uiSave();
|
||||
});
|
||||
|
||||
// * Wait for the system message to be posted
|
||||
cy.uiWaitUntilMessagePostedIncludes(newHeader);
|
||||
|
||||
// # Press UP arrow
|
||||
cy.findByTestId('post_textbox').
|
||||
type('{uparrow}');
|
||||
|
||||
// * Verify that the Edit Post Input is visible
|
||||
cy.get('#edit_textbox').
|
||||
should('be.visible').
|
||||
should('have.text', message);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
|
||||
// # Visit a test channel
|
||||
cy.visit(channelUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1261 UP arrow', () => {
|
||||
cy.postMessage('Hello World');
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Add a reply message, to have RHS container open
|
||||
cy.clickPostDotMenu(postId);
|
||||
cy.findByText('Reply').click();
|
||||
const replyMessage = 'Well, hello there.';
|
||||
cy.uiGetReplyTextBox().type(replyMessage);
|
||||
cy.uiGetReplyTextBox().type('{enter}');
|
||||
cy.uiWaitUntilMessagePostedIncludes(replyMessage);
|
||||
|
||||
// # Press up arrow key
|
||||
cy.get('body').type('{uparrow}');
|
||||
|
||||
// * Verify that the Edit Post Input is visible
|
||||
cy.get('#edit_textbox').should('be.visible');
|
||||
|
||||
// * Verify that edit box have value of edited message
|
||||
cy.get('#edit_textbox').should('have.value', replyMessage);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,319 @@
|
||||
// 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 @keyboard_shortcuts
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Keyboard Shortcuts', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
testUser = user;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1235 Arrow up key - no Edit modal open up if user has not posted any message yet', () => {
|
||||
const message2 = 'Test message from User 2';
|
||||
|
||||
cy.apiLogin(otherUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post message in the channel from User 2
|
||||
cy.postMessage(message2);
|
||||
cy.apiLogout();
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Press UP arrow
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
// * Verify that Edit modal should not be visible
|
||||
cy.get('#edit_textbox').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1236 Arrow up key - Edit Input opens up for own message of a user', () => {
|
||||
const message1 = 'Test message from User 1';
|
||||
const message2 = 'Test message from User 2';
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post message in the channel from User 1
|
||||
cy.postMessage(message1);
|
||||
cy.apiLogout();
|
||||
|
||||
cy.apiLogin(otherUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post message in the channel from User 2
|
||||
cy.postMessage(message2);
|
||||
cy.apiLogout();
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Press UP arrow
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
// * Verify that the Edit Post Input is visible
|
||||
cy.get('#edit_textbox').should('be.visible');
|
||||
|
||||
// * Verify that the Edit textbox contains previously sent message by user 1
|
||||
cy.get('#edit_textbox').should('have.text', message1);
|
||||
});
|
||||
|
||||
it('MM-T1271_1 UP - Removing all text in edit deletes post if without attachment', () => {
|
||||
const message = 'Message to be deleted';
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post message
|
||||
cy.postMessage(message);
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
|
||||
cy.getLastPostId().then((postID) => {
|
||||
// * Verify that testuser sees post
|
||||
cy.get(`#postMessageText_${postID}`).should('contain', message);
|
||||
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
// * Validate that edit box contains just posted message
|
||||
cy.get('#edit_textbox').should('have.text', message);
|
||||
|
||||
// # Clear all text, delete and confirm by pressing enter
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#edit_textbox').clear().type('{enter}');
|
||||
|
||||
// * Verify confirm modal is shown
|
||||
cy.findByRole('dialog', {name: 'Confirm Post Delete'}).should('be.visible');
|
||||
|
||||
// # Press enter on confirm dialog
|
||||
cy.uiGetButton('Delete').click();
|
||||
|
||||
// * Verify post is deleted
|
||||
cy.get(`#postMessageText_${postID}`).should('not.exist');
|
||||
});
|
||||
|
||||
// # Post message as other user
|
||||
cy.postMessageAs({sender: otherUser, message, channelId: testChannel.id});
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
cy.getLastPostId().then((postID) => {
|
||||
cy.get(`#postMessageText_${postID}`).should('contain', message);
|
||||
|
||||
// # Delete message as test user
|
||||
cy.externalRequest({user: otherUser, method: 'DELETE', path: `posts/${postID}`});
|
||||
|
||||
// * Verify that other user sees that message is deleted
|
||||
cy.get(`#post_${postID} #${postID}_message`).should('have.text', '(message deleted)');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1271_2 UP - Removing all text in edit does not delete post if with attachment', () => {
|
||||
const message = 'This is a message';
|
||||
const filename = 'mattermost-icon.png';
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post message with attachment
|
||||
cy.get('#fileUploadInput').attachFile(filename);
|
||||
cy.postMessage(message);
|
||||
|
||||
// * Verify that the message and file attachment is posted
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
cy.uiGetFileThumbnail(filename).should('be.visible');
|
||||
|
||||
// # Press up arrow
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Clear all text and confirm
|
||||
cy.get('#edit_textbox').clear().type('{enter}');
|
||||
|
||||
// * Delete post confirm modal should not exist
|
||||
cy.get('#deletePostModal').should('not.exist');
|
||||
|
||||
// * Verify that attachment is still visible
|
||||
cy.uiGetFileThumbnail(filename).should('be.visible');
|
||||
|
||||
// * Post should contain edited tag
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Post should have "Edited"
|
||||
cy.get(`#postEdited_${postId}`).
|
||||
should('be.visible').
|
||||
should('contain', 'Edited');
|
||||
});
|
||||
|
||||
// # Login with other user
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(otherUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// * Verify that attachment is still visible
|
||||
cy.uiGetFileThumbnail(filename).should('be.visible');
|
||||
|
||||
// * Post should contain edited tag
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Post should have "Edited"
|
||||
cy.get(`#postEdited_${postId}`).
|
||||
should('be.visible').
|
||||
should('contain', 'Edited');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1272 Arrow up key - Removing all text in edit deletes reply', () => {
|
||||
const message = 'Test message from User 1';
|
||||
const reply = 'Reply from User 1';
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post message in the channel from User 1
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Reply to message
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
cy.postMessageReplyInRHS(reply);
|
||||
});
|
||||
|
||||
cy.getLastPostId().then((postID) => {
|
||||
// # Press UP arrow
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Clear message and type ENTER
|
||||
cy.get('#edit_textbox').clear().type('{enter}');
|
||||
|
||||
// * Delete post confirmation modal should be visible
|
||||
cy.get('#deletePostModal').should('be.visible');
|
||||
|
||||
// # Confirm delete
|
||||
cy.get('#deletePostModalButton').click();
|
||||
|
||||
// * Assert post message disappears
|
||||
cy.get(`#postMessageText_${postID}`).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1269 Arrow up key - Edit code block', () => {
|
||||
const messageWithCodeblock1 = '```{shift}{enter}codeblock1{shift}{enter}```{shift}{enter}';
|
||||
const messageWithCodeblock2 = '```{shift}{enter}codeblock2{shift}{enter}```{shift}{enter}';
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Post code block message from User 1
|
||||
cy.uiGetPostTextBox().type(messageWithCodeblock1).type('{enter}');
|
||||
|
||||
cy.uiWaitUntilMessagePostedIncludes('codeblock1');
|
||||
|
||||
// # Press UP arrow
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
// # Edit text
|
||||
cy.get('#edit_textbox').clear().type(messageWithCodeblock2).type('{enter}');
|
||||
|
||||
// * Verify that the message was edited
|
||||
cy.uiWaitUntilMessagePostedIncludes('codeblock2');
|
||||
});
|
||||
|
||||
it('MM-T1264 Arrow up key - Ephemeral message does not open for edit; opens previous regular message', () => {
|
||||
// # Type user message
|
||||
const message = 'Hello World';
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Type "/code" with no text to receive ephemeral message
|
||||
cy.postMessage('/code ');
|
||||
|
||||
// * Verify if an ephemeral message was received
|
||||
cy.findByText('(Only visible to you)').should('exist');
|
||||
cy.findByText('A message must be provided with the /code command.').should('exist');
|
||||
|
||||
// # Press up arrow key
|
||||
cy.get('body').type('{uparrow}');
|
||||
|
||||
// * Verify that the Edit Post Input is visible
|
||||
cy.get('#edit_textbox').should('be.visible');
|
||||
|
||||
// * Verify that edit box have value of previous regular message
|
||||
cy.get('#edit_textbox').should('have.value', message);
|
||||
});
|
||||
|
||||
it('MM-T1270 UP - Edit message with attachment but no text', () => {
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Upload file
|
||||
cy.get('#fileUploadInput').attachFile('mattermost-icon.png');
|
||||
|
||||
// # Wait for file to upload
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
|
||||
cy.uiGetPostTextBox().type('{enter}');
|
||||
|
||||
cy.getLastPost().within(() => {
|
||||
// * Attachment should exist
|
||||
cy.get('.file-view--single').should('exist');
|
||||
|
||||
// * Edited indicator should not exist
|
||||
cy.get('.post-edited__indicator').should('not.exist');
|
||||
});
|
||||
|
||||
// # Press UP arrow
|
||||
cy.uiGetPostTextBox().type('{uparrow}');
|
||||
|
||||
// # Add some text to the previous message and save
|
||||
cy.get('#edit_textbox').type('Test').type('{enter}');
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
cy.getLastPost().within(() => {
|
||||
// * Posted message should be correct
|
||||
cy.get('.post-message__text').should('contain.text', 'Test');
|
||||
|
||||
// * Attachment should exist
|
||||
cy.get('.file-view--single').should('exist');
|
||||
|
||||
// * Edited indicator should exist
|
||||
cy.get('.post-edited__indicator').should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
Ссылка в новой задаче
Block a user