Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,182 @@
|
||||
// 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 @integrations
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import {getRandomId} from '../../../../utils';
|
||||
|
||||
import {verifyEphemeralMessage} from './helper';
|
||||
|
||||
describe('Integrations', () => {
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let offTopicUrl;
|
||||
let channelUrl;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then((out) => {
|
||||
testUser = out.user;
|
||||
offTopicUrl = out.offTopicUrl;
|
||||
channelUrl = out.channelUrl;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user}) => {
|
||||
otherUser = user;
|
||||
|
||||
cy.apiAddUserToTeam(out.team.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(out.channel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit(channelUrl);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
|
||||
it('MM-T573 / autocomplete list can scroll', () => {
|
||||
// # Clear post textbox
|
||||
cy.uiGetPostTextBox().clear().type('/');
|
||||
|
||||
// * Suggestion list should be visible
|
||||
// # Scroll to bottom and verify that the last command "/shrug" is visible
|
||||
cy.get('#suggestionList', {timeout: TIMEOUTS.FIVE_SEC}).should('be.visible').scrollTo('bottom').then((container) => {
|
||||
cy.contains('/away', {container}).should('not.be.visible');
|
||||
cy.contains('/shrug [message]', {container}).should('be.visible');
|
||||
});
|
||||
|
||||
// # Scroll to top and verify that the first command "/away" is visible
|
||||
cy.get('#suggestionList').scrollTo('top').then((container) => {
|
||||
cy.contains('/away', {container}).should('be.visible');
|
||||
cy.contains('/shrug [message]', {container}).should('not.be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T678 /code', () => {
|
||||
const message = '1. Not a list item, **not bolded**, http://notalink.com, ~off-topic is not a link to the channel.';
|
||||
|
||||
// # Use "/code"
|
||||
cy.postMessage(`/code ${message} `);
|
||||
|
||||
// * Verify that that markdown isn't rendered
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).find('.user-popover').should('have.text', testUser.username);
|
||||
cy.get(`#postMessageText_${postId}`).get('code').should('contain', message);
|
||||
});
|
||||
|
||||
// # Type "/code" with no text
|
||||
cy.postMessage('/code ');
|
||||
|
||||
// * Verify that an error message is shown
|
||||
verifyEphemeralMessage('A message must be provided with the /code command.');
|
||||
});
|
||||
|
||||
it('MM-T679 /echo', () => {
|
||||
const message = getRandomId();
|
||||
|
||||
// # Type "/echo message 3"
|
||||
cy.uiGetPostTextBox().clear().type(`/echo ${message} 3{enter}`);
|
||||
|
||||
// * Verify that post is not shown after 1 second
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
cy.getLastPost().within(() => {
|
||||
cy.findByText(message).should('not.exist');
|
||||
});
|
||||
|
||||
// * Verify that message is posted after 3 seconds
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
cy.getLastPost().within(() => {
|
||||
cy.findByText(testUser.username);
|
||||
cy.findByText(message);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T680 /help', () => {
|
||||
// # Type "/help"
|
||||
cy.postMessage('/help ');
|
||||
|
||||
// # get last posted message
|
||||
cy.wait(TIMEOUTS.HALF_SEC).getLastPostId().then((botLastPostId) => {
|
||||
cy.get(`#post_${botLastPostId}`).within(() => {
|
||||
// * Check if Bot message only visible to you
|
||||
cy.findByText('(Only visible to you)').should('exist');
|
||||
|
||||
// * Check if we got ephemeral message of our selection
|
||||
cy.contains('Mattermost is an open source platform for secure communication').should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T681 /invite_people error message with no text or text that is not an email address', () => {
|
||||
// # Type "/invite_people 123"
|
||||
cy.postMessage('/invite_people 123');
|
||||
|
||||
// * Verify the message is shown saying "Please specify one or more valid email addresses"
|
||||
verifyEphemeralMessage('Please specify one or more valid email addresses');
|
||||
});
|
||||
|
||||
it('MM-T682 /leave', () => {
|
||||
// # Go to Off-Topic
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Type "/leave"
|
||||
cy.postMessage('/leave ');
|
||||
|
||||
// * Verity Off-Topic is not shown in LHS
|
||||
cy.get('#sidebar-left').should('be.visible').should('not.contain', 'Off-Topic');
|
||||
|
||||
// * Verify user is redirected to Town Square
|
||||
cy.uiGetLhsSection('CHANNELS').find('.active').should('contain', 'Town Square');
|
||||
cy.get('#channelHeaderTitle').should('be.visible').should('contain', 'Town Square');
|
||||
});
|
||||
|
||||
it('MM-T574 /shrug test', () => {
|
||||
// # Login as otherUser and post a message
|
||||
cy.getCurrentChannelId().then((channelId) => {
|
||||
cy.postMessageAs({sender: otherUser, message: 'hello from otherUser', channelId});
|
||||
});
|
||||
|
||||
const message = getRandomId();
|
||||
|
||||
// # Post "/shrug test" as testUser
|
||||
cy.postMessage(`/shrug ${message} `);
|
||||
|
||||
// * Verify that it posted message as expected from testUser
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).find('.user-popover').should('have.text', testUser.username);
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', `${message} ¯\\_(ツ)_/¯`);
|
||||
});
|
||||
|
||||
// * Login as otherUser and verify that it read the same message as expected from testUser
|
||||
cy.apiLogin(otherUser);
|
||||
cy.visit(channelUrl);
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).find('.user-popover').should('have.text', testUser.username);
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', `${message} ¯\\_(ツ)_/¯`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T5100 /marketplace test', () => {
|
||||
cy.apiAdminLogin();
|
||||
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
// # Go to town square
|
||||
cy.visit(`/${team.name}/channels/town-square`);
|
||||
|
||||
// # Post "/marketplace" as SystemAdmin
|
||||
cy.postMessage('/marketplace ');
|
||||
|
||||
cy.get('#modal_marketplace').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,150 @@
|
||||
// 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 @integrations
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import {getRandomId} from '../../../../utils';
|
||||
|
||||
describe('Integrations', () => {
|
||||
let testUser;
|
||||
let testChannel;
|
||||
let otherChannel;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup({userPrefix: 'testUser'}).then(({team, user, channel}) => {
|
||||
testUser = user;
|
||||
testChannel = channel;
|
||||
|
||||
cy.apiCreateChannel(team.id, 'other-channel', 'Other Channel').then((out) => {
|
||||
otherChannel = out.channel;
|
||||
});
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit('/');
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('#sidebarItem_off-topic').click();
|
||||
cy.uiGetPostTextBox();
|
||||
});
|
||||
|
||||
it('MM-T683 /join', () => {
|
||||
// # Type "/join ~new-channel"
|
||||
cy.postMessage(`/join ~${otherChannel.name} `);
|
||||
|
||||
// * Verify user is redirected to New Channel
|
||||
cy.get('#channelHeaderTitle').should('be.visible').should('contain', otherChannel.display_name);
|
||||
});
|
||||
|
||||
it('MM-T684 /me', () => {
|
||||
// # Type "/me message"
|
||||
const message = getRandomId();
|
||||
cy.postMessage(`/me ${message}`);
|
||||
|
||||
// * Verify a message is posted
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).find('.user-popover').should('have.text', testUser.username);
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', message);
|
||||
|
||||
// * The message should match other system message formatting.
|
||||
cy.get(`#post_${postId}`).should('have.class', 'post--system');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T685 /me not case-sensitive', () => {
|
||||
// # Type "/Me message"
|
||||
const message = getRandomId();
|
||||
cy.postMessage(`/Me ${message}`);
|
||||
|
||||
// * Verify a message is posted
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).find('.user-popover').should('have.text', testUser.username);
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', message);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2345 /me on RHS', () => {
|
||||
cy.get(`#sidebarItem_${testChannel.name}`).click();
|
||||
cy.get('#channelHeaderTitle').should('be.visible').should('contain', testChannel.display_name);
|
||||
|
||||
const rootMessage = 'root message';
|
||||
cy.postMessage(rootMessage);
|
||||
|
||||
// # Open RHS (reply thread)
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Verify the message, both in RHS and center, is from current user
|
||||
// and formatted with full opacity
|
||||
[`#rhsPost_${postId}`, `#post_${postId}`].forEach((selector) => {
|
||||
cy.get(selector).should('have.class', 'current--user').within(() => {
|
||||
cy.get('.post__header').findByText(testUser.username);
|
||||
cy.get('.post-message__text').findByText(rootMessage).should('have.css', 'color', 'rgb(63, 67, 80)');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// # type /me message
|
||||
const message = 'reply';
|
||||
cy.postMessageReplyInRHS(`/me ${message} `);
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Verify the message reply, both in RHS and center, is from current user and formatted with lower opacity
|
||||
[`#rhsPost_${postId}`, `#post_${postId}`].forEach((selector) => {
|
||||
cy.get(selector).should('have.class', 'current--user').within(() => {
|
||||
cy.get('.profile-icon').should('not.be.visible');
|
||||
cy.get('.post-message__text').findByText(message).should('have.css', 'color', 'rgba(63, 67, 80, 0.6)');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T710 /mute error message', () => {
|
||||
const invalidChannel = `invalid-channel-${getRandomId()}`;
|
||||
|
||||
// # Type /mute with random characters
|
||||
cy.postMessage(`/mute ${invalidChannel} `);
|
||||
cy.uiWaitUntilMessagePostedIncludes('Please use the channel handle to identify channels');
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// * Should return an error message
|
||||
cy.get(`#postMessageText_${postId}`).
|
||||
should('have.text', `Could not find the channel ${invalidChannel}. Please use the channel handle to identify channels.`).
|
||||
|
||||
// * Channel handle links to: https://docs.mattermost.com/messaging/managing-channels.html#naming-a-channel
|
||||
contains('a', 'channel handle').then((link) => {
|
||||
const href = link.prop('href');
|
||||
cy.request(href).its('allRequestResponses').then((response) => {
|
||||
cy.wrap(response[0]['Request URL']).should('equal', 'https://docs.mattermost.com/messaging/managing-channels.html#naming-a-channel');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2834 Slash command help stays visible for system slash command', () => {
|
||||
// # Type the rename slash command in textbox
|
||||
cy.uiGetPostTextBox().clear().type('/rename ');
|
||||
|
||||
// # Scan inside of suggestion list
|
||||
cy.get('#suggestionList').should('exist').and('be.visible').within(() => {
|
||||
// * Verify that renaming part of rename autosuggestion is still
|
||||
// visible in the autocomplete, since [text] is same as description and title, we will check if title exists
|
||||
cy.findAllByText('[text]').first().should('exist');
|
||||
});
|
||||
|
||||
// # Append Hello to /rename and hit enter
|
||||
cy.uiGetPostTextBox().type('Hello{enter}').wait(TIMEOUTS.HALF_SEC);
|
||||
cy.uiGetPostTextBox().invoke('text').should('be.empty');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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 @integrations
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Integrations', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(() => {
|
||||
cy.visit('/');
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
});
|
||||
|
||||
// This test was moved here since Cypress is behaving differently as compared to browser
|
||||
// and kept redirecting into the landing page even if the corresponding localstorage is already set.
|
||||
it('MM-T686 /logout', () => {
|
||||
// # Type "/logout"
|
||||
cy.uiGetPostTextBox().should('be.visible').clear().type('/logout {enter}').wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Ensure that the user was redirected to the login page
|
||||
cy.url().should('include', '/login');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,142 @@
|
||||
// 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 @integrations
|
||||
|
||||
import {getRandomId} from '../../../../utils';
|
||||
|
||||
import {loginAndVisitChannel} from './helper';
|
||||
|
||||
describe('Integrations', () => {
|
||||
let testUser;
|
||||
const userGroup = [];
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
offTopicUrl = url;
|
||||
|
||||
Cypress._.times(8, () => {
|
||||
cy.apiCreateUser().then(({user: otherUser}) => {
|
||||
cy.apiAddUserToTeam(team.id, otherUser.id);
|
||||
userGroup.push(otherUser);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T664 /groupmsg initial tests', () => {
|
||||
function verifyPostedMessage(message, usernames) {
|
||||
// * Verify that the channel header contains each group member
|
||||
usernames.forEach((username) => {
|
||||
cy.contains('.channel-header__top', username).should('be.visible');
|
||||
});
|
||||
|
||||
// * Verify that the message is posted into the GM channel
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', message);
|
||||
});
|
||||
|
||||
// # Go back to off-topic channel
|
||||
cy.uiGetLhsSection('CHANNELS').findByText('Off-Topic').click();
|
||||
}
|
||||
|
||||
loginAndVisitChannel(testUser, offTopicUrl);
|
||||
|
||||
const usernames1 = Cypress._.map(userGroup, 'username').slice(0, 4);
|
||||
const usernames1Format = [
|
||||
`@${usernames1[0]},@${usernames1[1]},@${usernames1[2]},@${usernames1[3]}`, // Regular usernames format
|
||||
`${usernames1[0]}, @${usernames1[1]} , ${usernames1[2]} , @${usernames1[3]}`, // Irregular usernames format
|
||||
];
|
||||
|
||||
usernames1Format.forEach((users) => {
|
||||
const message = getRandomId();
|
||||
|
||||
// # Use /groupmsg command to send group message - "/groupmsg [usernames] [message]"
|
||||
cy.postMessage(`/groupmsg ${users} ${message}`);
|
||||
|
||||
// * Verify it redirects into the GM channel with new message posted.
|
||||
verifyPostedMessage(message, usernames1);
|
||||
|
||||
// # Use /groupmsg command to send message to existing GM - "group msg [usernames]" (note: no message)
|
||||
cy.postMessage(`/groupmsg ${users} `);
|
||||
|
||||
// * Verify it redirects into the GM channel without new message posted.
|
||||
verifyPostedMessage(message, usernames1);
|
||||
});
|
||||
|
||||
const usernames2 = Cypress._.map(userGroup, 'username').slice(1, 5);
|
||||
const usernames2Format = [
|
||||
`@${usernames2[0]}, @${usernames2[1]}, @${usernames2[2]}, @${usernames2[3]}`, // Regular usernames format
|
||||
`${usernames2[0]}, @${usernames2[1]} , ${usernames2[2]} , @${usernames2[3]}`, // Irregular usernames format
|
||||
];
|
||||
|
||||
usernames2Format.forEach((users) => {
|
||||
// # Use /groupmsg command to create GM - "group msg [usernames]" (note: no message)
|
||||
cy.postMessage(`/groupmsg ${users} `);
|
||||
|
||||
// * Verify that the channel header contains each group member
|
||||
usernames2.forEach((username) => {
|
||||
cy.contains('.channel-header__top', username).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T665 /groupmsg with users only and without message', () => {
|
||||
loginAndVisitChannel(testUser, offTopicUrl);
|
||||
|
||||
// # Use /groupmsg command to open group message - "/groupmsg [usernames]"
|
||||
const usernames = Cypress._.map(userGroup, 'username').slice(0, 3);
|
||||
const message = '/groupmsg @' + usernames.join(', @') + ' ';
|
||||
cy.postMessage(message);
|
||||
|
||||
// * Verify that the channel header contains each group member
|
||||
usernames.forEach((username) => {
|
||||
cy.contains('.channel-header__top', username).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T666 /groupmsg error if messaging more than 7 users', () => {
|
||||
loginAndVisitChannel(testUser, offTopicUrl);
|
||||
|
||||
// # Include more than 7 valid users in the command
|
||||
const usernames = Cypress._.map(userGroup, 'username');
|
||||
const message = '/groupmsg @' + usernames.join(', @') + ' hello';
|
||||
cy.postMessage(message);
|
||||
|
||||
// * If adding more than 7 users (excluding current user), system message saying "Group messages are limited to a maximum of 7 users."
|
||||
cy.uiWaitUntilMessagePostedIncludes('Group messages are limited to a maximum of 7 users');
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', 'Group messages are limited to a maximum of 7 users.');
|
||||
});
|
||||
|
||||
// # Include one invalid user in the command
|
||||
const message2 = '/groupmsg @' + usernames.slice(0, 2).join(', @') + ', @hello again';
|
||||
cy.postMessage(message2);
|
||||
|
||||
// * If users cannot be found, returns error that user could not be found
|
||||
cy.uiWaitUntilMessagePostedIncludes('Unable to find the user: @hello');
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', 'Unable to find the user: @hello');
|
||||
});
|
||||
|
||||
// # Include more than one invalid user in the command
|
||||
const message3 = '/groupmsg @' + usernames.slice(0, 2).join(', @') + ', @hello, @world again';
|
||||
cy.postMessage(message3);
|
||||
|
||||
// * If users cannot be found, returns error that user could not be found
|
||||
cy.uiWaitUntilMessagePostedIncludes('Unable to find the users: @hello, @world');
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', 'Unable to find the users: @hello, @world');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
export function loginAndVisitChannel(user, channelUrl) {
|
||||
cy.apiLogin(user);
|
||||
cy.visit(channelUrl);
|
||||
|
||||
cy.get('#postListContent', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
cy.uiGetPostTextBox();
|
||||
}
|
||||
|
||||
export function verifyEphemeralMessage(message) {
|
||||
// # Checking if we got the ephemeral message with the selection we made
|
||||
cy.wait(TIMEOUTS.HALF_SEC).getLastPostId().then((botLastPostId) => {
|
||||
cy.get(`#post_${botLastPostId}`).within(() => {
|
||||
// * Check if Bot message only visible to you
|
||||
cy.findByText('(Only visible to you)').should('exist');
|
||||
|
||||
// * Check if we got ephemeral message of our selection
|
||||
cy.findByText(message).should('exist');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @integrations
|
||||
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
describe('Invalid slash command', () => {
|
||||
const incorrectCommand1 = 'notacommand-1';
|
||||
const incorrectCommand2 = 'notacommand-2';
|
||||
const incorrectCommand3 = 'notacommand-3';
|
||||
|
||||
before(() => {
|
||||
// # Login as test user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
cy.visit(offTopicUrl);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T667 - Start message with slash and non-command', () => {
|
||||
// # Type a incorrect slash command and press enter
|
||||
cy.uiGetPostTextBox().type(`/${incorrectCommand1} {enter}`);
|
||||
|
||||
// * Check that error message of incorrect command is displayed
|
||||
verifyNonCommandErrorMessageIsDisplayed(incorrectCommand1);
|
||||
|
||||
// * Check that focus is still the center textbox
|
||||
cy.focused().should('have.id', 'post_textbox');
|
||||
|
||||
// # Backspace in the center textbox and verify error message disappeared
|
||||
cy.uiGetPostTextBox().type('{backspace}');
|
||||
verifyNonCommandErrorMessageIsNotDisplayed(incorrectCommand1);
|
||||
|
||||
// # Type another incorrect slash command
|
||||
cy.uiGetPostTextBox().clear().type(`/${incorrectCommand2} {enter}`);
|
||||
|
||||
// * Check that error message of incorrect command is displayed again
|
||||
verifyNonCommandErrorMessageIsDisplayed(incorrectCommand2);
|
||||
|
||||
// # Click on the link to post incorrect command as plain text
|
||||
cy.findByText('Click here to send as a message.').click({force: true});
|
||||
|
||||
// * Verify the incorrect command is posted as plain text when we pressed 'click here to send as message' link
|
||||
verifyLastPostedMessageContainsPlainTextOfCommand(incorrectCommand2);
|
||||
|
||||
// # Lets try to post incorrect message as plain text via twice enter press
|
||||
cy.uiGetPostTextBox().clear().type(`/${incorrectCommand3} {enter}`);
|
||||
|
||||
// * Check that error message of incorrect command is displayed again
|
||||
verifyNonCommandErrorMessageIsDisplayed(incorrectCommand3);
|
||||
|
||||
// # Lets press enter again in the textbox after error message is shown to submit command as plain text
|
||||
cy.uiGetPostTextBox().type('{enter}');
|
||||
|
||||
// * Verify incorrect command got posted as plain text message via twice enter press
|
||||
verifyLastPostedMessageContainsPlainTextOfCommand(incorrectCommand3);
|
||||
});
|
||||
|
||||
it('MM-T668 Start reply with slash and non-command', () => {
|
||||
// # Post a message in the center text plane
|
||||
cy.postMessage(MESSAGES.SMALL);
|
||||
|
||||
// # To the last message post a reply in RHS
|
||||
cy.getLastPostId().then((lastPostID) => {
|
||||
cy.clickPostCommentIcon(lastPostID);
|
||||
cy.postMessageReplyInRHS(MESSAGES.TINY);
|
||||
});
|
||||
|
||||
// # Type a incorrect slash command and press enter in RHS
|
||||
cy.uiGetReplyTextBox().type(`/${incorrectCommand1} {enter}`);
|
||||
|
||||
// # Move the text search for error inside the RHS container only, so we are certain it is rendered below RHS textbox
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
// * Check that error message of incorrect command is displayed
|
||||
verifyNonCommandErrorMessageIsDisplayed(incorrectCommand1);
|
||||
});
|
||||
|
||||
// * Check that the focus is still the RHS textbox and not in the center textbox
|
||||
cy.focused().
|
||||
should('have.id', 'reply_textbox').
|
||||
and('not.have.id', 'post_textbox');
|
||||
|
||||
// * Verify hitting backspace in the textbox removes the error message
|
||||
cy.uiGetReplyTextBox().type('{backspace}');
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
// * Verify error message is not displayed
|
||||
verifyNonCommandErrorMessageIsNotDisplayed(incorrectCommand1);
|
||||
});
|
||||
|
||||
// # Press enter once with incorrect to allow the error message to show
|
||||
cy.uiGetReplyTextBox().clear().type(`/${incorrectCommand2} {enter}`);
|
||||
|
||||
// * Check that error message of incorrect command is displayed
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
verifyNonCommandErrorMessageIsDisplayed(incorrectCommand2);
|
||||
});
|
||||
|
||||
// # Lets press enter again to submit it as plain text after error message is shown
|
||||
cy.uiGetReplyTextBox().type('{enter}');
|
||||
|
||||
// * Verify incorrect command got posted as plain text message via twice enter press
|
||||
verifyLastPostedMessageContainsPlainTextOfCommand(incorrectCommand2);
|
||||
|
||||
// # Lets add another incorrect command and press enter
|
||||
cy.uiGetReplyTextBox().clear().type(`/${incorrectCommand3} {enter}`);
|
||||
|
||||
// * Check that error message of incorrect command is displayed
|
||||
cy.get('#rhsContainer').within(() => {
|
||||
verifyNonCommandErrorMessageIsDisplayed(incorrectCommand3);
|
||||
});
|
||||
|
||||
// # Click on the link to post incorrect command as plain text below textbox
|
||||
cy.findByText('Click here to send as a message.').should('exist').click({force: true});
|
||||
|
||||
// * Verify incorrect command got posted as plain text message via clicking link
|
||||
verifyLastPostedMessageContainsPlainTextOfCommand(incorrectCommand3);
|
||||
|
||||
// # Close RHS
|
||||
cy.uiCloseRHS();
|
||||
});
|
||||
});
|
||||
|
||||
function verifyNonCommandErrorMessageIsDisplayed(nonCommand) {
|
||||
cy.findByText(`Command with a trigger of '/${nonCommand}' not found.`);
|
||||
cy.findByText('Click here to send as a message.');
|
||||
}
|
||||
|
||||
function verifyNonCommandErrorMessageIsNotDisplayed(nonCommand) {
|
||||
cy.findByText(`Command with a trigger of '/${nonCommand}' not found.`).should('not.exist');
|
||||
cy.findByText('Click here to send as a message.').should('not.exist');
|
||||
}
|
||||
|
||||
function verifyLastPostedMessageContainsPlainTextOfCommand(nonCommand) {
|
||||
// # Get the last posted message
|
||||
cy.getLastPost().within(() => {
|
||||
// * Verify the incorrect command is posted as plain text
|
||||
cy.findByText(`/${nonCommand}`);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
// 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 @integrations
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
import {loginAndVisitChannel} from './helper';
|
||||
|
||||
describe('Integrations', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
const userGroup = [];
|
||||
let testChannel;
|
||||
let testChannelUrl;
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
offTopicUrl = url;
|
||||
|
||||
Cypress._.times(8, () => {
|
||||
cy.apiCreateUser().then(({user: otherUser}) => {
|
||||
cy.apiAddUserToTeam(team.id, otherUser.id);
|
||||
userGroup.push(otherUser);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiCreateChannel(testTeam.id, 'channel', 'channel').then(({channel}) => {
|
||||
testChannel = channel;
|
||||
testChannelUrl = `/${testTeam.name}/channels/${channel.name}`;
|
||||
cy.apiAddUserToChannel(channel.id, testUser.id);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T658 /invite - current channel', () => {
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
return cy.apiDeactivateUser(user.id).then(() => user);
|
||||
}).then((deactivatedUser) => {
|
||||
const userToInvite = userGroup[0];
|
||||
|
||||
loginAndVisitChannel(testUser, testChannelUrl);
|
||||
|
||||
// # Post `/invite @username` where username is a user who is not in the current channel
|
||||
cy.postMessage(`/invite @${userToInvite.username} `);
|
||||
|
||||
// * User who added them sees system message "username added to the channel by you"
|
||||
cy.uiWaitUntilMessagePostedIncludes(`@${userToInvite.username} added to the channel by you`);
|
||||
|
||||
// * Cannot invite deactivated users to a channel
|
||||
cy.postMessage(`/invite @${deactivatedUser.username} `);
|
||||
cy.uiWaitUntilMessagePostedIncludes(`We couldn't find the user ${deactivatedUser.username}. They may have been deactivated by the System Administrator.`);
|
||||
|
||||
cy.apiLogout();
|
||||
loginAndVisitChannel(userToInvite, offTopicUrl);
|
||||
|
||||
// * Added user sees channel added to LHS, mention badge
|
||||
cy.uiGetLhsSection('CHANNELS').
|
||||
findByLabelText(`${testChannel.display_name.toLowerCase()} public channel 1 mention`).
|
||||
should('be.visible').
|
||||
click();
|
||||
|
||||
// * Added user sees system message "username added to the channel by username."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`You were added to the channel by @${testUser.username}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T661 /invite extra white space before @ in DM or GM', () => {
|
||||
const [member1, member2, userToInviteGM, userToInviteDM] = userGroup;
|
||||
|
||||
loginAndVisitChannel(testUser, testChannelUrl);
|
||||
|
||||
// # In a GM use the /invite command to invite a user to a channel you have permission to add them to but place extra white space before the username
|
||||
cy.postMessage(`/groupmsg @${member1.username} @${member2.username} `);
|
||||
cy.postMessage(`/invite @${userToInviteGM.username} ~${testChannel.name} `);
|
||||
|
||||
// * User added to channel as expected
|
||||
cy.uiWaitUntilMessagePostedIncludes(`${userToInviteGM.username} added to ${testChannel.name} channel.`);
|
||||
|
||||
cy.uiAddDirectMessage().click();
|
||||
cy.get('#selectItems input').typeWithForce(userToInviteDM.username).wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('#multiSelectList').findByText(`@${userToInviteDM.username}`).click();
|
||||
cy.findByText('Go').click();
|
||||
cy.uiGetChannelHeaderButton().contains(userToInviteDM.username);
|
||||
|
||||
// # In a DM use the /invite command to invite a user to a channel you have permission to add them to but place extra white space before the username
|
||||
cy.postMessage(`/invite @${userToInviteDM.username} ~${testChannel.name} `);
|
||||
|
||||
// * User added to channel as expected
|
||||
cy.uiWaitUntilMessagePostedIncludes(`${userToInviteDM.username} added to ${testChannel.name} channel.`);
|
||||
});
|
||||
|
||||
it('MM-T659 /invite - other channel', () => {
|
||||
const userToInvite = userGroup[0];
|
||||
|
||||
loginAndVisitChannel(testUser, offTopicUrl);
|
||||
|
||||
// # Post `/invite @username ~channel` where channel name is a channel you have permission to add members to but not the current channel, and username is a user not in that other channel
|
||||
cy.postMessage(`/invite @${userToInvite.username} ~${testChannel.name} `);
|
||||
|
||||
// * User who added them sees system message "username added to channel."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`${userToInvite.username} added to ${testChannel.name} channel.`);
|
||||
|
||||
cy.apiLogout();
|
||||
loginAndVisitChannel(userToInvite, offTopicUrl);
|
||||
|
||||
// * Added user sees channel added to LHS, mention badge.
|
||||
cy.uiGetLhsSection('CHANNELS').
|
||||
findByLabelText(`${testChannel.display_name.toLowerCase()} public channel 1 mention`).
|
||||
should('be.visible').
|
||||
click();
|
||||
|
||||
// * Added user sees system message "username added to the channel by username."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`You were added to the channel by @${testUser.username}`);
|
||||
});
|
||||
|
||||
it('MM-T660_1 /invite tests when used in DMs and GMs', () => {
|
||||
const [member1, member2, userDM] = userGroup;
|
||||
|
||||
loginAndVisitChannel(testUser, testChannelUrl);
|
||||
|
||||
// # In a GM Use the /invite command to invite a channel to another channel (e.g., /invite @[channel name])
|
||||
cy.postMessage(`/groupmsg @${member1.username} @${member2.username} `);
|
||||
cy.postMessage(`/invite @${testChannel.name} `);
|
||||
|
||||
// * Error appears: "We couldn't find the user. They may have been deactivated by the System Administrator."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`We couldn't find the user ${testChannel.name}. They may have been deactivated by the System Administrator.`);
|
||||
|
||||
cy.uiAddDirectMessage().click();
|
||||
cy.get('#selectItems input').typeWithForce(userDM.username).wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('#multiSelectList').findByText(`@${userDM.username}`).click();
|
||||
cy.findByText('Go').click();
|
||||
cy.uiGetChannelHeaderButton().contains(userDM.username);
|
||||
|
||||
// # In a GM Use the /invite command to invite a channel to another channel (e.g., /invite @[channel name])
|
||||
cy.postMessage(`/invite @${testChannel.name} `);
|
||||
|
||||
// * Error appears: "We couldn't find the user. They may have been deactivated by the System Administrator."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`We couldn't find the user ${testChannel.name}. They may have been deactivated by the System Administrator.`);
|
||||
});
|
||||
|
||||
it('MM-T660_2 /invite tests when used in DMs and GMs', () => {
|
||||
const [member1, member2, userDM, userToInvite] = userGroup;
|
||||
|
||||
cy.apiAddUserToChannel(testChannel.id, userToInvite.id);
|
||||
loginAndVisitChannel(testUser, testChannelUrl);
|
||||
|
||||
// # In a GM use the /invite command to invite someone to a channel they're already a member of
|
||||
cy.postMessage(`/groupmsg @${member1.username} @${member2.username} `);
|
||||
cy.postMessage(`/invite @${userToInvite.username} ~${testChannel.name} `);
|
||||
|
||||
// * Error appears: "[username] is already in the channel"
|
||||
cy.uiWaitUntilMessagePostedIncludes(`${userToInvite.username} is already in the channel.`);
|
||||
|
||||
cy.uiAddDirectMessage().click();
|
||||
cy.get('#selectItems input').typeWithForce(userDM.username).wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('#multiSelectList').findByText(`@${userDM.username}`).click();
|
||||
cy.findByText('Go').click();
|
||||
cy.uiGetChannelHeaderButton().contains(userDM.username);
|
||||
|
||||
// # In a DM use the /invite command to invite someone to a channel they're already a member of
|
||||
cy.postMessage(`/invite @${userToInvite.username} ~${testChannel.name} `);
|
||||
|
||||
// * Error appears: "[username] is already in the channel"
|
||||
cy.uiWaitUntilMessagePostedIncludes(`${userToInvite.username} is already in the channel.`);
|
||||
});
|
||||
|
||||
it('MM-T660_3 /invite tests when used in DMs and GMs', () => {
|
||||
const [userA, userB, userC, userDM, member1, member2] = userGroup;
|
||||
|
||||
// # As UserA create a new public channel
|
||||
loginAndVisitChannel(testUser, offTopicUrl);
|
||||
cy.uiCreateChannel({name: `${userA.username}-channel`});
|
||||
cy.get('#postListContent').should('be.visible');
|
||||
|
||||
cy.apiLogout();
|
||||
loginAndVisitChannel(userB, offTopicUrl);
|
||||
|
||||
cy.uiAddDirectMessage().click();
|
||||
cy.get('#selectItems input').typeWithForce(userDM.username).wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('#multiSelectList').findByText(`@${userDM.username}`).click();
|
||||
cy.findByText('Go').click();
|
||||
cy.uiGetChannelHeaderButton().contains(userDM.username);
|
||||
|
||||
// # As UserB use the /invite command in a DM to invite UserC to the public channel that UserB is not a member of
|
||||
cy.postMessage(`/invite @${userC.username} ~${userA.username}-channel `);
|
||||
|
||||
// * Error appears: "You don't have enough permissions to add [username] in [public channel name]."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`You don't have enough permissions to add ${userC.username} in ${userA.username}-channel.`);
|
||||
|
||||
// # As UserB use the /invite command in a GM to invite UserC to the public channel that UserB is not a member of
|
||||
cy.postMessage(`/groupmsg @${member1.username} @${member2.username} `);
|
||||
cy.postMessage(`/invite @${userC.username} ~${userA.username}-channel `);
|
||||
|
||||
// * Error appears: "You don't have enough permissions to add [username] in [public channel name]."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`You don't have enough permissions to add ${userC.username} in ${userA.username}-channel.`);
|
||||
});
|
||||
|
||||
it('MM-T660_4 /invite tests when used in DMs and GMs', () => {
|
||||
const userToInvite = userGroup[0];
|
||||
|
||||
loginAndVisitChannel(testUser, offTopicUrl);
|
||||
|
||||
// # Use the /invite command to invite a user to a channel by typing the channel name out without the tilde (~).
|
||||
cy.postMessage(`/invite @${userToInvite.username} ${testChannel.display_name} `);
|
||||
|
||||
// * Error appears: "Could not find the channel [channel name]. Please use the channel handle to identify channels."
|
||||
cy.uiWaitUntilMessagePostedIncludes(`Could not find the channel ${testChannel.display_name.split(' ')[1]}. Please use the channel handle to identify channels.`);
|
||||
|
||||
// * "channel handle" is a live link to https://docs.mattermost.com/messaging/managing-channels.html#naming-a-channel
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).
|
||||
contains('a', 'channel handle').should('have.attr', 'href', 'https://docs.mattermost.com/messaging/managing-channels.html#naming-a-channel');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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 @integrations
|
||||
|
||||
import {getJoinEmailTemplate, verifyEmailBody} from '../../../../utils';
|
||||
|
||||
import {loginAndVisitChannel} from './helper';
|
||||
|
||||
describe('Integrations', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
const usersToInvite = [];
|
||||
let siteName;
|
||||
let testChannelUrl;
|
||||
|
||||
before(() => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
siteName = config.TeamSettings.SiteName;
|
||||
});
|
||||
cy.apiInitSetup().then(({team, user, channelUrl}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
testChannelUrl = channelUrl;
|
||||
|
||||
Cypress._.times(2, () => {
|
||||
cy.apiCreateUser().then(({user: otherUser}) => {
|
||||
usersToInvite.push(otherUser);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T575 /invite-people', () => {
|
||||
loginAndVisitChannel(testUser, testChannelUrl);
|
||||
|
||||
// # Post `/invite email1 email2` where emails are of users not added to the team yet
|
||||
cy.postMessage(`/invite_people ${usersToInvite.map((user) => user.email).join(' ')} `);
|
||||
|
||||
// * User who added them sees system message "Email invite(s) sent"
|
||||
cy.uiWaitUntilMessagePostedIncludes('Email invite(s) sent');
|
||||
|
||||
usersToInvite.forEach((invitedUser) => {
|
||||
cy.getRecentEmail({username: invitedUser.username, email: invitedUser.email}).then((data) => {
|
||||
const {body: actualEmailBody, subject} = data;
|
||||
|
||||
// * Verify the subject
|
||||
expect(subject).to.contain(`[${siteName}] ${testUser.username} invited you to join ${testTeam.display_name} Team`);
|
||||
|
||||
// * Verify email body
|
||||
const expectedEmailBody = getJoinEmailTemplate(testUser.username, invitedUser.email, testTeam);
|
||||
verifyEmailBody(expectedEmailBody, actualEmailBody);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,82 @@
|
||||
// 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 @integrations
|
||||
|
||||
describe('Integrations', () => {
|
||||
const testCases = [
|
||||
{command: '/away', className: 'icon-clock', message: 'You are now away'},
|
||||
{command: '/dnd', className: 'icon-minus-circle', message: 'Do Not Disturb is enabled. You will not receive desktop or mobile push notifications until Do Not Disturb is turned off.'},
|
||||
{command: '/offline', className: 'icon-circle-outline', message: 'You are now offline'},
|
||||
{command: '/online', className: 'icon-check-circle', message: 'You are now online'},
|
||||
];
|
||||
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
// # Login as test user
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl: url}) => {
|
||||
offTopicUrl = url;
|
||||
});
|
||||
});
|
||||
|
||||
it('I18456 Built-in slash commands: change user status via post', () => {
|
||||
cy.apiSaveMessageDisplayPreference('compact');
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
cy.postMessage(testCase.command + ' ');
|
||||
|
||||
verifyUserStatus(testCase, true);
|
||||
});
|
||||
});
|
||||
|
||||
it('I18456 Built-in slash commands: change user status via suggestion list', () => {
|
||||
cy.apiSaveMessageDisplayPreference('clean');
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
// # Type "/" on textbox
|
||||
cy.uiGetPostTextBox().clear().type('/');
|
||||
|
||||
// # Verify that the suggestion list is visible
|
||||
cy.get('#suggestionList').should('be.visible').then((container) => {
|
||||
// # Find command and click
|
||||
cy.contains(new RegExp(testCase.command), {container}).click({force: true});
|
||||
});
|
||||
|
||||
// # Hit enter and verify user status
|
||||
cy.uiGetPostTextBox().type(' {enter}');
|
||||
verifyUserStatus(testCase, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verifyUserStatus(testCase, isCompactMode) {
|
||||
// * Verify that the user status is as indicated
|
||||
cy.uiGetProfileHeader().
|
||||
find('i').
|
||||
should('be.visible').
|
||||
and('have.class', testCase.className);
|
||||
|
||||
cy.uiWaitUntilMessagePostedIncludes(testCase.message);
|
||||
|
||||
// * Verify that ephemeral message is posted as expected
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).find('.user-popover').should('have.text', 'System');
|
||||
|
||||
if (isCompactMode) {
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', testCase.message + ' (Only visible to you)');
|
||||
} else {
|
||||
cy.get(`#postMessageText_${postId}`).should('have.text', testCase.message);
|
||||
cy.get('.post__visibility').last().should('be.visible').and('have.text', '(Only visible to you)');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -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.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @integrations
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Integrations', () => {
|
||||
const away = {name: 'away', ariaLabel: 'Away Icon', message: 'You are now away', className: 'icon-clock'};
|
||||
const offline = {name: 'offline', ariaLabel: 'Offline Icon', message: 'You are now offline', className: 'icon-circle-outline'};
|
||||
const online = {name: 'online', ariaLabel: 'Online Icon', message: 'You are now online', className: 'icon-check', profileClassName: 'icon-check-circle'};
|
||||
|
||||
before(() => {
|
||||
// # Login as test user and go to off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T670 /away', () => {
|
||||
// # Set online status and verify it's changed as the initial status
|
||||
setStatus(online.name, online.profileClassName);
|
||||
|
||||
verifyUserStatus(away);
|
||||
});
|
||||
|
||||
it('MM-T672 /offline', () => {
|
||||
// # Set online status and verify it's changed as the initial status
|
||||
setStatus(online.name, online.profileClassName);
|
||||
|
||||
verifyUserStatus(offline);
|
||||
|
||||
// # Switch to off-topic channel
|
||||
cy.uiGetLhsSection('CHANNELS').findByText('Off-Topic').click();
|
||||
cy.findByLabelText('channel header region').findByText('Off-Topic').should('be.visible');
|
||||
|
||||
// # Then switch back to off-topic channel again
|
||||
cy.uiGetLhsSection('CHANNELS').findByText('Off-Topic').click();
|
||||
cy.findByLabelText('channel header region').findByText('Off-Topic').should('be.visible');
|
||||
|
||||
// * Should not appear "New Messages" line
|
||||
cy.findByText('New Messages').should('not.exist');
|
||||
|
||||
// # Get the system message
|
||||
cy.uiGetNthPost(-2).within(() => {
|
||||
cy.findByText(offline.message);
|
||||
|
||||
// * Verify system message profile is visible and without status
|
||||
cy.findByLabelText('Mattermost Logo').should('be.visible');
|
||||
cy.get('.post__img').find('.status').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T674 /online', () => {
|
||||
// # Set offline status and verify it's changed as the initial status
|
||||
setStatus(offline.name, offline.className);
|
||||
|
||||
verifyUserStatus(online);
|
||||
});
|
||||
});
|
||||
|
||||
function setStatus(status, icon) {
|
||||
cy.apiUpdateUserStatus(status);
|
||||
cy.uiGetProfileHeader().
|
||||
find('i').
|
||||
and('have.class', icon);
|
||||
}
|
||||
|
||||
function verifyUserStatus(testCase) {
|
||||
// # Clear then type '/'
|
||||
cy.uiGetPostTextBox().clear().type('/');
|
||||
|
||||
// * Verify that the suggestion list is visible
|
||||
cy.get('#suggestionList').should('be.visible');
|
||||
|
||||
// # Post slash command to change user status
|
||||
cy.uiGetPostTextBox().type(`${testCase.name}{enter}`).wait(TIMEOUTS.ONE_HUNDRED_MILLIS).type('{enter}');
|
||||
|
||||
// * Get last post and verify system message
|
||||
cy.getLastPost().within(() => {
|
||||
cy.findByText(testCase.message);
|
||||
cy.findByText('(Only visible to you)');
|
||||
});
|
||||
|
||||
// * Verify status shown at user profile in LHS
|
||||
cy.uiGetProfileHeader().
|
||||
find('i').
|
||||
and('have.class', testCase.profileClassName || testCase.className);
|
||||
|
||||
// # Post a message
|
||||
cy.postMessage(testCase.name);
|
||||
|
||||
// Verify that the profile in the posted message shows correct status
|
||||
cy.get('.post__img').last().findByLabelText(testCase.ariaLabel);
|
||||
}
|
||||
Ссылка в новой задаче
Block a user