Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,74 @@
|
||||
// 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 @notifications
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testTeam;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({team, user}) => {
|
||||
testTeam = team;
|
||||
otherUser = user;
|
||||
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
|
||||
// # Open 'Settings' modal
|
||||
cy.uiOpenSettingsModal().within(() => {
|
||||
// # Open 'Words That Trigger Mentions' setting and uncheck all the checkboxes
|
||||
cy.findByRole('heading', {name: 'Words That Trigger Mentions'}).should('be.visible').click();
|
||||
cy.findByRole('checkbox', {name: `Your case-sensitive first name "${otherUser.first_name}"`}).should('not.be.checked');
|
||||
cy.findByRole('checkbox', {name: `Your non case-sensitive username "${otherUser.username}"`}).should('not.be.checked');
|
||||
cy.findByRole('checkbox', {name: 'Channel-wide mentions "@channel", "@all", "@here"'}).click().should('not.be.checked');
|
||||
cy.findByRole('checkbox', {name: 'Other non case-sensitive words, separated by commas:'}).should('not.be.checked');
|
||||
|
||||
// # Save then close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as sysadmin
|
||||
cy.apiAdminLogin();
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T550 Words that trigger mentions - @-icon still shows mentions list if all triggers deselected', () => {
|
||||
const text = `${otherUser.username} test message!`;
|
||||
|
||||
// # Type @ in the input box
|
||||
cy.focused().type('@');
|
||||
|
||||
// * Make sure that the suggestion list is visible and that otherUser's username is visible
|
||||
cy.get('#suggestionList').should('be.visible').within(() => {
|
||||
cy.findByText(`@${otherUser.username}`).should('be.visible');
|
||||
});
|
||||
|
||||
// # Post the text that was declared earlier and logout from sysadmin account
|
||||
cy.focused().type(`${text}{enter}{enter}`);
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as otherUser and visit the team
|
||||
cy.apiLogin(otherUser);
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
|
||||
// # Click on the @ button
|
||||
cy.uiGetRecentMentionButton().click();
|
||||
|
||||
cy.get('#search-items-container').should('be.visible').within(() => {
|
||||
// * Ensure that the mentions are visible in the RHS
|
||||
cy.findByText(`@${otherUser.username}`).should('be.visible');
|
||||
cy.findByText('test message!').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
// 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 @notification
|
||||
|
||||
import {getAdminAccount} from '../../../support/env';
|
||||
import {spyNotificationAs} from '../../../support/notification';
|
||||
|
||||
describe('Notifications', () => {
|
||||
const admin = getAdminAccount();
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let otherChannel;
|
||||
let receiver;
|
||||
let sender;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup({userPrefix: 'receiver'}).then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
receiver = user;
|
||||
return cy.apiCreateChannel(team.id, 'test', 'Test');
|
||||
}).then(({channel}) => {
|
||||
otherChannel = channel;
|
||||
return cy.apiCreateUser({prefix: 'sender'});
|
||||
}).then(({user}) => {
|
||||
sender = user;
|
||||
return cy.apiAddUserToTeam(testTeam.id, sender.id);
|
||||
}).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, sender.id);
|
||||
cy.apiAddUserToChannel(otherChannel.id, sender.id);
|
||||
return cy.apiAddUserToChannel(otherChannel.id, receiver.id);
|
||||
}).then(() => {
|
||||
// # Login as receiver and visit off-topic channel
|
||||
cy.apiLogin(receiver);
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).click();
|
||||
cy.get('#sidebarItem_off-topic').click();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T547 still triggers notification if username is not listed in words that trigger mentions', () => {
|
||||
// # Set Notification settings
|
||||
setNotificationSettings({first: false, username: true, shouts: true, custom: true}, 'off-topic');
|
||||
|
||||
const message = `@${receiver.username} I'm messaging you! ${Date.now()}`;
|
||||
|
||||
// # Use another account to post a message @-mentioning our receiver
|
||||
cy.postMessageAs({sender, message, channelId: otherChannel.id});
|
||||
|
||||
const body = `@${sender.username}: ${message}`;
|
||||
|
||||
cy.get('@notifySpy').should('have.been.calledWithMatch', otherChannel.display_name, (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${body}"`).to.equal(body);
|
||||
expect(args.tag, `Notification tag: "${args.tag}" should match: "${body}"`).to.equal(body);
|
||||
return true;
|
||||
});
|
||||
|
||||
cy.get('@notifySpy').should('have.been.calledWithMatch',
|
||||
otherChannel.display_name, {body, tag: body, requireInteraction: false, silent: false});
|
||||
|
||||
// * Verify unread mentions badge
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).
|
||||
scrollIntoView().
|
||||
find('#unreadMentions').
|
||||
should('be.visible').
|
||||
and('have.text', '1');
|
||||
|
||||
// * Go to that channel
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
|
||||
|
||||
// # Get last post message text
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).as('postMessageText');
|
||||
});
|
||||
|
||||
// * Verify entire message
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
|
||||
// * Verify highlight of username
|
||||
cy.get('@postMessageText').
|
||||
find(`[data-mention=${receiver.username}]`).
|
||||
should('be.visible').
|
||||
and('have.text', `@${receiver.username}`);
|
||||
});
|
||||
|
||||
it('MM-T545 does not trigger notifications with "Your non case-sensitive username" unchecked', () => {
|
||||
// # Set Notification settings
|
||||
setNotificationSettings({first: false, username: false, shouts: true, custom: true}, 'off-topic');
|
||||
|
||||
const message = `Hey ${receiver.username}! I'm messaging you! ${Date.now()}`;
|
||||
|
||||
// # Use another account to post a message @-mentioning our receiver
|
||||
cy.postMessageAs({sender, message, channelId: otherChannel.id});
|
||||
|
||||
// * Verify stub was not called
|
||||
cy.get('@notifySpy').should('be.not.called');
|
||||
|
||||
// * Verify unread mentions badge does not exist
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).
|
||||
scrollIntoView().
|
||||
find('#unreadMentions').
|
||||
should('not.exist');
|
||||
|
||||
// # Go to the channel where you were messaged
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
|
||||
|
||||
// # Get last post message text
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).as('postMessageText');
|
||||
});
|
||||
|
||||
// * Verify message contents
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
|
||||
// * Verify it's not highlighted
|
||||
cy.get('@postMessageText').
|
||||
find(`[data-mention=${receiver.username}]`).
|
||||
should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T548 does not trigger notifications with "channel-wide mentions" unchecked', () => {
|
||||
// # Set Notification settings
|
||||
setNotificationSettings({first: false, username: false, shouts: false, custom: true}, 'off-topic');
|
||||
|
||||
const channelMentions = ['@here', '@all', '@channel'];
|
||||
|
||||
channelMentions.forEach((mention) => {
|
||||
const message = `Hey ${mention} I'm message you all! ${Date.now()}`;
|
||||
|
||||
// # Use another account to post a message @-mentioning our receiver
|
||||
cy.postMessageAs({sender, message, channelId: otherChannel.id});
|
||||
|
||||
// * Verify stub was not called
|
||||
cy.get('@notifySpy').should('be.not.called');
|
||||
|
||||
// * Verify unread mentions badge does not exist
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).
|
||||
find('#unreadMentions').
|
||||
should('not.exist');
|
||||
|
||||
// # Go to the channel where you were messaged
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
|
||||
|
||||
// # Get last post message text
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).as('postMessageText');
|
||||
});
|
||||
|
||||
// * Verify message contents
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
|
||||
// * Verify it's not highlighted
|
||||
cy.get('@postMessageText').
|
||||
find(`[data-mention=${receiver.username}]`).
|
||||
should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T184 Words that trigger mentions support Chinese', () => {
|
||||
var customText = '番茄';
|
||||
|
||||
// # Set Notification settings
|
||||
setNotificationSettings({first: false, username: false, shouts: false, custom: true, customText}, 'off-topic');
|
||||
const message = '番茄 I\'m messaging you!';
|
||||
const message2 = '我爱吃番茄炒饭 I\'m messaging you!';
|
||||
|
||||
// # Use another account to post a message @-mentioning our receiver
|
||||
cy.postMessageAs({sender, message, channelId: otherChannel.id});
|
||||
|
||||
// # Check mention on other channel
|
||||
// * Verify unread mentions badge
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).
|
||||
scrollIntoView().
|
||||
find('#unreadMentions').
|
||||
should('be.visible').
|
||||
and('have.text', '1');
|
||||
|
||||
// * Go to that channel
|
||||
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
|
||||
|
||||
// # Get last post message text
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).as('postMessageText');
|
||||
});
|
||||
|
||||
// * Verify entire message
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
|
||||
// * Verify highlight of username
|
||||
cy.get('@postMessageText').
|
||||
find('.mention--highlight').
|
||||
should('be.visible').
|
||||
and('have.text', '番茄');
|
||||
|
||||
// # Check mention on test channel
|
||||
cy.postMessageAs({sender: admin, message: message2, channelId: testChannel.id});
|
||||
|
||||
// * Verify unread mentions badge
|
||||
cy.get(`#sidebarItem_${testChannel.name}`).
|
||||
scrollIntoView().
|
||||
find('#unreadMentions').
|
||||
should('be.visible').
|
||||
and('have.text', '1');
|
||||
|
||||
// * Go to that channel
|
||||
cy.get(`#sidebarItem_${testChannel.name}`).click({force: true});
|
||||
|
||||
// # Get last post message text
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).as('postMessageText');
|
||||
});
|
||||
|
||||
// * Verify entire message
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message2);
|
||||
|
||||
// * Verify highlight of username
|
||||
cy.get('@postMessageText').
|
||||
find('.mention--highlight').
|
||||
should('be.visible').
|
||||
and('have.text', '番茄');
|
||||
});
|
||||
});
|
||||
|
||||
function setNotificationSettings(desiredSettings = {first: true, username: true, shouts: true, custom: true, customText: '@'}, channelName) {
|
||||
// Navigate to settings modal
|
||||
cy.uiOpenSettingsModal();
|
||||
|
||||
// Notifications header should be visible
|
||||
cy.get('#notificationSettingsTitle').
|
||||
scrollIntoView().
|
||||
should('be.visible').
|
||||
and('contain', 'Notifications');
|
||||
|
||||
// Open up 'Words that trigger mentions' sub-section
|
||||
cy.get('#keysTitle').
|
||||
scrollIntoView().
|
||||
click();
|
||||
|
||||
const settings = [
|
||||
{key: 'first', selector: '#notificationTriggerFirst'},
|
||||
{key: 'username', selector: '#notificationTriggerUsername'},
|
||||
{key: 'shouts', selector: '#notificationTriggerShouts'},
|
||||
{key: 'custom', selector: '#notificationTriggerCustom'},
|
||||
];
|
||||
|
||||
// Set check boxes to desired state
|
||||
settings.forEach((setting) => {
|
||||
const checkbox = desiredSettings[setting.key] ? {state: 'check', verify: 'be.checked'} : {state: 'uncheck', verify: 'not.be.checked'};
|
||||
cy.get(setting.selector)[checkbox.state]().should(checkbox.verify);
|
||||
});
|
||||
|
||||
// Set Custom field
|
||||
if (desiredSettings.custom && desiredSettings.customText) {
|
||||
cy.get('#notificationTriggerCustomText').
|
||||
clear().
|
||||
type(desiredSettings.customText);
|
||||
}
|
||||
|
||||
// Click “Save” and close modal
|
||||
cy.uiSaveAndClose();
|
||||
|
||||
// Setup notification spy
|
||||
spyNotificationAs('notifySpy', 'granted');
|
||||
|
||||
// # Navigate to a channel we are NOT going to post to
|
||||
cy.get(`#sidebarItem_${channelName}`).scrollIntoView().click({force: true});
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
let otherTeam;
|
||||
let testTeamTownSquareUrl;
|
||||
let siteName;
|
||||
|
||||
before(() => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
siteName = config.TeamSettings.SiteName;
|
||||
});
|
||||
|
||||
cy.apiCreateTeam('team-b', 'Team B').then(({team}) => {
|
||||
otherTeam = team;
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, user, townSquareUrl}) => {
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
testTeamTownSquareUrl = townSquareUrl;
|
||||
|
||||
cy.apiAddUserToTeam(otherTeam.id, testUser.id);
|
||||
|
||||
cy.apiCreateUser().then(({user: otherUser}) => {
|
||||
cy.apiAddUserToTeam(team.id, otherUser.id);
|
||||
});
|
||||
|
||||
// # Remove mention notification (for initial channel).
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(testTeamTownSquareUrl);
|
||||
cy.postMessage('hello');
|
||||
cy.get('#sidebar-left').get('.unread-title').click();
|
||||
|
||||
// * Wait for some time, then verify that the badge is removed before logging out.
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('.badge').should('not.exist');
|
||||
cy.apiLogout();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T556 Browser tab and team sidebar notification - no unreads/mentions', () => {
|
||||
// # Test user views test team
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(testTeamTownSquareUrl);
|
||||
|
||||
cy.title().should('include', `Town Square - ${testTeam.display_name} ${siteName}`);
|
||||
|
||||
// * Browser tab shows channel name with no unread indicator
|
||||
cy.get(`#${testTeam.name}TeamButton`).parent('.unread').should('not.exist');
|
||||
cy.get('.badge').should('not.exist');
|
||||
|
||||
// * No unread/mention indicator in other team's sidebar
|
||||
cy.get(`#${otherTeam.name}TeamButton`).parent('.unread').should('not.exist');
|
||||
cy.get('.badge').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,151 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let user1;
|
||||
let user2;
|
||||
let team1;
|
||||
let team2;
|
||||
let testTeam1TownSquareUrl;
|
||||
let testTeam2TownSquareUrl;
|
||||
let siteName;
|
||||
|
||||
before(() => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
siteName = config.TeamSettings.SiteName;
|
||||
});
|
||||
|
||||
cy.apiCreateUser().then(({user: otherUser}) => {
|
||||
user2 = otherUser;
|
||||
});
|
||||
|
||||
cy.apiCreateTeam('team-b', 'Team B').then(({team}) => {
|
||||
team2 = team;
|
||||
testTeam2TownSquareUrl = `/${team2.name}/channels/town-square`;
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, user, townSquareUrl}) => {
|
||||
team1 = team;
|
||||
user1 = user;
|
||||
testTeam1TownSquareUrl = townSquareUrl;
|
||||
|
||||
cy.apiAddUserToTeam(team1.id, user2.id);
|
||||
cy.apiAddUserToTeam(team2.id, user1.id);
|
||||
cy.apiAddUserToTeam(team2.id, user2.id);
|
||||
|
||||
// # Remove mention notification (for initial channel).
|
||||
cy.apiLogin(user1);
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
cy.postMessage('hello');
|
||||
cy.get('#sidebar-left').get('.unread-title').click();
|
||||
|
||||
// * Wait for some time, then verify that the badge is removed before logging out.
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
cy.get('.badge').should('not.exist');
|
||||
cy.apiLogout();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T560_1 Browser tab and team sidebar unreads and mentions - Mention in different team', () => {
|
||||
// # User 1 views team A
|
||||
cy.apiLogin(user1);
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
|
||||
// # Return to town square
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
|
||||
// * Check for no unreads or mentions
|
||||
cy.get('.unread-title').should('not.exist');
|
||||
|
||||
//* Favicons should be default(blue)
|
||||
verifyFaviconEquals('favicon-default-16x16.png');
|
||||
|
||||
// # Have the other user post an at-mention for you in any channel on team B
|
||||
cy.apiGetChannelByName(team2.name, 'off-topic').then(({channel}) => {
|
||||
cy.postMessageAs({sender: user2, message: `@${user1.username}`, channelId: channel.id});
|
||||
});
|
||||
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Browser tab should displays (1) * channel - [team name] Mattermost
|
||||
cy.title().should('include', `(1) Town Square - ${team1.display_name} ${siteName}`);
|
||||
|
||||
// * Team sidebar: Small dot left of team B icon in team sidebar
|
||||
cy.get(`#${team2.name}TeamButton`).parent('.unread').should('be.visible').within(() => {
|
||||
// * Team sidebar: a mention badge in top right corner of the badge with number "1"
|
||||
cy.get('.badge').contains('1');
|
||||
});
|
||||
|
||||
// * Favicon should turn red when there are mentions indicated
|
||||
verifyFaviconEquals('favicon-mentions-16x16.png');
|
||||
});
|
||||
|
||||
it('MM-T560_2 Team sidebar icon - Badge with mention count increments when added to channel', () => {
|
||||
// # User 1 view and remain on team A
|
||||
cy.apiLogin(user1);
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
|
||||
// * Browser tab should displays (1) * channel - [team name] Mattermost (for verify count increase)
|
||||
cy.title().should('include', `(1) Town Square - ${team1.display_name} ${siteName}`);
|
||||
|
||||
// # Have another user view team B
|
||||
cy.apiLogin(user2);
|
||||
cy.visit(testTeam2TownSquareUrl);
|
||||
|
||||
// # Create a new channel
|
||||
cy.uiCreateChannel({name: 'new-channel'});
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Invites User 1
|
||||
cy.get('#member_popover').should('be.visible').click();
|
||||
cy.contains('Manage Members').click();
|
||||
cy.contains('Add Members').click();
|
||||
cy.get('.channel-invite__content').
|
||||
should('be.visible').
|
||||
find('input').
|
||||
type(`${user1.username}{enter}`, {force: true});
|
||||
cy.get('#saveItems').click();
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * User 1 should be added.
|
||||
cy.getLastPost().
|
||||
should('contain', `@${user1.username}`).
|
||||
should('contain', 'added to the channel');
|
||||
|
||||
// # Switch to User 1 and visit the town-square
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(user1);
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
|
||||
// * Title should be increased
|
||||
// * Browser tab should displays (1) * channel - [team name] Mattermost
|
||||
cy.title().should('include', `(2) Town Square - ${team1.display_name} ${siteName}`);
|
||||
|
||||
// * Team sidebar: Small dot left of team B icon in team sidebar
|
||||
cy.get(`#${team2.name}TeamButton`).should('be.visible').within(() => {
|
||||
// * Team sidebar: a mention badge in top right corner of the badge with number "1"
|
||||
cy.get('.badge').contains('2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verifyFaviconEquals(expectedFixture) {
|
||||
cy.get('link[rel=icon]').should('have.attr', 'href').then((defaultFaviconUrl) => {
|
||||
cy.fixture(expectedFixture).then((imageData) => {
|
||||
cy.request({url: defaultFaviconUrl, encoding: 'base64'}).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
expect(response.body).to.eq(imageData);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {
|
||||
FixedCloudConfig,
|
||||
getMentionEmailTemplate,
|
||||
verifyEmailBody,
|
||||
} from '../../../utils';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let config;
|
||||
let sender;
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let testChannelUrl;
|
||||
let receiver;
|
||||
|
||||
before(() => {
|
||||
cy.shouldHaveEmailEnabled();
|
||||
|
||||
// # Get config
|
||||
cy.apiGetConfig().then((data) => {
|
||||
({config} = data);
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, channel, user, channelUrl}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
testChannelUrl = channelUrl;
|
||||
sender = user;
|
||||
|
||||
cy.apiCreateUser().then(({user: user1}) => {
|
||||
receiver = user1;
|
||||
cy.apiAddUserToTeam(testTeam.id, receiver.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, receiver.id);
|
||||
|
||||
// # Login as receiver and visit test channel
|
||||
cy.apiLogin(receiver);
|
||||
cy.visit(testChannelUrl);
|
||||
|
||||
// # Open 'Notifications' of 'Settings' modal
|
||||
cy.uiOpenSettingsModal().within(() => {
|
||||
// # Open 'Email Notifications' setting and set to 'Immediately'
|
||||
cy.findByRole('heading', {name: 'Email Notifications'}).should('be.visible').click();
|
||||
cy.findByRole('radio', {name: 'Immediately'}).click().should('be.checked');
|
||||
|
||||
// # Save then close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
|
||||
// # As receiver, set status to offline and logout
|
||||
cy.uiGetSetStatusButton().click();
|
||||
cy.findByText('Offline').should('be.visible').click();
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as sender and visit test channel
|
||||
cy.apiLogin(sender);
|
||||
cy.visit(testChannelUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T506 Channel links show as links in notification emails', () => {
|
||||
const baseUrl = Cypress.config('baseUrl');
|
||||
const message = {
|
||||
orig: `This is a message in ~${testChannel.name} channel for @${receiver.username} `,
|
||||
emailLinked: `This is a message in ~${testChannel.name} ( ${baseUrl}/landing#/${testTeam.name}/channels/${testChannel.name} ) channel for @${receiver.username}`,
|
||||
posted: `This is a message in ~${testChannel.display_name} channel for @${receiver.username} `,
|
||||
};
|
||||
|
||||
// # Post a message as sender that contains the channel name and receiver's username
|
||||
cy.postMessage(message.orig);
|
||||
|
||||
// # Wait for a while to ensure that email notification is sent.
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Login as the receiver and visit test channel
|
||||
cy.apiLogin(receiver);
|
||||
cy.visit(testChannelUrl);
|
||||
cy.get('#confirmModalButton').
|
||||
should('be.visible').
|
||||
and('have.text', 'Yes, set my status to "Online"').
|
||||
click();
|
||||
|
||||
cy.getRecentEmail(receiver).then((data) => {
|
||||
const {body, from, subject} = data;
|
||||
const siteName = config.TeamSettings.SiteName;
|
||||
const feedbackEmail = config.EmailSettings.FeedbackEmail || FixedCloudConfig.EmailSettings.FEEDBACK_EMAIL;
|
||||
|
||||
// * Verify that email is from default feedback email
|
||||
expect(from).to.contain(feedbackEmail);
|
||||
|
||||
// * Verify that the email subject is correct
|
||||
expect(subject).to.contain(`[${siteName}] Notification in ${testTeam.display_name}`);
|
||||
|
||||
// * Verify that the email body is correct
|
||||
const expectedEmailBody = getMentionEmailTemplate(
|
||||
sender.username,
|
||||
message.emailLinked,
|
||||
postId,
|
||||
siteName,
|
||||
testTeam.name,
|
||||
testChannel.display_name,
|
||||
);
|
||||
verifyEmailBody(expectedEmailBody, body);
|
||||
|
||||
const permalink = body[3].split(' ')[4];
|
||||
const permalinkPostId = permalink.split('/')[6];
|
||||
|
||||
// # Visit permalink (e.g. click on email link) then view in browser to proceed
|
||||
cy.visit(permalink);
|
||||
cy.findByText('View in Browser').click();
|
||||
|
||||
// * Verify that message is correct
|
||||
const postText = `#postMessageText_${permalinkPostId}`;
|
||||
cy.get(postText).should('have.text', message.posted);
|
||||
|
||||
// * Should match last post and permalink post IDs
|
||||
expect(permalinkPostId).to.equal(postId);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testTeam;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
testTeam = team;
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
otherUser = user;
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
cy.apiLogin(otherUser);
|
||||
});
|
||||
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
|
||||
// # Open 'Settings' modal
|
||||
cy.uiOpenSettingsModal().within(() => {
|
||||
cy.get('#keysEdit').should('be.visible').click();
|
||||
|
||||
// * As otherUser, ensure that 'Your non-case sensitive username' is not checked
|
||||
cy.get('#notificationTriggerUsername').should('not.be.checked');
|
||||
|
||||
// # Close the modal
|
||||
cy.get('#accountSettingsHeader').find('button').should('be.visible').click();
|
||||
});
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as sysadmin
|
||||
cy.apiAdminLogin();
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T546 Words that trigger mentions - Deselect username, still get mention when added to private channel', () => {
|
||||
// # Create a new private channel
|
||||
cy.apiCreateChannel(testTeam.id, 'private-channel', 'Private Channel', 'P').then(({channel}) => {
|
||||
// # Add otherUser to the newly created private channel and logout from sysadmin account
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as otherUser and visit team
|
||||
cy.apiLogin(otherUser);
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
|
||||
// * Verify that the channel appears in LHS
|
||||
cy.get(`#sidebarItem_${channel.name}`, {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').within(() => {
|
||||
// * Verify that the channel name is visible and is the channel otherUser was invited to
|
||||
cy.findByText(channel.display_name).should('be.visible');
|
||||
|
||||
// * Ensure that the unread mentions badge is visible and has the text '1'
|
||||
cy.get('#unreadMentions').should('have.text', 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as MESSAGES from '../../../fixtures/messages';
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {spyNotificationAs} from '../../../support/notification';
|
||||
|
||||
import {
|
||||
changeDesktopNotificationAs,
|
||||
changeTeammateNameDisplayAs,
|
||||
} from './helper';
|
||||
|
||||
describe('Desktop notifications', () => {
|
||||
let testTeam;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
// Initialise a user
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
otherUser = user;
|
||||
testTeam = team;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
testUser = user;
|
||||
cy.apiAddUserToTeam(testTeam.id, testUser.id);
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// Visit town-square.
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T482 Desktop Notifications - (at) here not rec\'d when logged off', () => {
|
||||
spyNotificationAs('withoutNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification if are mentioned.
|
||||
changeDesktopNotificationAs('#desktopNotificationMentions');
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
// # Logout the user
|
||||
cy.uiLogout();
|
||||
|
||||
// Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: '@here', channelId: channel.id});
|
||||
});
|
||||
|
||||
// # Login with the user and visit town-square
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
|
||||
// * Desktop notification is not received.
|
||||
cy.get('@withoutNotification').should('not.have.been.called');
|
||||
|
||||
// * Should not have unread mentions indicator.
|
||||
cy.get('#sidebarItem_off-topic').
|
||||
scrollIntoView().
|
||||
find('#unreadMentions').
|
||||
should('not.exist');
|
||||
|
||||
// # Verify that off-topic channel is unread and then click.
|
||||
cy.findByLabelText('off-topic public channel unread').
|
||||
should('exist').
|
||||
click();
|
||||
|
||||
// # Get last post message text
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#postMessageText_${postId}`).as('postMessageText');
|
||||
});
|
||||
|
||||
// * Verify message has @here mention and it is highlighted.
|
||||
cy.get('@postMessageText').
|
||||
find('[data-mention="here"]').
|
||||
should('exist');
|
||||
|
||||
// * Verify no email notification received for the mention.
|
||||
cy.getRecentEmail(testUser).then((data) => {
|
||||
// # Verify that the email subject is about joining.
|
||||
expect(data.subject).to.contain('You joined');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T487 Desktop Notifications - For all activity with apostrophe, emoji, and markdown in notification', () => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
const actualMsg = '*I\'m* [hungry](http://example.com) :taco: ';
|
||||
const expected = '@' + otherUser.username + ': I\'m hungry :taco: Mattermost';
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification if are mentioned.
|
||||
changeDesktopNotificationAs('#desktopNotificationAllActivity');
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
// # Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
|
||||
|
||||
// * Desktop notification should be received with expected body.
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T495 Desktop Notifications - Can set to DND and no notification fires on DM', () => {
|
||||
cy.apiCreateDirectChannel([otherUser.id, testUser.id]).then(({channel}) => {
|
||||
// # Ensure notifications are set up to fire a desktop notification if you receive a DM
|
||||
cy.apiPatchUser(testUser.id, {notify_props: {...testUser.notify_props, desktop: 'all'}});
|
||||
|
||||
spyNotificationAs('withoutNotification', 'granted');
|
||||
|
||||
// # Post the following: /dnd
|
||||
cy.uiGetPostTextBox().clear().type('/dnd{enter}');
|
||||
|
||||
// # Have another user send you a DM
|
||||
cy.postMessageAs({sender: otherUser, message: MESSAGES.TINY, channelId: channel.id});
|
||||
|
||||
// * Desktop notification is not received
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withoutNotification').should('not.have.been.called');
|
||||
|
||||
// * Verify that the status indicator next to your name has changed to "Do Not Disturb"
|
||||
cy.uiGetSetStatusButton().
|
||||
find('.icon-minus-circle').
|
||||
should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T497 Desktop Notifications for empty string without mention badge', () => {
|
||||
// # Visit the MM webapp with the notification API stubbed
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
const actualMsg = '---';
|
||||
const expected = '@' + otherUser.username + ' did something new';
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification for all activity.
|
||||
changeDesktopNotificationAs('#desktopNotificationAllActivity');
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
// # Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
|
||||
|
||||
// * Desktop notification should be received with expected body.
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
|
||||
// * Verify that the channel is now unread without a mention badge
|
||||
cy.get(`#sidebarItem_${channel.name} .badge`).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T488 Desktop Notifications - Teammate name display set to username', () => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification if are mentioned
|
||||
changeDesktopNotificationAs('#desktopNotificationMentions');
|
||||
|
||||
// # Ensure display settings are set to "Show username"
|
||||
changeTeammateNameDisplayAs('#name_formatFormatA');
|
||||
|
||||
const actualMsg = `@${testUser.username} How are things?`;
|
||||
const expected = `@${otherUser.username}: @${testUser.username} How are things?`;
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
// # Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
|
||||
|
||||
// * Desktop notification should be received with expected body.
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T490 Desktop Notifications - Teammate name display set to first and last name', () => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification if are mentioned
|
||||
changeDesktopNotificationAs('#desktopNotificationMentions');
|
||||
|
||||
// # Ensure display settings are set to "Show first and last name"
|
||||
changeTeammateNameDisplayAs('#name_formatFormatC');
|
||||
|
||||
const actualMsg = `@${testUser.username} How are things?`;
|
||||
const expected = `@${otherUser.first_name} ${otherUser.last_name}: @${testUser.username} How are things?`;
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
// # Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
|
||||
|
||||
// * Desktop notification should be received with expected body.
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T491 - Channel notifications: No desktop notification when in focus', () => {
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
const message = '/echo test 3';
|
||||
|
||||
// # Go to test channel
|
||||
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Have another user send a post with delay
|
||||
cy.postMessageAs({sender: otherUser, message, channelId: channel.id});
|
||||
|
||||
// * Desktop notification is not received
|
||||
cy.get('@withNotification').should('not.have.been.called');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T494 - Channel notifications: Send Desktop Notifications - Only mentions and DMs', () => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification
|
||||
changeDesktopNotificationAs('#desktopNotificationMentions');
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
const messageWithoutNotification = 'message without notification';
|
||||
const messageWithNotification = `random message with mention @${testUser.username}`;
|
||||
const expected = `@${otherUser.username}: ${messageWithNotification}`;
|
||||
|
||||
// # Have another user send a post with no mention
|
||||
cy.postMessageAs({sender: otherUser, message: messageWithoutNotification, channelId: channel.id});
|
||||
|
||||
// * Desktop notification is not received
|
||||
cy.get('@withNotification').should('not.have.been.called');
|
||||
|
||||
// Have another user send a post with a mention
|
||||
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: channel.id});
|
||||
|
||||
// * Desktop notification is received
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
|
||||
// # Have another user post a direct message
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(({channel: dmChannel}) => {
|
||||
cy.postMessageAs({sender: otherUser, message: 'hi', channelId: dmChannel.id});
|
||||
|
||||
// * DM notification is received
|
||||
cy.get('@withNotification').should('have.been.called');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T496 - Channel notifications: Send Desktop Notifications - Never', () => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to never fire a desktop notification
|
||||
changeDesktopNotificationAs('#desktopNotificationNever');
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
const messageWithNotification = `random message with mention @${testUser.username}`;
|
||||
|
||||
// Have another user send a post with a mention
|
||||
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: channel.id});
|
||||
|
||||
// * Desktop notification is not received
|
||||
cy.get('@withNotification').should('not.have.been.called');
|
||||
|
||||
// # Have another user post a direct message
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(({channel: dmChannel}) => {
|
||||
cy.postMessageAs({sender: otherUser, message: 'hi', channelId: dmChannel.id});
|
||||
|
||||
// * DM notification is not received
|
||||
cy.get('@withNotification').should('not.have.been.called');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T499 - Channel notifications: Desktop Notification Sounds OFF', () => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Open settings modal
|
||||
cy.uiOpenSettingsModal().within(() => {
|
||||
// # Click "Desktop"
|
||||
cy.findByText('Desktop Notifications').should('be.visible').click();
|
||||
|
||||
// # Select sound off.
|
||||
cy.get('#soundOff').check();
|
||||
|
||||
// # Ensure sound dropdown is not visible
|
||||
cy.get('#displaySoundNotification').should('not.exist');
|
||||
|
||||
// # Click "Save" and close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
const messageWithNotification = `random message with mention @${testUser.username}`;
|
||||
|
||||
// # Have another user send a post with a mention
|
||||
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: channel.id});
|
||||
|
||||
// * Desktop notification is received without sound
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
|
||||
expect(args.silent).to.equal(true);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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 @notifications
|
||||
|
||||
import {spyNotificationAs} from '../../../support/notification';
|
||||
|
||||
import {changeDesktopNotificationAs} from './helper';
|
||||
|
||||
describe('Desktop notifications', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
otherUser = user;
|
||||
});
|
||||
|
||||
// Initialize a user
|
||||
cy.apiInitSetup().then(({team, channel, user, offTopicUrl}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
|
||||
// Login then visit off-topic
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T885 Channel notifications: Desktop notifications mentions only', () => {
|
||||
// # Ensure notifications are set up to fire a desktop notification
|
||||
changeDesktopNotificationAs('#desktopNotificationAllActivity');
|
||||
|
||||
const messageWithNotification = `random message with mention @${testUser.username}`;
|
||||
const expected = `@${otherUser.username}: ${messageWithNotification}`;
|
||||
|
||||
// # Go to test channel
|
||||
cy.uiClickSidebarItem(testChannel.name);
|
||||
|
||||
// # Set channel notifications to show on mention only
|
||||
cy.uiOpenChannelMenu('Notification Preferences');
|
||||
cy.findByText('Send desktop notifications').click();
|
||||
cy.findByRole('radio', {name: 'Only for mentions'}).click();
|
||||
cy.uiSaveAndClose();
|
||||
|
||||
// # Visit off-topic
|
||||
cy.uiClickSidebarItem('off-topic');
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// Have another user send a post with no mention
|
||||
cy.postMessageAs({sender: otherUser, message: 'random message no mention', channelId: testChannel.id});
|
||||
|
||||
// * Desktop notification is not received
|
||||
cy.get('@withNotification').should('not.have.been.called');
|
||||
|
||||
// Have another user send a post with a mention
|
||||
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: testChannel.id});
|
||||
|
||||
// * Desktop notification is received
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', testChannel.display_name, (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
|
||||
// * Notification badge is aligned to the right of LHS
|
||||
cy.uiGetSidebarItem(testChannel.name).find('.badge').should('exist').and('have.css', 'margin', '0px 4px');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,109 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {spyNotificationAs} from '../../../support/notification';
|
||||
import {getAdminAccount} from '../../../support/env';
|
||||
|
||||
import {
|
||||
changeDesktopNotificationAs,
|
||||
changeTeammateNameDisplayAs,
|
||||
} from './helper';
|
||||
|
||||
describe('Desktop notifications', () => {
|
||||
let testTeam;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
otherUser = user;
|
||||
testTeam = team;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
testUser = user;
|
||||
cy.apiAddUserToTeam(testTeam.id, testUser.id);
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// Visit town-square.
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T489_1 Display teammate nickname when nickname exists', () => {
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification if are mentioned
|
||||
changeDesktopNotificationAs('#desktopNotificationMentions');
|
||||
|
||||
// # Ensure display settings are set to "Show nickname if one exists, otherwise show first and last name"
|
||||
changeTeammateNameDisplayAs('#name_formatFormatB');
|
||||
|
||||
const actualMsg = `@${testUser.username} first`;
|
||||
const expected = `@${otherUser.nickname}: ${actualMsg}`;
|
||||
|
||||
// # Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
|
||||
|
||||
// * Desktop notification should be received with expected body.
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', channel.display_name, (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T489_2 Display teammates first and last name when nickname does not exists', () => {
|
||||
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
|
||||
// # Ensure other user is without nickname set up
|
||||
patchUser(otherUser.id, {nickname: ''});
|
||||
|
||||
spyNotificationAs('withNotification', 'granted');
|
||||
|
||||
// # Ensure notifications are set up to fire a desktop notification if are mentioned
|
||||
changeDesktopNotificationAs('#desktopNotificationMentions');
|
||||
|
||||
// # Ensure display settings are set to "Show nickname if one exists, otherwise show first and last name"
|
||||
changeTeammateNameDisplayAs('#name_formatFormatB');
|
||||
|
||||
const actualMsg = `@${testUser.username} second`;
|
||||
const expected = `@${otherUser.first_name} ${otherUser.last_name}: ${actualMsg}`;
|
||||
|
||||
// # Have another user send a post.
|
||||
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
|
||||
|
||||
// * Desktop notification should be received with expected body.
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('@withNotification').should('have.been.calledWithMatch', channel.display_name, (args) => {
|
||||
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function patchUser(userId, data) {
|
||||
const sysadmin = getAdminAccount();
|
||||
|
||||
return cy.externalRequest({
|
||||
user: sysadmin,
|
||||
method: 'PUT',
|
||||
path: `users/${userId}/patch`,
|
||||
data,
|
||||
}).its('status').should('eq', 200);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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 @notifications
|
||||
|
||||
describe('Notifications', () => {
|
||||
let user1;
|
||||
let user2;
|
||||
let team1;
|
||||
let team2;
|
||||
let testTeam1TownSquareUrl;
|
||||
let siteName;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
team1 = team;
|
||||
user1 = user;
|
||||
testTeam1TownSquareUrl = `/${team.name}/channels/town-square`;
|
||||
|
||||
cy.apiCreateUser().then(({user: otherUser}) => {
|
||||
user2 = otherUser;
|
||||
cy.apiAddUserToTeam(team.id, user2.id);
|
||||
});
|
||||
|
||||
cy.apiCreateTeam('team-b', 'Team B').then(({team: anotherTeam}) => {
|
||||
team2 = anotherTeam;
|
||||
cy.apiAddUserToTeam(team2.id, user1.id);
|
||||
cy.apiAddUserToTeam(team2.id, user2.id);
|
||||
});
|
||||
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
siteName = config.TeamSettings.SiteName;
|
||||
});
|
||||
|
||||
// # Remove mention notification (for initial channel).
|
||||
cy.apiLogin(user1);
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
cy.findByText('CHANNELS').get('.unread-title').click();
|
||||
cy.findByText('CHANNELS').get('.unread-title').should('not.exist');
|
||||
cy.apiLogout();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T561 Browser tab and team sidebar - direct messages don\'t add indicator on team icon in team sidebar (but do in browser tab)', () => {
|
||||
// # User A: Join teams A and B. Open team A
|
||||
cy.apiLogin(user1);
|
||||
cy.visit(testTeam1TownSquareUrl);
|
||||
|
||||
// # User B: Join team B
|
||||
// # User B: Post a direct message to user A
|
||||
cy.apiCreateDirectChannel([user1.id, user2.id]).then(({channel: ownDMChannel}) => {
|
||||
cy.postMessageAs({sender: user2, message: `@${user1.username}`, channelId: ownDMChannel.id});
|
||||
});
|
||||
|
||||
// * Browser tab shows: (1) * Town Square - [team name] Mattermost
|
||||
cy.title().should('include', `(1) Town Square - ${team1.display_name} ${siteName}`);
|
||||
|
||||
// * Team sidebar shows: No unread / mention indicator in team sidebar on either team
|
||||
cy.get(`#${team2.name}TeamButton`).parent('.unread').should('not.exist');
|
||||
cy.get(`#${team2.name}TeamButton`).parent().within(() => {
|
||||
cy.get('.badge').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export function changeDesktopNotificationAs(category) {
|
||||
// # Open settings modal
|
||||
cy.uiOpenSettingsModal().within(() => {
|
||||
// # Click "Desktop Notifications"
|
||||
cy.findByText('Desktop Notifications').should('be.visible').click();
|
||||
|
||||
// # Select category.
|
||||
cy.get(category).check();
|
||||
|
||||
// # Click "Save" and close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
}
|
||||
|
||||
export function changeTeammateNameDisplayAs(category) {
|
||||
// # Open settings modal
|
||||
cy.uiOpenSettingsModal('Display').within(() => {
|
||||
// # Click "Desktop"
|
||||
cy.findByText('Teammate Name Display').click();
|
||||
|
||||
// # Select category.
|
||||
cy.get(category).check();
|
||||
|
||||
// # Click "Save" and close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testTeam;
|
||||
let userB;
|
||||
|
||||
let channelA;
|
||||
let channelB;
|
||||
|
||||
before(() => {
|
||||
// # Login as new user and visit town-square
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
testTeam = team;
|
||||
|
||||
// # Add 1 user
|
||||
cy.apiCreateUser().then(({user: newUser}) => {
|
||||
userB = newUser;
|
||||
cy.apiAddUserToTeam(testTeam.id, userB.id);
|
||||
});
|
||||
|
||||
// # Create two channels
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
|
||||
channelA = channel;
|
||||
});
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
|
||||
channelB = channel;
|
||||
});
|
||||
|
||||
cy.apiLogin(user);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T567 - Channel Notifications - Turn on Ignore mentions for @channel, @here and @all', () => {
|
||||
cy.visit(`/${testTeam.name}/channels/${channelA.name}`);
|
||||
|
||||
// # Add users to channel
|
||||
addNumberOfUsersToChannel(1);
|
||||
|
||||
cy.getLastPostId().then((id) => {
|
||||
// * The system message should contain 'added to the channel by you'
|
||||
cy.get(`#postMessageText_${id}`).should('contain', 'added to the channel by you');
|
||||
});
|
||||
|
||||
// # Set ignore mentions
|
||||
setIgnoreMentions(true);
|
||||
|
||||
// # Go to a different channel
|
||||
cy.visit(`/${testTeam.name}/channels/${channelB.name}`);
|
||||
|
||||
// # Post messages as another user on the first channel
|
||||
cy.postMessageAs({sender: userB, message: '@all test', channelId: channelA.id});
|
||||
cy.postMessageAs({sender: userB, message: '@channel test', channelId: channelA.id});
|
||||
cy.postMessageAs({sender: userB, message: '@here test', channelId: channelA.id});
|
||||
|
||||
// * Assert the channel is unread with no mentions
|
||||
cy.get(`#sidebarItem_${channelA.name}`).wait(TIMEOUTS.ONE_SEC).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${channelA.name} > #unreadMentions`).should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T568 - Channel Notifications - Turn off Ignore mentions for @channel, @here and @all', () => {
|
||||
cy.visit(`/${testTeam.name}/channels/${channelA.name}`);
|
||||
|
||||
// # Unset ignore mentions
|
||||
setIgnoreMentions(false);
|
||||
|
||||
// # Go to a different channel
|
||||
cy.visit(`/${testTeam.name}/channels/${channelB.name}`);
|
||||
|
||||
// # Post messages as another user on the first channel
|
||||
cy.postMessageAs({sender: userB, message: '@all test', channelId: channelA.id});
|
||||
cy.postMessageAs({sender: userB, message: '@channel test', channelId: channelA.id});
|
||||
cy.postMessageAs({sender: userB, message: '@here test', channelId: channelA.id});
|
||||
|
||||
// * Assert the channel is unread with 3 mentions
|
||||
cy.get(`#sidebarItem_${channelA.name}`).should('have.class', 'unread-title');
|
||||
cy.get(`#sidebarItem_${channelA.name} > #unreadMentions`).should('exist').wait(TIMEOUTS.ONE_SEC).should('contain', '3');
|
||||
});
|
||||
});
|
||||
|
||||
function addNumberOfUsersToChannel(num = 1) {
|
||||
// # Open channel menu and click 'Add Members'
|
||||
cy.uiOpenChannelMenu('Add Members');
|
||||
cy.get('#addUsersToChannelModal').should('be.visible');
|
||||
|
||||
// * Assert that modal appears
|
||||
// # Click the first row for a number of times
|
||||
Cypress._.times(num, () => {
|
||||
cy.get('#selectItems input').typeWithForce('u');
|
||||
cy.get('#multiSelectList').should('be.visible').children().first().click();
|
||||
});
|
||||
|
||||
// # Click the button "Add" to add user to a channel
|
||||
cy.get('#saveItems').click();
|
||||
|
||||
// # Wait for the modal to disappear
|
||||
cy.get('#addUsersToChannelModal').should('not.exist');
|
||||
}
|
||||
|
||||
function setIgnoreMentions(toSet) {
|
||||
let stringToSet = 'Off';
|
||||
if (toSet) {
|
||||
stringToSet = 'On';
|
||||
}
|
||||
|
||||
// # Open channel menu and click Notification Preferences
|
||||
cy.uiOpenChannelMenu('Notification Preferences');
|
||||
|
||||
// # Click on the edit button for ignore channel mentions
|
||||
cy.get('#ignoreChannelMentionsEdit').should('exist').click();
|
||||
|
||||
// # Click on selected option
|
||||
cy.get(`#ignoreChannelMentions${stringToSet}`).should('exist').click();
|
||||
|
||||
// # Click on save to save the configuration
|
||||
cy.get('#saveSetting').should('exist').click();
|
||||
|
||||
// * Assert that the option selected is reflected
|
||||
cy.get('#ignoreChannelMentionsDesc').should('contain', stringToSet);
|
||||
|
||||
// # Click on the X button to close the modal
|
||||
cy.get('#channelNotificationModalLabel').siblings('.close').click();
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// 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 @notification
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {
|
||||
FixedCloudConfig,
|
||||
getMentionEmailTemplate,
|
||||
verifyEmailBody,
|
||||
} from '../../../utils';
|
||||
|
||||
describe('Email notification', () => {
|
||||
let config;
|
||||
let sender;
|
||||
let receiver;
|
||||
let testTeam;
|
||||
|
||||
before(() => {
|
||||
// # Do email test if setup properly
|
||||
cy.shouldHaveEmailEnabled();
|
||||
|
||||
// # Get config
|
||||
cy.apiGetConfig().then((data) => {
|
||||
({config} = data);
|
||||
});
|
||||
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
receiver = user;
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
|
||||
sender = user;
|
||||
testTeam = team;
|
||||
|
||||
cy.apiAddUserToTeam(team.id, receiver.id);
|
||||
|
||||
// # Login and go to off-topic
|
||||
cy.apiLogin(sender);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T4062 Post a message that mentions a user', () => {
|
||||
// # Post a message mentioning other user
|
||||
const message = `Hello @${receiver.username} `;
|
||||
cy.postMessage(message);
|
||||
|
||||
// # Wait for a while to ensure that email notification is sent.
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.getRecentEmail(receiver).then((data) => {
|
||||
const {body, from, subject} = data;
|
||||
const siteName = config.TeamSettings.SiteName;
|
||||
const feedbackEmail = config.EmailSettings.FeedbackEmail || FixedCloudConfig.EmailSettings.FEEDBACK_EMAIL;
|
||||
|
||||
// * Verify that email is from default feedback email
|
||||
expect(from).to.contain(feedbackEmail);
|
||||
|
||||
// * Verify that the email subject is correct
|
||||
expect(subject).to.contain(`[${siteName}] Notification in ${testTeam.display_name}`);
|
||||
|
||||
// * Verify that the email body is correct
|
||||
const expectedEmailBody = getMentionEmailTemplate(
|
||||
sender.username,
|
||||
message.trim(),
|
||||
postId,
|
||||
siteName,
|
||||
testTeam.name,
|
||||
'Off-Topic',
|
||||
);
|
||||
|
||||
verifyEmailBody(expectedEmailBody, body);
|
||||
|
||||
const permalink = body[3].split(' ')[4];
|
||||
const permalinkPostId = permalink.split('/')[6];
|
||||
|
||||
// # Visit permalink (e.g. click on email link) then view in browser to proceed
|
||||
cy.visit(permalink);
|
||||
cy.findByText('View in Browser').click();
|
||||
|
||||
const postText = `#postMessageText_${permalinkPostId}`;
|
||||
cy.get(postText).should('have.text', message);
|
||||
|
||||
// * Should match last post and permalink post IDs
|
||||
expect(permalinkPostId).to.equal(postId);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as MESSAGES from '../../../fixtures/messages';
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let otherUser;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
otherUser = user;
|
||||
|
||||
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T565 New message bar - Doesnt display for emoji reaction', () => {
|
||||
// # Make a starting post from the user 1
|
||||
cy.postMessage(MESSAGES.SMALL);
|
||||
|
||||
// # Make a few posts from user 2 so that center can be scrolled
|
||||
Cypress._.times(30, (postNumber) => {
|
||||
cy.postMessageAs({sender: otherUser, message: `P${postNumber}`, channelId: testChannel.id});
|
||||
});
|
||||
|
||||
// # Make a final post from the user 1 where reaction will be added
|
||||
cy.postMessage('This post will have a reaction');
|
||||
|
||||
// # Scroll to top of the channel to first post
|
||||
cy.getNthPostId(1).then((firstPostId) => {
|
||||
cy.get(`#post_${firstPostId}`).should('exist').scrollIntoView();
|
||||
});
|
||||
|
||||
// # Get the last posted message
|
||||
cy.getLastPostId().then((lastPostID) => {
|
||||
// # Add a reaction to the last post with another user
|
||||
cy.reactToMessageAs({sender: otherUser, postId: lastPostID, reaction: 'smile'});
|
||||
});
|
||||
|
||||
// * Verify that new message bar is not visible even after a new reaction
|
||||
// was added to the message in the bottom
|
||||
cy.get('.toast.toast__visible').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T566 New message bar - Displays in permalink view', () => {
|
||||
cy.makeClient().then(async (client) => {
|
||||
const townChannel = await client.getChannelByName(testTeam.id, 'town-square');
|
||||
const townChannelId = townChannel.id;
|
||||
|
||||
// # Post messages in town-square channel
|
||||
Cypress._.times(15, (postNumber) => {
|
||||
cy.postMessageAs({sender: otherUser, message: `P${postNumber}`, channelId: townChannelId});
|
||||
});
|
||||
|
||||
// # Enter "in:town-square" in the search bar and hit ENTER
|
||||
cy.get('#searchBox').
|
||||
typeWithForce('in:town-square').
|
||||
typeWithForce('{enter}').
|
||||
typeWithForce('{enter}');
|
||||
|
||||
// # Click "Jump" to one of the search results
|
||||
cy.get('a.search-item__jump').last().click();
|
||||
|
||||
// * Verify permalink in main channel view (post highlighted, fades in 6sec.)
|
||||
cy.getNthPostId(1).then((postIdTest) => {
|
||||
cy.get(`#post_${postIdTest}`, {timeout: TIMEOUTS.HALF_MIN}).should('have.class', 'post--highlight');
|
||||
cy.clock();
|
||||
cy.tick(6000);
|
||||
cy.get(`#post_${postIdTest}`).should('not.have.class', 'post--highlight');
|
||||
});
|
||||
|
||||
// # Other user post a message in town-square channel
|
||||
cy.postMessageAs({
|
||||
sender: otherUser,
|
||||
message: 'message from user B',
|
||||
channelId: townChannelId,
|
||||
});
|
||||
|
||||
// * Verify New message bar appears
|
||||
cy.get('.NotificationSeparator').should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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 @notifications
|
||||
|
||||
import {getRandomId} from '../../../utils';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let otherUser;
|
||||
let offTopicChannelId;
|
||||
const numberOfPosts = 30;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
|
||||
otherUser = user;
|
||||
|
||||
cy.apiGetChannelByName(team.name, 'off-topic').then(({channel}) => {
|
||||
offTopicChannelId = channel.id;
|
||||
});
|
||||
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T562 New message bar - Message posted while scrolled up in same channel', () => {
|
||||
// # Post 30 random messages from the 'otherUser' account in off-topic
|
||||
Cypress._.times(numberOfPosts, (num) => {
|
||||
cy.postMessageAs({sender: otherUser, message: `${num} ${getRandomId()}`, channelId: offTopicChannelId});
|
||||
});
|
||||
|
||||
// # Scroll to the top of the channel so that the 'Jump to New Messages' button would be visible
|
||||
cy.get('.post-list__dynamic').scrollTo('top');
|
||||
|
||||
// # Post two new messages as 'otherUser'
|
||||
cy.postMessageAs({sender: otherUser, message: 'Random Message', channelId: offTopicChannelId});
|
||||
cy.postMessageAs({sender: otherUser, message: 'Last Message', channelId: offTopicChannelId});
|
||||
|
||||
// * Verify that the last message is currently not visible
|
||||
cy.findByText('Last Message').should('not.be.visible');
|
||||
|
||||
// # Click on the 'Jump to New Messages' button
|
||||
cy.get('.toast__visible').should('be.visible').click();
|
||||
|
||||
// * Verify that the last message is now visible
|
||||
cy.findByText('Last Message').should('be.visible');
|
||||
|
||||
// * Verify that 'Jump to New Messages' is not visible
|
||||
cy.get('.toast__visible').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testTeam;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
testTeam = team;
|
||||
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
otherUser = user;
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
cy.apiLogin(otherUser);
|
||||
});
|
||||
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T555 Notification Preferences do not save when modal is closed without saving', () => {
|
||||
// # Call function that clicks on Settings -> Notifications -> Email Notifications -> Send Email Notifications -> Never without saving
|
||||
openSettingsAndClickEmailEdit(true);
|
||||
|
||||
// # Call function that checks Settings -> Notifications -> Email Notifications -> Send Email Notifications -> Never is not saved
|
||||
openSettingsAndClickEmailEdit(false);
|
||||
});
|
||||
|
||||
function openSettingsAndClickEmailEdit(shouldBeClicked = false) {
|
||||
// # Open 'Settings' modal
|
||||
cy.uiOpenSettingsModal().within(() => {
|
||||
// # Click on the 'Edit' button next to Email Notifications
|
||||
cy.get('#emailEdit').click();
|
||||
|
||||
if (shouldBeClicked) {
|
||||
// * Ensure that 'Send email notifications' is set to 'Immediately'
|
||||
cy.get('#emailNotificationImmediately').should('be.visible').and('be.checked');
|
||||
|
||||
// # Check that 'Never' is not currently checked, and click it
|
||||
cy.get('#emailNotificationNever').should('be.visible').and('not.be.checked').click();
|
||||
|
||||
// # Wait for half a second just to be sure the setting was correctly checked
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Close the modal
|
||||
cy.get('#accountSettingsHeader').find('button').should('be.visible').click();
|
||||
} else {
|
||||
// * Ensure that 'Send email notifications' is set to 'Immediately'
|
||||
cy.get('#emailNotificationImmediately').should('be.visible').and('be.checked');
|
||||
|
||||
// * Ensure that 'Send email notifications' is not set to 'Never'
|
||||
cy.get('#emailNotificationNever').should('be.visible').and('not.be.checked');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -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 @notifications
|
||||
|
||||
import {getRandomId} from '../../../utils';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let otherUser;
|
||||
let offTopicChannelId;
|
||||
const numberOfPosts = 30;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
|
||||
otherUser = user;
|
||||
|
||||
cy.apiGetChannelByName(team.name, 'off-topic').then(({channel}) => {
|
||||
offTopicChannelId = channel.id;
|
||||
});
|
||||
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T564 New message bar - Own user posts a reply while scrolled up in a channel', () => {
|
||||
// # Post 30 random messages from the 'otherUser' account in off-topic
|
||||
Cypress._.times(numberOfPosts, (num) => {
|
||||
cy.postMessageAs({sender: otherUser, message: `${num} ${getRandomId()}`, channelId: offTopicChannelId});
|
||||
});
|
||||
|
||||
// # Click on the post comment icon of the last message
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// # Scroll to the top of the channel so that the 'Jump to New Messages' button would be visible (if it existed)
|
||||
cy.get('.post-list__dynamic').scrollTo('top');
|
||||
|
||||
// # Post a reply in RHS
|
||||
const message = 'This is a test message';
|
||||
cy.postMessageReplyInRHS(message);
|
||||
|
||||
// * 'Jump to New Messages' is not visible
|
||||
cy.get('.toast__visible').should('not.exist');
|
||||
|
||||
// * Message gets posted in off-topic
|
||||
cy.uiWaitUntilMessagePostedIncludes(message);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,250 @@
|
||||
// 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 @notifications
|
||||
|
||||
import {spyNotificationAs} from '../../../support/notification';
|
||||
|
||||
describe('reply-notifications', () => {
|
||||
let testTeam;
|
||||
let testChannelUrl;
|
||||
let testChannelId;
|
||||
let testChannelName;
|
||||
let receiver;
|
||||
let sender;
|
||||
|
||||
before(() => {
|
||||
cy.apiCreateUser().then(({user}) => {
|
||||
sender = user;
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({team, channel, user, channelUrl}) => {
|
||||
testTeam = team;
|
||||
receiver = user;
|
||||
testChannelUrl = channelUrl;
|
||||
testChannelId = channel.id;
|
||||
testChannelName = channel.name;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, sender.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannelId, sender.id);
|
||||
});
|
||||
|
||||
// # Login as receiver
|
||||
cy.apiLogin(receiver);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T551 Do not trigger notifications on messages in reply threads unless I\'m mentioned', () => {
|
||||
cy.visit(testChannelUrl);
|
||||
|
||||
// Setup notification spy
|
||||
spyNotificationAs('notifySpy', 'granted');
|
||||
|
||||
// # Set users notification settings
|
||||
setReplyNotificationsSetting('#notificationCommentsNever');
|
||||
|
||||
// # Post a message
|
||||
cy.postMessage('Hi there, this is a root message');
|
||||
|
||||
// # Get post id of message
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Switch to town-square so that unread notifications in test channel may be triggered
|
||||
cy.uiClickSidebarItem('town-square');
|
||||
|
||||
cy.uiGetSidebarItem(testChannelName).click({force: true});
|
||||
|
||||
// # Post a message in original thread as another user
|
||||
cy.postMessage('This is a reply to the root post');
|
||||
|
||||
// * Verify stub was not called
|
||||
cy.get('@notifySpy').should('be.not.called');
|
||||
|
||||
// * Verify unread mentions badge does not exist
|
||||
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('not.exist');
|
||||
|
||||
// # Switch again to other channel
|
||||
cy.uiClickSidebarItem('town-square');
|
||||
|
||||
// # Reply to a post as another user mentioning the receiver
|
||||
cy.postMessageAs({sender, message: `Another reply with mention @${receiver.username}`, channelId: testChannelId, rootId: postId});
|
||||
|
||||
// * Verify stub was called
|
||||
cy.get('@notifySpy').should('be.called');
|
||||
|
||||
// * Verify unread mentions badge exists
|
||||
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T552 Trigger notifications on messages in threads that I start', () => {
|
||||
cy.visit(testChannelUrl);
|
||||
|
||||
// Setup notification spy
|
||||
spyNotificationAs('notifySpy', 'granted');
|
||||
|
||||
// # Set users notification settings
|
||||
setReplyNotificationsSetting('#notificationCommentsRoot');
|
||||
|
||||
// # Post a message
|
||||
cy.postMessage('Hi there, this is another root message');
|
||||
|
||||
// # Get post id of message
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Switch to town-square so that unread notifications in test channel may be triggered
|
||||
cy.uiClickSidebarItem('town-square');
|
||||
|
||||
// # Post a message in original thread as another user
|
||||
const message = 'This is a reply to the root post';
|
||||
cy.postMessageAs({sender, message, channelId: testChannelId, rootId: postId}).then(() => {
|
||||
// * Verify stub was called
|
||||
cy.get('@notifySpy').should('be.called');
|
||||
|
||||
// * Verify unread mentions badge exists
|
||||
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
|
||||
|
||||
// # Navigate to test channel
|
||||
cy.uiClickSidebarItem(testChannelName);
|
||||
|
||||
// * Verify entire message
|
||||
cy.getLastPostId().then((msgId) => {
|
||||
cy.get(`#postMessageText_${msgId}`).as('postMessageText');
|
||||
|
||||
// * Verify reply bar highlight
|
||||
cy.get(`#post_${msgId}`).should('have.class', 'mention-comment');
|
||||
});
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T553 Trigger notifications on messages in reply threads that I start or participate in - start thread', () => {
|
||||
cy.visit(testChannelUrl);
|
||||
|
||||
// Setup notification spy
|
||||
spyNotificationAs('notifySpy', 'granted');
|
||||
|
||||
// # Set users notification settings
|
||||
setReplyNotificationsSetting('#notificationCommentsAny');
|
||||
|
||||
// # Post a message
|
||||
cy.postMessage('Hi there, this is another root message');
|
||||
|
||||
// # Get post id of message
|
||||
cy.getLastPostId().then((postId) => {
|
||||
// # Switch to town-square so that unread notifications in test channel may be triggered
|
||||
cy.uiClickSidebarItem('town-square');
|
||||
|
||||
// # Post a message in original thread as another user
|
||||
const message = 'This is a reply to the root post';
|
||||
cy.postMessageAs({sender, message, channelId: testChannelId, rootId: postId}).then(() => {
|
||||
// * Verify stub was called
|
||||
cy.get('@notifySpy').should('be.called');
|
||||
|
||||
// * Verify unread mentions badge exists
|
||||
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
|
||||
|
||||
// # Navigate to test channel
|
||||
cy.uiClickSidebarItem(testChannelName);
|
||||
|
||||
// * Verify entire message
|
||||
cy.getLastPostId().then((msgId) => {
|
||||
cy.get(`#postMessageText_${msgId}`).as('postMessageText');
|
||||
|
||||
// * Verify reply bar highlight
|
||||
cy.get(`#post_${msgId}`).should('have.class', 'mention-comment');
|
||||
});
|
||||
cy.get('@postMessageText').
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T554 Trigger notifications on messages in reply threads that I start or participate in - participate in', () => {
|
||||
cy.visit(testChannelUrl);
|
||||
|
||||
// Setup notification spy
|
||||
spyNotificationAs('notifySpy', 'granted');
|
||||
|
||||
// # Set users notification settings
|
||||
setReplyNotificationsSetting('#notificationCommentsAny');
|
||||
|
||||
// # Make a root post as some other user
|
||||
const rootPostMessage = 'a root message by some other user';
|
||||
cy.postMessageAs({sender, message: rootPostMessage, channelId: testChannelId}).then((post) => {
|
||||
const rootPostId = post.id;
|
||||
const rootPostMessageId = `#rhsPostMessageText_${rootPostId}`;
|
||||
|
||||
// # Click comment icon to open RHS
|
||||
cy.clickPostCommentIcon(rootPostId);
|
||||
|
||||
// * Check that the RHS is open
|
||||
cy.get('#rhsContainer').should('be.visible');
|
||||
|
||||
// * Verify that the original message is in the RHS
|
||||
cy.get('#rhsContainer').find(rootPostMessageId).should('have.text', `${rootPostMessage}`);
|
||||
|
||||
// # Post a reply as receiver, i.e. participate in the thread
|
||||
cy.postMessageReplyInRHS('this is a reply from the receiver');
|
||||
|
||||
// # Wait till receiver's post is visible
|
||||
cy.getLastPostId().then(() => {
|
||||
// # Switch to town-square so that unread notifications in test channel may be triggered
|
||||
cy.uiClickSidebarItem('town-square');
|
||||
|
||||
// # Post a message in thread as another user
|
||||
const message = 'This is a reply by sender';
|
||||
cy.postMessageAs({sender, message, channelId: testChannelId, rootId: rootPostId}).then(() => {
|
||||
// * Verify stub was called
|
||||
cy.get('@notifySpy').should('be.called');
|
||||
|
||||
// * Verify unread mentions badge exists
|
||||
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
|
||||
|
||||
// # Navigate to test channel
|
||||
cy.uiClickSidebarItem(testChannelName);
|
||||
|
||||
cy.getLastPostId().then((msgId) => {
|
||||
// * Verify entire message
|
||||
cy.get(`#postMessageText_${msgId}`).
|
||||
should('be.visible').
|
||||
and('have.text', message);
|
||||
|
||||
// * Verify reply bar highlight
|
||||
cy.get(`#rhsPost_${msgId}`).should('have.class', 'mention-comment');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function setReplyNotificationsSetting(idToToggle) {
|
||||
// Navigate to settings modal
|
||||
cy.uiOpenSettingsModal();
|
||||
|
||||
// Notifications header should be visible
|
||||
cy.get('#notificationSettingsTitle').
|
||||
scrollIntoView().
|
||||
should('be.visible').
|
||||
and('contain', 'Notifications');
|
||||
|
||||
// Open up 'Reply Notifications' sub-section
|
||||
cy.get('#commentsTitle').
|
||||
scrollIntoView().
|
||||
click();
|
||||
|
||||
cy.get(idToToggle).check().should('be.checked');
|
||||
|
||||
// Click “Save” and close modal
|
||||
cy.uiSaveAndClose();
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let testTeam;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
|
||||
cy.apiCreateUser().then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
|
||||
});
|
||||
|
||||
cy.apiLogin(testUser).then(() => {
|
||||
// # Create new test channel
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
|
||||
cy.apiAddUserToChannel(channel.id, otherUser.id);
|
||||
|
||||
// # Create more channels for scrolling in LHS
|
||||
Cypress._.times(40, (i) => {
|
||||
cy.apiCreateChannel(testTeam.id, `channel-test-${i}`, `channel-${i}`).then((out) => {
|
||||
cy.apiAddUserToChannel(out.channel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
|
||||
// # Most page of messages so the channel can be scrolled up
|
||||
Cypress._.times(40, (i) => {
|
||||
cy.postMessageAs({sender: testUser, message: `test${i}`, channelId: channel.id});
|
||||
});
|
||||
|
||||
// # Go to test channel
|
||||
cy.visit(`/${team.name}/channels/${channel.name}`);
|
||||
|
||||
// # Scroll above the last few messages
|
||||
cy.get('div.post-list__dynamic', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').
|
||||
scrollTo(0, '70%', {duration: TIMEOUTS.ONE_SEC}).
|
||||
wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # scroll to the last channel
|
||||
cy.get('#sidebar-left li').last().scrollIntoView();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T563 New message bar - Reply posted while scrolled up in same channel', () => {
|
||||
// # Login as other user
|
||||
cy.apiLogin(otherUser);
|
||||
|
||||
// # Get last post and reply a message
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.clickPostCommentIcon(postId);
|
||||
const replyMessage = 'A reply to an older post';
|
||||
cy.postMessageReplyInRHS(replyMessage);
|
||||
});
|
||||
|
||||
// # Login as test user
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// * Verify the toast is visible with correct message
|
||||
cy.get('div.toast').should('be.visible').contains('1 new message');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,113 @@
|
||||
// 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 @notifications
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {getRandomId} from '../../../utils';
|
||||
|
||||
describe('Notifications', () => {
|
||||
let testTeam;
|
||||
let firstUser;
|
||||
let secondUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
testTeam = team;
|
||||
|
||||
// # Create two users with same first name in username
|
||||
const firstUsername = `test${getRandomId()}`;
|
||||
cy.apiCreateUser({user: generateTestUser(firstUsername)}).then(({user: user1}) => {
|
||||
firstUser = user1;
|
||||
cy.apiAddUserToTeam(testTeam.id, firstUser.id);
|
||||
});
|
||||
|
||||
const secondUsername = `${firstUsername}.one`;
|
||||
cy.apiCreateUser({user: generateTestUser(secondUsername)}).then(({user: user2}) => {
|
||||
secondUser = user2;
|
||||
cy.apiAddUserToTeam(testTeam.id, secondUser.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T486 Users with the same firstname in their username should not get a mention when one of them leaves a channel', () => {
|
||||
// # Login as first user
|
||||
cy.apiLogin(firstUser);
|
||||
|
||||
cy.apiCreateChannel(testTeam.id, 'test_channel', 'Test Channel').then(({channel}) => {
|
||||
// # Visit the newly created channel as the first user and invite the second user
|
||||
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
|
||||
cy.apiAddUserToChannel(channel.id, secondUser.id);
|
||||
|
||||
// # Go to the 'Off Topic' channel and logout
|
||||
cy.get('#sidebarItem_off-topic', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').click();
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as the second user and go to the team site
|
||||
cy.apiLogin(secondUser);
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
|
||||
// * Verify that the channel that the first created is visible and that there is one unread mention (for being invited)
|
||||
cy.get(`#sidebarItem_${channel.name}`, {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').within(() => {
|
||||
cy.findByText(channel.display_name).should('be.visible');
|
||||
cy.get('#unreadMentions').should('have.text', '1');
|
||||
});
|
||||
|
||||
// # Go to the test channel
|
||||
cy.get(`#sidebarItem_${channel.name}`).click();
|
||||
|
||||
// # Verify that the mention does not exist anymore
|
||||
checkUnreadMentions(channel);
|
||||
|
||||
// # Leave the test channel and logout
|
||||
cy.uiOpenChannelMenu('Leave Channel');
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as first user and visit town square
|
||||
cy.apiLogin(firstUser);
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
|
||||
// * Check that the display name of the team the user was invited to is being correctly displayed
|
||||
cy.uiOpenUserMenu().findByText(`@${firstUser.username}`);
|
||||
|
||||
// # Close the user menu
|
||||
cy.uiGetSetStatusButton().click();
|
||||
|
||||
// * Check that 'Town Square' is currently being selected
|
||||
cy.get('.active').within(() => {
|
||||
cy.get('#sidebarItem_town-square').should('exist');
|
||||
});
|
||||
|
||||
// * Verify that the first user did not get a mention from the test channel when the second user left
|
||||
checkUnreadMentions(channel);
|
||||
});
|
||||
});
|
||||
|
||||
// Function to check that the unread mentions badge does not exist (the user was not mentioned in the test channel)
|
||||
function checkUnreadMentions(testChannel) {
|
||||
cy.get(`#sidebarItem_${testChannel.name}`).within(() => {
|
||||
cy.get('#unreadMentions').should('not.exist');
|
||||
});
|
||||
}
|
||||
|
||||
// Function to generate a test user with a random username
|
||||
function generateTestUser(username) {
|
||||
const randomId = getRandomId();
|
||||
|
||||
return {
|
||||
email: `${username}${randomId}@sample.mattermost.com`,
|
||||
username,
|
||||
password: 'passwd',
|
||||
first_name: `First${randomId}`,
|
||||
last_name: `Last${randomId}`,
|
||||
nickname: `Nickname${randomId}`,
|
||||
};
|
||||
}
|
||||
});
|
||||
Ссылка в новой задаче
Block a user