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

44
e2e-tests/cypress/tests/integration/channels/channel_sidebar/category.d.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,44 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/// <reference types="cypress" />
// ***************************************************************
// Each command should be properly documented using JSDoc.
// See https://jsdoc.app/index.html for reference.
// Basic requirements for documentation are the following:
// - Meaningful description
// - Each parameter with `@params`
// - Return value with `@returns`
// - Example usage with `@example`
// Custom command should follow naming convention of having `ui` prefix, e.g. `uiOpenFilePreviewModal`.
// ***************************************************************
declare namespace Cypress {
interface Chainable {
/**
* Create a new category
*
* @param [categoryName] category's name
*
* @example
* cy.uiCreateSidebarCategory();
*/
uiCreateSidebarCategory(categoryName?: string): Chainable;
/**
* Move a channel to a category.
* Open the channel menu, select Move to, and click either New Category or on the category.
*
* @param channelName channel's name
* @param categoryName category's name
* @param [newCategory=false] create a new category to move into
* @param [isChannelId=false] whether channelName is a channel ID
*
* @example
* cy.uiMoveChannelToCategory('Town Square', 'Favorites');
*/
uiMoveChannelToCategory(channelName: string, categoryName: string, newCategory: boolean = false, isChannelId: boolean = false): Chainable;
}
}

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

@@ -0,0 +1,169 @@
// 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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
import * as MESSAGES from '../../../fixtures/messages';
import {getAdminAccount} from '../../../support/env';
describe('Channel sidebar', () => {
const sysadmin = getAdminAccount();
let testTeam;
beforeEach(() => {
// # Start with a new team
cy.apiAdminLogin();
cy.apiInitSetup({loginAfter: true}).then(({team, townSquareUrl}) => {
testTeam = team;
cy.visit(townSquareUrl);
});
});
it('should display collapsed state when collapsed', () => {
// # Check that the CHANNELS group header is visible
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible').as('channelsGroup');
// * Verify that the category doesn't appear collapsed currently
cy.get('@channelsGroup').find('i').should('not.have.class', 'icon-rotate-minus-90');
// # Click on CHANNELS
cy.get('@channelsGroup').click();
// * Verify that the category now appears collapsed
cy.get('@channelsGroup').find('i').should('have.class', 'icon-rotate-minus-90');
});
it('should collapse channels that are not the currently viewed channel', () => {
// # Check that the CHANNELS group header is visible
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible').as('channelsGroup');
// * Verify that both channels are visible when not collapsed
cy.get('.SidebarChannelGroup').should('be.visible').as('sidebarChannelGroup');
cy.get('@sidebarChannelGroup').findByText('Town Square').should('exist').and('be.visible');
cy.get('@sidebarChannelGroup').findByText('Off-Topic').should('be.visible');
// # Click on CHANNELS
cy.get('@channelsGroup').click();
// * Verify that both channels are visible when not collapsed
cy.get('.SidebarChannelGroup').should('be.visible').as('sidebarChannelGroup');
cy.get('@sidebarChannelGroup').findByText('Town Square').should('be.visible');
cy.get('@sidebarChannelGroup').findByText('Off-Topic').should('not.exist');
});
it('should collapse channels that are not unread channels', () => {
const uniqueChannelName = MESSAGES.TINY;
// Create a new channel and post a message into it
cy.apiCreateChannel(testTeam.id, 'channel-test', uniqueChannelName, 'O', '', '', false).then(({channel}) => {
cy.postMessageAs({sender: sysadmin, message: MESSAGES.SMALL, channelId: channel.id});
// Force a reload to ensure the unread message displays
cy.reload();
cy.uiGetPostTextBox();
// # Check that the CHANNELS group header is visible
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible').as('channelsGroup');
// * Verify that all channels are visible
cy.get('.SidebarChannelGroup').should('be.visible').as('sidebarChannelGroup');
cy.get('.SidebarChannelGroup').findByText('Off-Topic').should('exist').and('be.visible');
cy.get('.SidebarChannelGroup').findByText(uniqueChannelName).should('exist').and('be.visible');
// # Click on CHANNELS
cy.get('@channelsGroup').click();
// * Verify that Off-Topic is no longer visible but Channel Test still is
cy.get('.SidebarChannelGroup').should('be.visible').as('sidebarChannelGroup');
cy.get('@sidebarChannelGroup').findByText('Off-Topic').should('not.exist');
cy.get('@sidebarChannelGroup').findByText(uniqueChannelName).should('be.visible');
});
});
it('should save collapsed state and remember the state on refresh', () => {
// # Check that the CHANNELS group header is visible
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
// * Verify that the category doesn't appear collapsed currently
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('be.visible').should('not.have.class', 'icon-rotate-minus-90');
// # Click on CHANNELS
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible').click();
// * Verify that the category appears collapsed
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('have.class', 'icon-rotate-minus-90');
// Wait for state to settle
// This is necessary since we have no observable way of finding out when the state actually settles so that it persists on reload
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(TIMEOUTS.FIVE_SEC);
// # Reload the page and wait
cy.reload();
cy.uiGetPostTextBox();
// * Verify that the category still appears collapsed after refresh
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('have.class', 'icon-rotate-minus-90');
// # Click on CHANNELS
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').click();
// * Verify that the category appears not collapsed after refresh
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('not.have.class', 'icon-rotate-minus-90');
// Wait for state to settle
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(TIMEOUTS.FIVE_SEC);
// # Reload the page and wait
cy.reload();
cy.uiGetPostTextBox();
// * Verify that the category still appears not collapsed after refresh
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('not.have.class', 'icon-rotate-minus-90');
});
it('should retain the collapsed state of categories when unread filter is enabled/disabled', () => {
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel Test').then(({channel}) => {
cy.postMessageAs({sender: sysadmin, message: 'Test', channelId: channel.id});
// * Verify that CHANNELS starts expanded
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('not.have.class', 'icon-rotate-minus-90');
// * Verify that all categories are visible
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('be.visible').should('not.have.class', 'icon-rotate-minus-90');
cy.get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES)').should('be.visible');
cy.get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES) i').should('be.visible').should('not.have.class', 'icon-rotate-minus-90');
// # Collapse CHANNELS
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').click();
// * Verify that CHANNELS is collapsed
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('have.class', 'icon-rotate-minus-90');
// # Enable the unread filter
cy.get('.SidebarFilters_filterButton').click();
// * Verify that the unread filter is enabled
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('be.visible');
// # Disable the unread filter
cy.get('.SidebarFilters_filterButton').click();
// * Verify that DIRECT MESSAGES is not collapsed but CHANNELS still is
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS) i').should('be.visible').should('have.class', 'icon-rotate-minus-90');
cy.get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES) i').should('be.visible').should('not.have.class', 'icon-rotate-minus-90');
});
});
});

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

@@ -0,0 +1,119 @@
// 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 @channel_sidebar
import {getAdminAccount} from '../../../support/env';
import {getRandomId} from '../../../utils';
import {clickCategoryMenuItem} from './helpers';
describe('Category muting', () => {
let testTeam;
let testUser;
before(() => {
cy.apiInitSetup({loginAfter: true}).then((({team, user}) => {
testTeam = team;
testUser = user;
cy.visit(`/${team.name}/channels/off-topic`);
// # Post any message
cy.postMessage('hello');
}));
});
it('MM-T3488 category headers should be muted and unmuted correctly', () => {
// * Verify that the Channels category and its channels start unmuted
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible').should('not.have.class', 'muted');
cy.get('#sidebarItem_town-square').should('not.have.class', 'muted');
cy.get('#sidebarItem_off-topic').should('not.have.class', 'muted');
// # Mute the category
clickCategoryMenuItem('CHANNELS', 'Mute Category');
// * Verify that the category has been muted
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('have.class', 'muted');
cy.get('#sidebarItem_town-square').should('have.class', 'muted');
cy.get('#sidebarItem_off-topic').should('have.class', 'muted');
// # Unmute the category
clickCategoryMenuItem('CHANNELS', 'Unmute Category');
// * Verify that the category is no longer muted
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('not.have.class', 'muted');
cy.get('#sidebarItem_town-square').should('not.have.class', 'muted');
cy.get('#sidebarItem_off-topic').should('not.have.class', 'muted');
});
it('MM-T3489_1 moving a channel into a muted category should mute it', () => {
// # Create a new category
cy.uiCreateSidebarCategory().then((category) => {
// # Mute the new category
clickCategoryMenuItem(category.displayName, 'Mute Category');
// * Verify that Town Square starts unmuted
cy.get('#sidebarItem_town-square').should('not.have.class', 'muted');
// * Verify that the new category is muted
cy.get(`.SidebarChannelGroupHeader:contains(${category.displayName})`).should('have.class', 'muted');
// # Move Town Square into the custom category
cy.uiMoveChannelToCategory('Town Square', category.displayName);
// * Verify that Town Square is now muted
cy.get('#sidebarItem_town-square').should('have.class', 'muted');
// # Move Town Square back to Channels
cy.uiMoveChannelToCategory('Town Square', 'Channels');
// * Verify that Town Square is now unmuted
cy.get('#sidebarItem_town-square').should('not.have.class', 'muted');
});
});
it('MM-T3489_2 being added to a new channel should not mute it, even if the Channels category is muted', () => {
// * Verify that the Channels category starts unmuted
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible').should('not.have.class', 'muted');
// # Mute Channels
clickCategoryMenuItem('CHANNELS', 'Mute Category');
cy.makeClient({user: getAdminAccount()}).then((client) => {
// # Have another user create a channel
const channelName = `channel${getRandomId()}`;
cy.wrap(client.createChannel({
display_name: channelName,
name: channelName,
team_id: testTeam.id,
type: 'O',
create_at: 0,
creator_id: '',
delete_at: 0,
extra_update_at: 0,
group_constrained: false,
header: '',
id: '',
last_post_at: 0,
purpose: '',
scheme_id: '',
total_msg_count: 0,
update_at: 0,
})).then((channel: Cypress.Channel) => {
// # And then invite us to it
cy.wrap(client.addToChannel(testUser.id, channel.id));
// * Verify that the test channel appears in the sidebar and is unmuted
cy.get(`#sidebarItem_${channel.name}`).should('be.visible').should('not.have.class', 'muted');
});
});
});
});

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

@@ -0,0 +1,158 @@
// 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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getRandomId} from '../../../utils';
import {clickSortCategoryMenuItem} from './helpers';
let testTeam;
let testUser;
describe('Category sorting', () => {
beforeEach(() => {
// # Login as test user and visit town-square
cy.apiAdminLogin();
cy.apiInitSetup({loginAfter: true}).then(({team, user}) => {
testTeam = team;
testUser = user;
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3834 Category sorting -- KNOWN ISSUE: MM-43576', () => {
const channelNames = [];
const categoryName = createCategoryFromSidebarMenu();
// # Create 5 channels and add them to a custom category
for (let i = 0; i < 5; i++) {
channelNames.push(createChannelAndAddToCategory(categoryName));
cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
}
// # Sort alphabetically
clickSortCategoryMenuItem(categoryName, 'Alphabetically');
// * Verify channels are sorted alphabetically
verifyAlphabeticalSortingOrder(categoryName, channelNames.length);
// # Add another channel
channelNames.push(createChannelAndAddToCategory(categoryName));
cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
// * Verify channels are still sorted alphabetically
verifyAlphabeticalSortingOrder(categoryName, channelNames.length);
// # Sort by recency
clickSortCategoryMenuItem(categoryName, 'Recent activity');
// # Sort channel names in reverse order that they were created (ie. most recent to least)
let sortedByRecencyChannelNames = channelNames.concat().reverse();
for (let i = 0; i < channelNames.length; i++) {
// * Verify that the channels are in reverse order that they were created
cy.get(`.SidebarChannelGroup:contains(${categoryName}) .NavGroupContent li:nth-child(${i + 1}) a[id^="sidebarItem_${sortedByRecencyChannelNames[i]}"]`).should('be.visible');
}
// # Add another channel
channelNames.push(createChannelAndAddToCategory(categoryName));
cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
// # Sort channel names in reverse order that they were created (ie. most recent to least)
sortedByRecencyChannelNames = channelNames.concat().reverse();
for (let i = 0; i < channelNames.length; i++) {
// * Verify that the channels are still in reverse order that they were created
cy.get(`.SidebarChannelGroup:contains(${categoryName}) .NavGroupContent li:nth-child(${i + 1}) a[id^="sidebarItem_${sortedByRecencyChannelNames[i]}"]`).should('be.visible');
}
// # Click on channel options of the oldest from the category
cy.get(`.SidebarChannelGroup:contains(${categoryName}) .NavGroupContent a[id^="sidebarItem_${channelNames[0]}"]`).should('be.visible').within(() => {
// # Open dropdown next to channel name
cy.get('.SidebarMenu').invoke('show').get('.SidebarMenu_menuButton').should('be.visible').click({force: true});
});
// # Open the channel menu, select Move to
cy.findAllByRole('menu', {name: 'Edit channel menu'}).should('be.visible').within(() => {
cy.findByText('Move to...').should('be.visible').trigger('mouseover');
});
// # Click on move to favorites
cy.findAllByRole('menu', {name: 'Move to submenu'}).should('be.visible').within(() => {
cy.findByText('Favorites').should('be.visible').click({force: true});
});
// * Verify the channel is now in Favourites
cy.get(`.SidebarChannelGroup:contains(FAVORITES) .NavGroupContent a[id^="sidebarItem_${channelNames[0]}"]`).should('be.visible');
channelNames.shift();
// # Sort manually
clickSortCategoryMenuItem(categoryName, 'Manually');
// # Add another channel
channelNames.push(createChannelAndAddToCategory(categoryName));
cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
// * Verify that the channel has been placed at the bottom of the category
cy.get(`.SidebarChannelGroup:contains(${categoryName}) .NavGroupContent li:nth-child(1) a[id^="sidebarItem_${channelNames[channelNames.length - 1]}"]`).should('be.visible');
});
});
function createChannelAndAddToCategory(categoryName) {
const channelName = `channel-${getRandomId()}`;
const userId = testUser.id;
cy.apiCreateChannel(testTeam.id, channelName, 'New Test Channel').then(({channel}) => {
// # Add the user to the channel
cy.apiAddUserToChannel(channel.id, userId).then(() => {
// # Move to a new category
cy.uiMoveChannelToCategory(channel.display_name, categoryName);
});
});
return channelName;
}
function verifyAlphabeticalSortingOrder(categoryName, length) {
// # Go through each channel to get its name
const sortedAlphabeticalChannelNames = [];
for (let i = 0; i < length; i++) {
// Grab the elements in the order that they appear in the sidebar
cy.get(`.SidebarChannelGroup:contains(${categoryName}) .NavGroupContent li:nth-child(${i + 1}) .SidebarChannelLinkLabel`).should('be.visible').invoke('text').then((text) => {
sortedAlphabeticalChannelNames.push(text);
// # Sort the names manually
const comparedSortedChannelNames = sortedAlphabeticalChannelNames.concat().sort((a, b) => a.localeCompare(b, 'en', {numeric: true}));
// * Verify that the sorted order matches the order they were already in
assert.deepEqual(sortedAlphabeticalChannelNames, comparedSortedChannelNames);
});
}
}
function createCategoryFromSidebarMenu() {
// # Start with a new category
const categoryName = `category-${getRandomId()}`;
// # Click on the sidebar menu dropdown
cy.findByLabelText('Add Channel Dropdown').click();
// # Click on create category link
cy.findByText('Create New Category').should('be.visible').click();
// # Verify that Create Category modal has shown up.
// # Wait for a while until the modal has fully loaded, especially during first-time access.
cy.get('#editCategoryModal').should('be.visible').wait(TIMEOUTS.HALF_SEC).within(() => {
cy.findByText('Create New Category').should('be.visible');
// # Enter category name and hit enter
cy.findByPlaceholderText('Name your category').should('be.visible').type(categoryName).type('{enter}');
});
return categoryName;
}

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

@@ -0,0 +1,128 @@
// 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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Category sorting', () => {
beforeEach(() => {
// # Login as test user and visit town-square
cy.apiAdminLogin();
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3916 Create Category character limit', () => {
// # Click on the sidebar menu dropdown
cy.findByLabelText('Add Channel Dropdown').click();
// # Click on create category link
cy.findByText('Create New Category').should('be.visible').click();
// # Add a name 26 characters in length e.g `abcdefghijklmnopqrstuvwxyz`
cy.get('#editCategoryModal').should('be.visible').wait(TIMEOUTS.HALF_SEC).within(() => {
cy.findByText('Create New Category').should('be.visible');
// # Enter category name
cy.findByPlaceholderText('Name your category').should('be.visible').type('abcdefghijklmnopqrstuvwxyz');
});
// * Verify error state and negative character count at the end of the textbox based on the number of characters the user has exceeded
cy.get('#editCategoryModal .MaxLengthInput.has-error').should('be.visible');
cy.get('#editCategoryModal .MaxLengthInput__validation').should('be.visible').should('contain', '-4');
// * Verify Create button is disabled.
cy.get('#editCategoryModal .GenericModal__button.confirm').should('be.visible').should('be.disabled');
// # Use backspace to remove 4 characters
cy.get('#editCategoryModal .MaxLengthInput').should('be.visible').type('{backspace}{backspace}{backspace}{backspace}');
// * Verify error state and negative character count at the end of the textbox are no longer displaying
cy.get('#editCategoryModal .MaxLengthInput.has-error').should('not.exist');
cy.get('#editCategoryModal .MaxLengthInput__validation').should('not.exist');
// * Verify Create button is enabled
cy.get('#editCategoryModal .GenericModal__button.confirm').should('be.visible').should('not.be.disabled');
// Click Create
cy.get('#editCategoryModal .GenericModal__button.confirm').should('be.visible').click();
// Verify new category is created
cy.findByLabelText('abcdefghijklmnopqrstuv').should('be.visible');
});
// // Commented out since we've had to disable sticky headings because of issues with the menu components
// it('MM-T3864 Sticky category headers', () => {
// const categoryName = createCategoryFromSidebarMenu();
// // # Move test channel to Favourites
// cy.get(`#sidebarItem_${testChannel.name}`).parent().then((element) => {
// // # Get id of the channel
// const id = element[0].getAttribute('data-rbd-draggable-id');
// cy.get(`#sidebarItem_${testChannel.name}`).parent('li').within(() => {
// // # Open dropdown next to channel name
// cy.get('.SidebarMenu').invoke('show').get('.SidebarMenu_menuButton').should('be.visible').click({force: true});
// // # Favourite the channel
// cy.get(`#favorite-${id} button`).should('be.visible').click({force: true});
// });
// });
// // # Create 15 channels and add them to a custom category
// for (let i = 0; i < 15; i++) {
// createChannelAndAddToCategory(categoryName);
// cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
// }
// // # Create 10 channels and add them to Favourites
// for (let i = 0; i < 10; i++) {
// createChannelAndAddToFavourites();
// cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
// }
// // # Scroll to the center of the channel list
// cy.get('#SidebarContainer .scrollbar--view').scrollTo('center', {ensureScrollable: false});
// // * Verify that both the 'More Unreads' label and the category header are visible
// cy.get('#unreadIndicatorTop').should('be.visible');
// cy.get('#SidebarContainer .SidebarChannelGroupHeader:contains(FAVORITES)').should('be.visible');
// // # Scroll to the bottom of the list
// cy.get('#SidebarContainer .scrollbar--view').scrollTo('bottom', {ensureScrollable: false});
// // * Verify that the 'More Unreads' label is still visible but the category is not
// cy.get('#unreadIndicatorTop').should('be.visible');
// cy.get('#SidebarContainer .SidebarChannelGroupHeader:contains(FAVORITES)').should('not.be.visible');
// });
});
// // Commented out since we've had to disable sticky headings because of issues with the menu components
// function createChannelAndAddToFavourites() {
// const userId = testUser.id;
// cy.apiCreateChannel(testTeam.id, `channel-${getRandomId()}`, 'New Test Channel').then(({channel}) => {
// // # Add the user to the channel
// cy.apiAddUserToChannel(channel.id, userId).then(() => {
// // # Move to a new category
// cy.get(`#sidebarItem_${channel.name}`).parent().then((element) => {
// // # Get id of the channel
// const id = element[0].getAttribute('data-rbd-draggable-id');
// cy.get(`#sidebarItem_${channel.name}`).parent('li').within(() => {
// // # Open dropdown next to channel name
// cy.get('.SidebarMenu').invoke('show').get('.SidebarMenu_menuButton').should('be.visible').click({force: true});
// // # Favourite the channel
// cy.get(`#favorite-${id} button`).should('be.visible').click({force: true});
// });
// });
// });
// });
// }

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

@@ -0,0 +1,148 @@
// 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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getAdminAccount} from '../../../support/env';
import {getRandomId} from '../../../utils';
function verifyChannelSwitch(displayName, url) {
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').should('contain', displayName);
cy.url().should('include', url);
}
describe('Channel sidebar', () => {
const sysadmin = getAdminAccount();
let testTeam;
let testUser;
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({team, user}) => {
testTeam = team;
testUser = user;
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('should switch channels when clicking on a channel in the sidebar', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Click on Off Topic
cy.get('.SidebarChannel:contains(Off-Topic)').should('be.visible').click();
// * Verify that the channel changed
cy.url().should('include', `/${teamName}/channels/off-topic`);
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').should('contain', 'Off-Topic');
// # Click on Town Square
cy.get('.SidebarChannel:contains(Town Square)').should('be.visible').click();
// * Verify that the channel changed
verifyChannelSwitch('Town Square', `/${teamName}/channels/town-square`);
});
it('should mark channel as read and unread in sidebar', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// * Verify that both Off Topic and Town Square are read
cy.get('.SidebarChannel:not(.unread):contains(Off-Topic)').should('be.visible');
cy.get('.SidebarChannel:not(.unread):contains(Town Square)').should('be.visible');
// # Have another user post in the Off Topic channel
cy.apiGetChannelByName(teamName, 'off-topic').then(({channel}) => {
cy.postMessageAs({sender: sysadmin, message: 'Test', channelId: channel.id});
});
// * Verify that Off Topic is unread and Town Square is read
cy.get('.SidebarChannel.unread:contains(Off-Topic)').should('be.visible');
cy.get('.SidebarChannel:not(.unread):contains(Town Square)').should('be.visible');
});
it('should remove channel from sidebar after leaving it', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Switch to Off Topic
cy.visit(`/${teamName}/channels/off-topic`);
// # Wait for the channel to change
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').should('contain', 'Off-Topic');
// # Click on the channel menu and select Leave Channel
cy.get('#channelHeaderTitle').click();
cy.get('#channelLeaveChannel').should('be.visible').click();
// * Verify that we've switched to Town Square
verifyChannelSwitch('Town Square', `/${teamName}/channels/town-square`);
// * Verify that Off Topic has disappeared from the sidebar
cy.get('.SidebarChannel:contains(Off-Topic)').should('not.exist');
});
it('MM-T1684 should remove channel from sidebar after deleting it', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Switch to Off Topic
cy.visit(`/${teamName}/channels/off-topic`);
// # Wait for the channel to change
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').should('contain', 'Off-Topic');
// # Click on the channel menu and select Archive Channel
cy.get('#channelHeaderTitle').click();
cy.get('#channelArchiveChannel').should('be.visible').click();
cy.get('#deleteChannelModalDeleteButton').should('be.visible').click();
// * Verify that we've switched to Town Square
verifyChannelSwitch('Town Square', `/${teamName}/channels/town-square`);
// * Verify that Off Topic has disappeared from the sidebar
cy.get('.SidebarChannel:contains(Off-Topic)').should('not.exist');
});
it('MM-T3351 Channels created from another instance should immediately appear in the sidebar', () => {
// # Go to Town Square on the test team
cy.visit(`/${testTeam.name}/channels/town-square`);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(testTeam.display_name);
// # Create a new channel
cy.apiCreateChannel(testTeam.id, `channel-${getRandomId()}`, 'New Test Channel').then(({channel}) => {
// # Add the user to the channel
cy.apiAddUserToChannel(channel.id, testUser.id).then(() => {
// * Verify that new channel appears in the sidebar;
cy.get(`#sidebarItem_${channel.name}`).should('be.visible');
});
});
});
});

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

@@ -0,0 +1,108 @@
// 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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getRandomId} from '../../../utils';
import {clickCategoryMenuItem} from './helpers';
describe('Channel sidebar', () => {
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3161_1 should create a new category from sidebar menu -- KNOWN ISSUE: MM-42576', () => {
const categoryName = createCategoryFromSidebarMenu();
// * Check if the category exists
cy.findByLabelText(categoryName).should('be.visible');
});
it('MM-T3161_2 should create a new category from category menu -- KNOWN ISSUE: MM-42576', () => {
const categoryName = createCategoryFromSidebarMenu();
// # Create new category from category menu
clickCategoryMenuItem(categoryName, 'Create New Category');
const newCategoryName = `category-${getRandomId()}`;
cy.get('#editCategoryModal input').type(newCategoryName).type('{enter}');
// * Check if the newly created category exists
cy.findByLabelText(newCategoryName).should('be.visible');
});
it('MM-T3161_3 move an existing channel to a new category -- KNOWN ISSUE: MM-42576', () => {
const newCategoryName = `category-${getRandomId()}`;
// # Move to a new category
cy.uiMoveChannelToCategory('Off-Topic', newCategoryName, true);
// * Check if the newly created category exists
cy.findByLabelText(newCategoryName).should('be.visible');
});
it('MM-T3163 Rename a category -- KNOWN ISSUE: MM-42576', () => {
const categoryName = createCategoryFromSidebarMenu();
// # Rename category from category menu
clickCategoryMenuItem(categoryName, 'Rename Category');
const renameCategory = `category-${getRandomId()}`;
// # Rename category
cy.get('#editCategoryModal input').clear().type(renameCategory).type('{enter}');
// * Check if the previous category exist
cy.findByLabelText(categoryName).should('not.exist');
// * Check if the renamed category exists
cy.findByLabelText(renameCategory).should('be.visible');
});
it('MM-T3165 Delete a category -- KNOWN ISSUE: MM-42576', () => {
const categoryName = createCategoryFromSidebarMenu();
// # Delete category from category menu
clickCategoryMenuItem(categoryName, 'Delete Category');
// # Click on delete button
cy.get('.GenericModal__button.delete').click();
// * Check if the deleted category exists
cy.findByLabelText(categoryName).should('not.exist');
});
});
function createCategoryFromSidebarMenu() {
// # Start with a new category
const categoryName = `category-${getRandomId()}`;
// # Click on the sidebar menu dropdown
cy.findByLabelText('Add Channel Dropdown').click();
// # Click on create category link
cy.findByText('Create New Category').should('be.visible').click();
// # Verify that Create Category modal has shown up.
// # Wait for a while until the modal has fully loaded, especially during first-time access.
cy.get('#editCategoryModal').should('be.visible').wait(TIMEOUTS.HALF_SEC).within(() => {
cy.findByText('Create New Category').should('be.visible');
// # Enter category name and hit enter
cy.findByPlaceholderText('Name your category').should('be.visible').type(categoryName).type('{enter}');
});
return categoryName;
}

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

@@ -0,0 +1,96 @@
// 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 @dm_category
import * as TIMEOUTS from '../../../fixtures/timeouts';
const SpaceKeyCode = 32;
const DownArrowKeyCode = 40;
describe('MM-T3156 DM category', () => {
let testUser;
const usernames = [];
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true, promoteNewUserAsAdmin: true}).then(({team, user}) => {
testUser = user;
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3156_1 Should open DM modal on click of + in category header', () => {
cy.findByLabelText('DIRECT MESSAGES').parents('.SidebarChannelGroup').within(() => {
cy.get('.SidebarChannelGroupHeader_addButton').click();
});
cy.get('#moreDmModal').should('be.visible');
cy.get('#moreDmModal .close').click();
});
it('MM-T3156_2 should order DMs based on recent interactions', () => {
const usersPrefixes = ['a', 'c', 'd', 'j', 'p', 'u', 'x', 'z'];
usersPrefixes.forEach((prefix) => {
// # Create users with prefixes in alphabetical order
cy.apiCreateUser({prefix}).then(({user: newUser}) => {
cy.apiCreateDirectChannel([testUser.id, newUser.id]).then(({channel}) => {
// # Post message in The DM channel
cy.postMessageAs({sender: newUser, message: 'test', channelId: channel.id});
// add usernames in array for reference
usernames.push(newUser.username);
});
});
});
// get DM category group
cy.findByLabelText('DIRECT MESSAGES').parents('.SidebarChannelGroup').within(() => {
const usernamesReversed = [...usernames].reverse();
cy.get('.NavGroupContent').children().each(($el, index) => {
// * Verify that the usernames are in reverse order i.e ordered by recent activity
cy.wrap($el).find('.SidebarChannelLinkLabel').should('contain', usernamesReversed[index]);
});
});
});
it('MM-T3156_3 should order DMs alphabetically ', () => {
// # Hover over DIRECT MESSAGES and click channel options
cy.get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES) .SidebarMenu').invoke('show').
get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES) .SidebarMenu_menuButton').should('be.visible').click();
// # Change sorting to be alphabetical
cy.findByText('Sort').trigger('mouseover');
cy.findByText('Alphabetically').click();
cy.findByLabelText('DIRECT MESSAGES').should('be.visible').
parents('.SidebarChannelGroup').within(() => {
cy.get('.NavGroupContent').children().each(($el, index) => {
// * Verify that the usernames are in alphabetical order
cy.wrap($el).findByText(usernames[index]).should('be.visible');
});
});
});
it('MM-T3156_4 should not be able to rearrange DMs', () => {
cy.get('button[aria-label="DIRECT MESSAGES"]').parents('.SidebarChannelGroup').within(() => {
// # Rearrange the first dm to be below second one
cy.get(`.SidebarChannel:contains(${usernames[0]}) > .SidebarLink`).
trigger('keydown', {keyCode: SpaceKeyCode}).
trigger('keydown', {keyCode: DownArrowKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC).
trigger('keydown', {keyCode: SpaceKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC);
cy.get('.NavGroupContent').children().each(($el, index) => {
// * Verify that the usernames are in alphabetical order
cy.wrap($el).find('.SidebarChannelLinkLabel').should('contain', usernames[index]);
});
});
});
});

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

@@ -0,0 +1,249 @@
// 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 @dm_category
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('DM category', () => {
let testUser;
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true, promoteNewUserAsAdmin: true}).then(({team, user}) => {
testUser = user;
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T2016_1 Opening a new DM should make sure the DM appears in the sidebar', () => {
// # Create a new user to start a DM with
cy.apiCreateUser().then(({user}) => {
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// # Click the + button next to the DM category
clickOnNewDMButton();
// # Search for the new user's username
cy.get('#selectItems input').
typeWithForce(user.username).
wait(TIMEOUTS.HALF_SEC);
// # Select the user you searched for
cy.get(`#displayedUserName${user.username}`).click().wait(TIMEOUTS.HALF_SEC);
// # Click Go
cy.findByTestId('saveSetting').should('be.visible').click();
// * Verify that a DM channel shows up in the sidebar
cy.get(`.SidebarLink:contains(${user.username})`).should('be.visible');
});
});
it('MM-T2016_2 Opening a new DM with a bot should make sure the DM appears in the sidebar, and the bot icon should be present', () => {
// # Create a new user to start a DM with
cy.apiCreateBot().then(({bot}) => {
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// * Verify that a DM channel shows up in the sidebar
cy.get(`.SidebarLink:contains(${bot.username})`).should('be.visible');
// * Verify bot icon appears
cy.get(`.SidebarLink:contains(${bot.username})`).find('.Avatar').should('exist').
and('have.attr', 'src').
then((avatar) => cy.request({url: avatar.attr('src'), encoding: 'binary'})).
should(({body}) => {
// * Verify it matches default bot avatar
cy.fixture('bot-default-avatar.png', 'binary').should('deep.equal', body);
});
});
});
it('MM-T2016_3 Receiving a DM from a user should show the DM in the sidebar', () => {
// # Create a new user to start a DM with
cy.apiCreateUser().then(({user}) => {
cy.apiCreateDirectChannel([testUser.id, user.id]).then(({channel}) => {
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// # Post a message as the new user
cy.postMessageAs({
sender: user,
message: `Hey ${testUser.username}`,
channelId: channel.id,
});
// * Verify that a DM channel shows up in the sidebar
cy.get(`.SidebarLink:contains(${user.username})`).should('be.visible').click();
// # Close the new DM
cy.uiOpenChannelMenu('Close Direct Message');
// * Verify that the DM channel disappears
cy.get(`.SidebarLink:contains(${user.username})`).should('not.exist');
// # Post a message as the new user again
cy.postMessageAs({
sender: user,
message: `Hello ${testUser.username}`,
channelId: channel.id,
});
// * Verify that the DM channel re-appears in the sidebar
cy.get(`.SidebarLink:contains(${user.username})`).should('be.visible');
});
});
});
it('MM-T2017_1 Opening a new GM should make sure the GM appears in the sidebar', () => {
// # Create 2 new users to start a GM with
cy.apiCreateUser().then(({user}) => {
cy.apiCreateUser().then(({user: user2}) => {
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// # Click the + button next to the DM category
clickOnNewDMButton();
// # Search for the new user's username
cy.get('#selectItems input').
typeWithForce(user.username).
wait(TIMEOUTS.HALF_SEC);
// # Select the user you searched for
cy.get(`#displayedUserName${user.username}`).click().wait(TIMEOUTS.HALF_SEC);
// # Search for the 2nd user's username
cy.get('#selectItems input').
typeWithForce(user2.username).
wait(TIMEOUTS.HALF_SEC);
// # Select the user you searched for
cy.get(`#displayedUserName${user2.username}`).click().wait(TIMEOUTS.HALF_SEC);
// # Click Go
cy.findByTestId('saveSetting').should('be.visible').click();
// * Verify that a GM channel shows up in the sidebar
cy.get(`.SidebarLink:contains(${user.username})`).should('contain', user2.username).should('be.visible');
});
});
});
it('MM-T2017_2 Receiving a DM from a user should show the DM in the sidebar', () => {
// # Create 2 new users to start a GM with
cy.apiCreateUser().then(({user}) => {
cy.apiCreateUser().then(({user: user2}) => {
cy.apiCreateGroupChannel([testUser.id, user.id, user2.id]).then(({channel}) => {
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// # Post a message as the new user
cy.postMessageAs({
sender: user,
message: `Hey ${testUser.username}`,
channelId: channel.id,
});
// * Verify that a GM channel shows up in the sidebar
cy.get(`#sidebarItem_${channel.name}`).should('be.visible').click();
// # Close the new GM
cy.uiOpenChannelMenu('Close Group Message');
// * Verify that the GM channel disappears
cy.get(`.SidebarLink:contains(${user.username})`).should('not.exist');
// # Post a message as the new user again
cy.postMessageAs({
sender: user,
message: `Hello ${testUser.username}`,
channelId: channel.id,
});
// * Verify that the DM channel re-appears in the sidebar
cy.get(`#sidebarItem_${channel.name}`).should('be.visible');
});
});
});
});
it('MM-T2017_3 Should not double already open GMs in a custom category', () => {
// # Create 2 new users to start a GM with
cy.apiCreateUser().then(({user}) => {
cy.apiCreateUser().then(({user: user2}) => {
cy.apiCreateGroupChannel([testUser.id, user.id, user2.id]).then(({channel}) => {
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// # Post a message as the new user
cy.postMessageAs({
sender: user,
message: `Hey ${testUser.username}`,
channelId: channel.id,
});
// * Verify that a GM channel shows up in the sidebar
cy.get(`#sidebarItem_${channel.name}`).should('be.visible').click();
// # Move the GM to a custom category and enter new category name and Save
cy.uiMoveChannelToCategory(channel.name, `Category ${user.username}`, true, true);
// * Verify that the GM has moved to a new category
cy.get(`.SidebarChannelGroup:contains(Category ${user.username})`).find(`#sidebarItem_${channel.name}`).should('be.visible');
// # Go to Town Square
cy.get('#sidebarItem_town-square').should('be.visible').click();
// * Verify we are now in town square
cy.url().should('include', '/channels/town-square');
// # Click the + button next to the DM category
clickOnNewDMButton();
// # Search for the new user's username
cy.get('#selectItems input').
typeWithForce(user.username).
wait(TIMEOUTS.HALF_SEC);
// # Select the user you searched for
cy.get(`#displayedUserName${user.username}`).click().wait(TIMEOUTS.HALF_SEC);
// # Search for the 2nd user's username
cy.get('#selectItems input').
typeWithForce(user2.username).
wait(TIMEOUTS.HALF_SEC);
// # Select the user you searched for
cy.get(`#displayedUserName${user2.username}`).click().wait(TIMEOUTS.HALF_SEC);
// # Click Go
cy.findByTestId('saveSetting').should('be.visible').click();
// * Verify that the GM is in the original category and that it hasn't duplicated in the DM category
cy.get(`.SidebarChannelGroup:contains(Category ${user.username})`).find(`#sidebarItem_${channel.name}`).should('be.visible');
cy.get('.SidebarChannelGroup:contains(DIRECT MESSAGES)').find(`#sidebarItem_${channel.name}`).should('not.exist');
// * Verify that we switched to the GM
cy.url().should('include', `/messages/${channel.name}`);
});
});
});
});
});
function clickOnNewDMButton() {
cy.uiGetLHS().within(() => {
cy.findByText('DIRECT MESSAGES').should('be.visible').parents('.SidebarChannelGroupHeader').within(() => {
cy.findByLabelText('Write a direct message').should('be.visible').click();
});
});
}

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

@@ -0,0 +1,101 @@
// 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 @dm_category
import * as MESSAGES from '../../../fixtures/messages';
describe('DM/GM filtering and sorting', () => {
let testUser;
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true, promoteNewUserAsAdmin: true}).then(({user, townSquareUrl}) => {
testUser = user;
cy.visit(townSquareUrl);
});
});
it('MM-T2003 Number of direct messages to show', () => {
const receivingUser = testUser;
cy.intercept('**/api/v4/users/status/ids**').as('userStatus');
// * Verify that we can see the sidebar
cy.uiGetLHSHeader();
// # Collapse the DM category (so that we can check all unread DMs quickly without the sidebar scrolling being an issue)
cy.get('button.SidebarChannelGroupHeader_groupButton:contains(DIRECT MESSAGES)').should('be.visible').click();
// # Create 41 DMs (ie. one over the max displayable read limit)
for (let i = 0; i < 41; i++) {
// # Create a new user to have a DM with
cy.apiCreateUser().then(({user}) => {
cy.apiCreateDirectChannel([receivingUser.id, user.id]).then(({channel}) => {
// # Post a message as the new user
cy.postMessageAs({
sender: user,
message: MESSAGES.TINY,
channelId: channel.id,
});
cy.wait('@userStatus');
// * Verify that the DM count is now correct
cy.get('.SidebarChannelGroup:contains(DIRECT MESSAGES) a[id^="sidebarItem"]').should('be.visible').should('have.length', Math.min(i + 1, 2));
// # Click on the new DM channel to mark it read
cy.get(`#sidebarItem_${channel.name}`).should('be.visible').click();
});
});
}
// # Expand the DM category (so that we can check all unread DMs quickly without the sidebar scrolling being an issue)
cy.get('button.SidebarChannelGroupHeader_groupButton:contains(DIRECT MESSAGES)').should('be.visible').click();
// * Verify that there are 40 DMs shown in the sidebar
cy.get('.SidebarChannelGroup:contains(DIRECT MESSAGES) a[id^="sidebarItem"]').should('have.length', 40);
// # Go to Sidebar Settings
cy.uiOpenSettingsModal('Sidebar');
// * Verify that the default setting for DMs shown is 40
cy.get('#limitVisibleGMsDMsDesc').should('be.visible').should('contain', '40');
// # Click Edit
cy.get('#limitVisibleGMsDMsEdit').should('be.visible').click();
// # Change the value to All Direct Messages
cy.get('#limitVisibleGMsDMs').should('be.visible').click();
cy.get('.react-select__option:contains(All Direct Messages)').should('be.visible').click();
// # Save and close Settings
cy.uiSaveAndClose();
// * Verify that there are 41 DMs shown in the sidebar
cy.get('.SidebarChannelGroup:contains(DIRECT MESSAGES) a[id^="sidebarItem"]').should('have.length', 41);
// # Go to Sidebar Settings
cy.uiOpenSettingsModal('Sidebar');
// # Click Edit
cy.get('#limitVisibleGMsDMsEdit').should('be.visible').click();
// # Change the value to 10
cy.get('#limitVisibleGMsDMs').should('be.visible').click();
cy.get('.react-select__option:contains(10)').should('be.visible').click();
// # Save and close Settings
cy.uiSaveAndClose();
// * Verify that there are 10 DMs shown in the sidebar
cy.get('.SidebarChannelGroup:contains(DIRECT MESSAGES) a[id^="sidebarItem"]').should('have.length', 10);
});
});

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

@@ -0,0 +1,56 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @dm_category
describe('DM on sidebar', () => {
let testUser;
let otherUser;
before(() => {
cy.apiCreateUser().then(({user}) => {
otherUser = user;
});
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({user, townSquareUrl}) => {
testUser = user;
cy.visit(townSquareUrl);
});
});
it('MM-T3832 DMs/GMs should not be removed from the sidebar when only viewed (no message)', () => {
// # Create DM with other user
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(({channel}) => {
// # Post a message as the new user
cy.postMessageAs({
sender: otherUser,
message: `Hey ${testUser.username}`,
channelId: channel.id,
});
// # Click on the new DM channel to mark it read
cy.get(`#sidebarItem_${channel.name}`).should('be.visible').click();
// # Click on Town Square
cy.get('.SidebarLink:contains(Town Square)').should('be.visible').click();
// * Verify we're on Town Square
cy.url().should('contain', 'town-square');
// # Refresh the page
cy.visit('/');
// * Verify that the DM we just read remains in the sidebar
cy.get(`#sidebarItem_${channel.name}`).should('be.visible');
});
});
});

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

@@ -0,0 +1,104 @@
// 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 @smoke
// Group: @channels @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Channel sidebar', () => {
const SpaceKeyCode = 32;
const DownArrowKeyCode = 40;
let teamName;
let channelName;
before(() => {
cy.apiCreateCustomAdmin({loginAfter: true});
});
beforeEach(() => {
// # Start with a new team
cy.apiCreateTeam('team', 'Team').then(({team}) => {
teamName = team.display_name;
cy.apiCreateChannel(team.id, 'channel', 'Channel').then(({channel}) => {
channelName = channel.display_name;
});
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('should move channel to correct place when dragging channel within category', () => {
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// * Verify the order is correct to begin with
cy.uiGetLhsSection('CHANNELS').within(() => {
cy.get('.SidebarChannel > .SidebarLink').should('be.visible').as('fromChannelSidebarLink');
cy.get('@fromChannelSidebarLink').eq(0).should('contain', channelName);
cy.get('@fromChannelSidebarLink').eq(1).should('contain', 'Off-Topic');
cy.get('@fromChannelSidebarLink').eq(2).should('contain', 'Town Square');
});
// # Perform drag using keyboard
cy.get('.SidebarChannel:contains(Off-Topic) > .SidebarLink').
trigger('keydown', {keyCode: SpaceKeyCode}).
trigger('keydown', {keyCode: DownArrowKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC).
trigger('keydown', {keyCode: SpaceKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC);
// * Verify that the elements have been re-ordered
cy.uiGetLhsSection('CHANNELS').within(() => {
cy.get('.SidebarChannel > .SidebarLink').as('toChannelSidebarLink');
cy.get('@toChannelSidebarLink').eq(0).should('contain', channelName);
cy.get('@toChannelSidebarLink').eq(1).should('contain', 'Town Square');
cy.get('@toChannelSidebarLink').eq(2).should('contain', 'Off-Topic');
});
});
it('should move category to correct place', () => {
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Get channel group button and wait for Channels to be visible since for some reason it shows up later...
cy.get('.SidebarChannelGroupHeader_groupButton > div[data-rbd-drag-handle-draggable-id]').should('be.visible').as('fromChannelGroup');
cy.get('@fromChannelGroup').should('contain', 'CHANNELS');
// * Verify the order is correct to begin with
cy.get('@fromChannelGroup').eq(0).should('contain', 'CHANNELS');
cy.get('@fromChannelGroup').eq(1).should('contain', 'DIRECT MESSAGES');
// # Perform drag using keyboard
cy.get('@fromChannelGroup').eq(0).should('contain', 'CHANNELS').
trigger('keydown', {keyCode: SpaceKeyCode}).
trigger('keydown', {keyCode: DownArrowKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC).
trigger('keydown', {keyCode: SpaceKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC);
// * Verify that the elements have been re-ordered
cy.get('.SidebarChannelGroupHeader_groupButton > div[data-rbd-drag-handle-draggable-id]').as('toChannelGroup');
cy.get('@toChannelGroup').eq(1).should('contain', 'CHANNELS');
cy.get('@toChannelGroup').eq(0).should('contain', 'DIRECT MESSAGES');
});
it('should retain focus within the channel sidebar after dragging and dropping with the keyboard', () => {
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Perform drag using keyboard
cy.get('.SidebarChannel:contains(Off-Topic) > .SidebarLink').
click().
focus().
trigger('keydown', {key: ' ', keyCode: SpaceKeyCode}).
trigger('keydown', {keyCode: DownArrowKeyCode, force: true}).
wait(TIMEOUTS.THREE_SEC).
trigger('keydown', {key: ' ', keyCode: SpaceKeyCode, force: true}).wait(TIMEOUTS.THREE_SEC);
// * Verify that the current focused element is the channel
cy.focused().should('contain', 'Off-Topic');
});
});

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

@@ -0,0 +1,153 @@
// 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 @channel_sidebar
import {getAdminAccount} from '../../../support/env';
describe('Channel sidebar - group unreads separately', () => {
let testTeam;
let testChannel;
beforeEach(() => {
cy.apiAdminLogin().then(() => {
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
testTeam = team;
testChannel = channel;
cy.visit(`/${team.name}/channels/town-square`);
// # Toggle the unreads category setting
enableOrDisableUnreadsCategory();
// # Receive a message to the new channel
cy.postMessageAs({sender: getAdminAccount(), message: 'test message', channelId: testChannel.id});
});
});
});
it('MM-T3719_1 Unreads category should show only if there is an unread message', () => {
// * Verify UNREADS category is shown and that the channel is in there
cy.get('.SidebarChannelGroup:contains(UNREADS)').should('be.visible').within(() => {
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('be.visible');
cy.get(`.SidebarChannel.unread:contains(${testChannel.display_name})`).should('be.visible');
});
// # Click on the unread channel
cy.get(`.SidebarChannel.unread .SidebarLink:contains(${testChannel.display_name})`).should('be.visible').click();
// * Verify we've switched to the new channel
cy.url().should('include', `/${testTeam.name}/channels/${testChannel.name}`);
// * Verify the channel is no longer unread but hasn't left the unreads category
cy.get('.SidebarChannelGroup:contains(UNREADS)').should('be.visible').get(`.SidebarChannel:not(.unread):contains(${testChannel.display_name})`).should('be.visible');
// # Switch to another channel
cy.get('.SidebarLink:contains(Town Square)').should('be.visible').click();
// * Verify unreads category has disappeared
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('not.exist');
// * Verify channel is in the CHANNELS category
cy.get('.SidebarChannelGroup:contains(CHANNELS)').should('be.visible').get(`.SidebarChannel:contains(${testChannel.display_name})`).should('be.visible');
});
it('MM-T3719_2 Unreads category should disappear when the setting is turned off', () => {
// * Verify UNREADS category is shown and that the channel is in there
cy.get('.SidebarChannelGroup:contains(UNREADS)').should('be.visible').within(() => {
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('be.visible');
cy.get(`.SidebarChannel.unread:contains(${testChannel.display_name})`).should('be.visible');
});
// # Disable the unreads category
enableOrDisableUnreadsCategory(false);
// * Verify unreads category has disappeared
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('not.exist');
// * Verify that the channel is in the CHANNELS category
cy.get('.SidebarChannelGroup:contains(CHANNELS)').should('be.visible').get(`.SidebarChannel.unread:contains(${testChannel.display_name})`).should('be.visible');
});
it('MM-T3719_3 Channels marked as unread should appear in the unreads category', () => {
// # Click on the unread channel
cy.get(`.SidebarChannel.unread .SidebarLink:contains(${testChannel.display_name})`).should('be.visible').click();
// # Switch to another channel
cy.get('.SidebarLink:contains(Town Square)').should('be.visible').click();
// * Verify that the channel is currently in the CHANNELS category
cy.get('.SidebarChannelGroup:contains(CHANNELS)').should('be.visible').get(`.SidebarChannel:not(.unread):contains(${testChannel.display_name})`).should('be.visible');
// # Switch back to the test channel
cy.get(`.SidebarChannel:not(.unread) .SidebarLink:contains(${testChannel.display_name})`).should('be.visible').click();
// # Mark the last message as unread
cy.getLastPostId().then((postId) => {
cy.uiClickPostDropdownMenu(postId, 'Mark as Unread');
});
// * Verify that the channel appears in the UNREADS section
cy.get('.SidebarChannelGroup:contains(UNREADS)').should('be.visible').get(`.SidebarChannel.unread:contains(${testChannel.display_name})`).should('be.visible');
});
it('MM-T3719_4 Read channels should not enter the unreads category', () => {
// # Switch to a read channel
cy.get('.SidebarLink:contains(Off-Topic)').should('be.visible').click();
// * Verify channel is not in the UNREADS category
cy.get('.SidebarChannelGroup:contains(CHANNELS)').should('be.visible').get('.SidebarChannel:not(.unread):contains(Off-Topic)').should('be.visible');
});
it('MM-T4655 Leaving an unread channel when unread category is ON', () => {
// # Click on the unread channel
cy.get(`.SidebarChannel.unread .SidebarLink:contains(${testChannel.display_name})`).should('be.visible').click();
// # Mark the last message as unread
cy.getLastPostId().then((postId) => {
cy.uiClickPostDropdownMenu(postId, 'Mark as Unread');
});
// * Verify that the channel appears in the UNREADS section
cy.get('.SidebarChannelGroup:contains(UNREADS)').should('be.visible').get(`.SidebarChannel.unread:contains(${testChannel.display_name})`).should('be.visible');
// # Leave the channel
cy.uiLeaveChannel();
// * User should be redirect to Town Square
cy.url().should('include', '/channels/town-square');
});
});
function toggleOnOrOffUnreadsCategory(toggleOn = true) {
// # Go to Sidebar Settings
cy.uiOpenSettingsModal('Sidebar');
cy.get('#showUnreadsCategoryEdit').click();
if (toggleOn) {
cy.findByTestId('showUnreadsCategoryOn').click();
} else {
cy.findByTestId('showUnreadsCategoryOff').click();
}
}
function enableOrDisableUnreadsCategory(enable = true) {
toggleOnOrOffUnreadsCategory(enable);
cy.uiSave();
if (enable) {
cy.get('#showUnreadsCategoryDesc').should('have.text', 'On');
} else {
cy.get('#showUnreadsCategoryDesc').should('have.text', 'Off');
}
cy.uiClose();
}

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

@@ -0,0 +1,32 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import * as TIMEOUTS from '../../../fixtures/timeouts';
export function clickCategoryMenuItem(categoryDisplayName, menuItemText, isSubMenu = false) {
cy.get('#SidebarContainer').should('be.visible').within(() => {
cy.findByText(categoryDisplayName).should('exist').parents('.SidebarChannelGroupHeader').within(() => {
cy.findByLabelText('Category options').should('exist').click({force: true});
});
});
cy.wait(TIMEOUTS.HALF_SEC);
cy.findByRole('menu', {name: 'Edit category menu'}).should('be.visible').within(() => {
if (isSubMenu) {
cy.findByText(menuItemText).should('exist').trigger('mouseover', {force: true});
} else {
cy.findByText(menuItemText).should('exist').click({force: true});
}
});
}
export function clickSortCategoryMenuItem(categoryDisplayName, menuItemText) {
clickCategoryMenuItem(categoryDisplayName, 'Sort', true);
cy.wait(TIMEOUTS.HALF_SEC);
cy.findAllByRole('menu', {name: 'Sort submenu'}).should('be.visible').within(() => {
cy.findByText(menuItemText).should('exist').click({force: true});
});
}

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

@@ -0,0 +1,61 @@
// 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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getRandomId} from '../../../utils';
describe('Channel sidebar', () => {
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('should not show history arrows on the regular webapp', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// * Verify both buttons don't exist
cy.get('.SidebarChannelNavigator_backButton').should('not.exist');
cy.get('.SidebarChannelNavigator_forwardButton').should('not.exist');
});
it('should switch to channel when using the channel switcher', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Click the Channel Switcher button
cy.get('.SidebarChannelNavigator_jumpToButton').should('be.visible').click();
// # Search for Off-Topic and press Enter
cy.get('.channel-switcher__suggestion-box #quickSwitchInput').click().type('Off-Topic');
cy.wait(TIMEOUTS.ONE_HUNDRED_MILLIS);
cy.get('.channel-switcher__suggestion-box #suggestionList').should('be.visible');
cy.get('.channel-switcher__suggestion-box .suggestion-list__item').its('length').should('eq', 3);
cy.get('.channel-switcher__suggestion-box .suggestion-list__item').contains(teamName).click();
// * Verify that the channel switcher is closed and the active channel is now Off-Topic
cy.get('.channel-switch__modal').should('not.exist');
cy.url().should('include', `/${teamName}/channels/off-topic`);
cy.get('#channelHeaderTitle').should('contain', 'Off-Topic');
cy.get('.SidebarChannel.active:contains(Off-Topic)').should('be.visible');
});
});

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

@@ -0,0 +1,105 @@
// 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 @channel_sidebar
import {getAdminAccount} from '../../../support/env';
describe('Channel switching', () => {
const sysadmin = getAdminAccount();
const cmdOrCtrl = Cypress.platform === 'darwin' ? '{cmd}' : '{ctrl}';
let testTeam;
let testChannel;
beforeEach(() => {
// # Start with a new team
cy.apiAdminLogin();
cy.apiInitSetup({
loginAfter: true,
channelPrefix: {name: 'c1', displayName: 'C1'},
}).then(({team, channel, offTopicUrl}) => {
testTeam = team;
testChannel = channel;
cy.visit(offTopicUrl);
});
});
it('should switch channels when pressing the alt + arrow hotkeys', () => {
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(testTeam.display_name);
// # Post any message
cy.postMessage('hello');
// # Press alt + up
cy.get('body').type('{alt}', {release: false}).type('{uparrow}').type('{alt}', {release: true});
// * Verify that the channel changed to the test channel
cy.url().should('include', `/${testTeam.name}/channels/${testChannel.name}`);
cy.get('#channelHeaderTitle').should('contain', testChannel.display_name);
// # Press alt + down
cy.get('body').type('{alt}', {release: false}).type('{downarrow}').type('{alt}', {release: true});
// * Verify that the channel changed to the off-topic
cy.url().should('include', `/${testTeam.name}/channels/off-topic`);
cy.get('#channelHeaderTitle').should('contain', 'Off-Topic');
});
it('should switch to unread channels when pressing the alt + shift + arrow hotkeys', () => {
cy.apiCreateChannel(testTeam.id, 'c2', 'C2');
// # Have another user post a message in the new channel
cy.postMessageAs({sender: sysadmin, message: 'Test', channelId: testChannel.id});
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(testTeam.display_name);
// # Post any message
cy.postMessage('hello');
cy.getCurrentChannelId().as('offTopicId');
// # Press alt + shift + up
cy.get('body').type('{alt}{shift}', {release: false}).type('{uparrow}').type('{alt}{shift}', {release: true});
// * Verify that the channel changed to Test Channel and skipped Off Topic
cy.url().should('include', `/${testTeam.name}/channels/${testChannel.name}`);
cy.get('#channelHeaderTitle').should('contain', testChannel.display_name);
// # Have another user post a message in the town square
cy.get('@offTopicId').then((offTopicId) => cy.postMessageAs({sender: sysadmin, message: 'Test', channelId: offTopicId.text()}));
// # Press alt + shift + down
cy.get('body').type('{alt}{shift}', {release: false}).type('{downarrow}').type('{alt}{shift}', {release: true});
// * Verify that the channel changed back to 'Off-Topic' and skipped test channel 2
cy.url().should('include', `/${testTeam.name}/channels/off-topic`);
cy.get('#channelHeaderTitle').should('contain', 'Off-Topic');
});
it('should open and close channel switcher on ctrl/cmd + k', () => {
// * Verify that the channel has loaded
cy.get('#channelHeaderTitle').should('be.visible');
// # Press ctrl/cmd + k
cy.get('body').type(cmdOrCtrl, {release: false}).type('k').type(cmdOrCtrl, {release: true});
// * Verify that the modal has been opened
cy.get('.channel-switcher').should('be.visible');
// # Press ctrl/cmd + k
cy.get('body').type(cmdOrCtrl, {release: false}).type('k').type(cmdOrCtrl, {release: true});
// * Verify that the modal has been closed
cy.get('.channel-switcher').should('not.exist');
});
});

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

@@ -0,0 +1,56 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @channel_sidebar
import {getRandomId} from '../../../utils';
describe('New category badge', () => {
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3312 should show the new badge until a channel is added to the category', () => {
const categoryName = `new-${getRandomId()}`;
// # Create a new category
cy.uiCreateSidebarCategory(categoryName).as('newCategory');
cy.contains('.SidebarChannelGroup', categoryName, {matchCase: false}).within(() => {
// * Verify that the new category has been added to the sidebar and that it has the required badge and drop target
cy.get('.SidebarCategory_newLabel').should('be.visible');
cy.get('.SidebarCategory_newDropBox').should('be.visible');
});
// # Move Town Square into the new category
cy.uiMoveChannelToCategory('Town Square', categoryName);
cy.contains('.SidebarChannelGroup', categoryName, {matchCase: false}).within(() => {
// * Verify that the new category badge and drop target have been removed
cy.get('.SidebarCategory_newLabel').should('not.exist');
cy.get('.SidebarCategory_newDropBox').should('not.exist');
});
// # Move Town Square out of the new category
cy.uiMoveChannelToCategory('Town Square', 'Channels');
cy.contains('.SidebarChannelGroup', categoryName, {matchCase: false}).within(() => {
// * Verify that Town Square has moved out of the new category
cy.get('#sidebarItem_town-square').should('not.exist');
// * Verify that the new category badge and drop target did not reappear
cy.get('.SidebarCategory_newLabel').should('not.exist');
cy.get('.SidebarCategory_newDropBox').should('not.exist');
});
});
});

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

@@ -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 @channel_sidebar
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getRandomId} from '../../../utils';
describe('Channel sidebar', () => {
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('should create a new channel when using the new channel dropdown', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Create new channel
const channelName = 'Test Channel';
cy.uiCreateChannel({name: channelName}).then(() => {
// * Verify that new channel is in the sidebar and is active
cy.url().should('include', `/${teamName}/channels/test-channel`);
cy.get('#channelHeaderTitle').should('contain', channelName);
cy.get(`.SidebarChannel.active:contains(${channelName})`).should('be.visible');
});
});
it('should join a new public channel when using the new channel dropdown', () => {
// # Start with a new team
const teamName = `team-${getRandomId()}`;
cy.createNewTeam(teamName, teamName);
// * Verify that we've switched to the new team
cy.uiGetLHSHeader().findByText(teamName);
// # Switch to Off Topic
cy.visit(`/${teamName}/channels/off-topic`);
// # Wait for the channel to change
cy.get('#channelHeaderTitle', {timeout: TIMEOUTS.HALF_MIN}).should('contain', 'Off-Topic');
// # Click on the channel menu and select Leave Channel
cy.get('#channelHeaderTitle').click();
cy.get('#channelLeaveChannel').click();
// * Verify that we've switched to Town Square
cy.get('#channelHeaderTitle').should('contain', 'Town Square');
cy.url().should('include', `/${teamName}/channels/town-square`);
// # Click the New Channel Dropdown button
cy.get('.AddChannelDropdown_dropdownButton').should('be.visible').click();
// # Click the Browse Channels dropdown item
cy.get('.AddChannelDropdown .MenuItem:contains(Browse Channels) button').should('be.visible').click();
// * Verify that the more channels modal is visible
cy.get('.more-modal').should('be.visible');
// Click the Off-Topic channel
cy.get('.more-modal button:contains(Off-Topic)').should('be.visible').click();
// Verify that new channel is in the sidebar and is active
cy.get('.more-modal').should('not.exist');
cy.url().should('include', `/${teamName}/channels/off-topic`);
cy.get('#channelHeaderTitle').should('contain', 'Off-Topic');
cy.get('.SidebarChannel.active:contains(Off-Topic)').should('be.visible');
});
});

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

@@ -0,0 +1,46 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {clickCategoryMenuItem} from './helpers';
// ***************************************************************
// - [#] 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 @channel_sidebar
describe('Sidebar category menu', () => {
before(() => {
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3171_1 Verify that the 3-dot menu on the Channels Category contains an option to Create New Category', () => {
clickCategoryMenuItem('CHANNELS', 'Create New Category');
cy.get('body').type('{esc}', {force: true});
});
it('MM-T3171_2 Verify that the 3-dot menu on the Favourites Category contains an option to Create New Category, and that the Create New Category modal shows', () => {
// * Verify that the channel starts in the CHANNELS category
cy.contains('.SidebarChannelGroup', 'CHANNELS').as('channelsCategory');
cy.get('@channelsCategory').find('#sidebarItem_town-square');
// # Open the channel menu and select the Favorite option
cy.uiGetChannelSidebarMenu('Town Square').within(() => {
cy.findByText('Favorite').click();
});
// * Verify that the channel has moved to the FAVORITES category
cy.contains('.SidebarChannelGroup', 'FAVORITES').find('#sidebarItem_town-square');
// # Verify that Create New Category exists on Favorites category and click on it
clickCategoryMenuItem('FAVORITES', 'Create New Category');
cy.get('body').type('{esc}', {force: true});
});
});

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

@@ -0,0 +1,192 @@
// 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 @channel_sidebar
import {
beMuted,
beRead,
beUnmuted,
beUnread,
} from '../../../support/assertions';
import {getAdminAccount} from '../../../support/env';
import {getRandomId, stubClipboard} from '../../../utils';
describe('Sidebar channel menu', () => {
const sysadmin = getAdminAccount();
const townSquare = 'Town Square';
let teamName;
let userName;
before(() => {
cy.apiInitSetup({loginAfter: true}).then(({team, user}) => {
teamName = team.name;
userName = user.username;
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T3349_1 should be able to mark a channel as read', () => {
// # Start in Town Square
cy.uiGetLHS().within(() => {
cy.findByText(townSquare).should('be.visible');
});
cy.get('#channelHeaderTitle').should('contain', townSquare);
// # Save the ID of the Town Square channel for later
cy.getCurrentChannelId().as('townSquareId');
// # Switch to the Off Topic channel
cy.get('#sidebarItem_off-topic').click();
cy.get('#channelHeaderTitle').should('contain', 'Off-Topic');
// # Have another user send a message in the Town Square
cy.get('@townSquareId').then((townSquareId) => {
cy.postMessageAs({
sender: sysadmin,
message: 'post1',
channelId: `${townSquareId}`,
});
});
// * Verify that the Town Square channel is now unread
cy.get('#sidebarItem_town-square').should(beUnread);
// # Open the channel menu and select the Mark as Read option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Mark as Read').click();
});
// * Verify that the Town Square channel is now read
cy.get('#sidebarItem_town-square').should(beRead);
});
it('MM-T3349_2 should be able to favorite/unfavorite a channel', () => {
// * Verify that the channel starts in the CHANNELS category
cy.uiGetLhsSection('CHANNELS').findByText(townSquare).should('be.visible');
// # Open the channel menu and select the Favorite option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Favorite').click();
});
// * Verify that the channel has moved to the FAVORITES category
cy.uiGetLhsSection('FAVORITES').findByText(townSquare).should('be.visible');
// # Open the channel menu and select the Unfavorite option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Unfavorite').click();
});
// * Verify that the channel has moved back to the CHANNELS category
cy.uiGetLhsSection('CHANNELS').findByText(townSquare).should('be.visible');
});
it('MM-T3349_3 should be able to mute/unmute a channel', () => {
// * Verify that the channel starts unmuted
cy.get('#sidebarItem_town-square').should(beUnmuted);
// # Open the channel menu and select the Mute Channel option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Mute Channel').click();
});
// * Verify that the channel is now muted
cy.get('#sidebarItem_town-square').should(beMuted);
// # Open the channel menu and select the Unmute Channel option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Unmute Channel').click();
});
// // * Verify that the channel is no longer muted
cy.get('#sidebarItem_town-square').should(beUnmuted);
});
it('MM-T3349_4 should be able to move channels between categories', () => {
const categoryName = `new-${getRandomId()}`;
// * Verify that the channel starts in the CHANNELS category
cy.uiGetLhsSection('CHANNELS').findByText(townSquare).should('be.visible');
// # Move the channel into a new category
cy.uiMoveChannelToCategory(townSquare, categoryName, true);
// * Verify that Town Square has moved into the new category
cy.uiGetLhsSection(categoryName).findByText(townSquare).should('be.visible');
cy.uiGetLhsSection('CHANNELS').findByText(townSquare).should('not.exist');
// # Move the channel back to Channels
cy.uiMoveChannelToCategory(townSquare, 'Channels');
// * Verify that Town Square has moved back to Channels
cy.uiGetLhsSection(categoryName).findByText(townSquare).should('not.exist');
cy.uiGetLhsSection('CHANNELS').findByText(townSquare).should('be.visible');
});
it('MM-T3349_5 should be able to copy the channel link', () => {
stubClipboard().as('clipboard');
// # Open the channel menu and select the Copy Link option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Copy Link').click();
});
// Ensure that the clipboard contents are correct
cy.get('@clipboard').its('wasCalled').should('eq', true);
cy.location().then((location) => {
cy.get('@clipboard').its('contents').should('eq', `${location.origin}/${teamName}/channels/town-square`);
});
});
it('MM-T3349_6 should be able to open the add other users to the channel', () => {
// # Open the channel menu and select the Add Members option
cy.uiGetChannelSidebarMenu(townSquare).within(() => {
cy.findByText('Add Members').click();
});
// * Verify that the modal appears and then close it
cy.get('#addUsersToChannelModal').should('be.visible').findByText('Add people to Town Square');
cy.uiClose();
});
it('MM-T3350 Mention badge should remain hidden as long as the channel/dm/gm menu is open', () => {
// # Start in Town Square
cy.get('#sidebarItem_town-square').click();
cy.get('#channelHeaderTitle').should('contain', townSquare);
// # Save the ID of the Town Square channel for later
cy.getCurrentChannelId().as('townSquareId');
// # Switch to the Off Topic channel
cy.get('#sidebarItem_off-topic').click();
cy.get('#channelHeaderTitle').should('contain', 'Off-Topic');
// # Have another user send a message in the Town Square
cy.get('@townSquareId').then((townSquareId) => {
cy.postMessageAs({
sender: sysadmin,
message: `@${userName} post1`,
channelId: `${townSquareId}`,
});
});
// * Verify that a mention badge appears
cy.get('#sidebarItem_town-square .badge').should('be.visible');
// # Open the channel menu
cy.get('#sidebarItem_town-square').find('.SidebarMenu_menuButton').click({force: true});
// * Verify that the mention badge disappears
cy.get('#sidebarItem_town-square .badge').should('not.be.visible');
});
});

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

@@ -0,0 +1,348 @@
// 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 @channel_sidebar
import {
beMuted,
beRead,
beUnread,
} from '../../../support/assertions';
import {getAdminAccount} from '../../../support/env';
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getRandomId} from '../../../utils';
describe('Channel sidebar unread filter', () => {
const randomId = getRandomId();
let testUser;
let teamId;
before(() => {
// # Setting up for CRT
cy.apiUpdateConfig({
ServiceSettings: {
ThreadAutoFollow: true,
CollapsedThreads: 'default_off',
},
});
// # Setting up user
cy.apiInitSetup({loginAfter: true}).then(({user, team}) => {
testUser = user;
teamId = team.id;
cy.visit('/');
});
});
it('MM-T3441 should change the filter label when the unread filter changes state', () => {
// * Verify that the unread filter is in all channels state
cy.findByRole('application', {name: 'channel sidebar region'}).within(() => {
cy.findAllByText('UNREADS').should('not.exist');
cy.findAllByRole('button', {name: 'CHANNELS'}).should('be.visible');
cy.findAllByRole('button', {name: 'DIRECT MESSAGES'}).should('be.visible');
});
enableUnreadFilter();
// * Verify that the unread filter is in filter by unread state
cy.findByRole('application', {name: 'channel sidebar region'}).within(() => {
cy.findAllByText('UNREADS').should('be.visible');
cy.findAllByRole('button', {name: 'CHANNELS'}).should('not.exist');
cy.findAllByRole('button', {name: 'DIRECT MESSAGES'}).should('not.exist');
});
disableUnreadFilter();
// * Verify that the unread filter is back in all channels state
cy.findByRole('application', {name: 'channel sidebar region'}).within(() => {
cy.findAllByText('UNREADS').should('not.exist');
cy.findAllByRole('button', {name: 'CHANNELS'}).should('be.visible');
cy.findAllByRole('button', {name: 'DIRECT MESSAGES'}).should('be.visible');
});
});
it('MM-T3442 should not persist the state of the unread filter on reload', () => {
// * Verify that all categories are visible
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
cy.get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES)').should('be.visible');
enableUnreadFilter();
// # Reload the page
cy.reload();
// * Verify that all categories are visible again
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
cy.get('.SidebarChannelGroupHeader:contains(DIRECT MESSAGES)').should('be.visible');
});
it('MM-T3443 should only show unread channels with filter enabled', () => {
// * Verify that the unread filter is not enabled
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
// # Create a couple of new channels, one of which is unread and one of which is not
const readChannelName = `read${randomId}`;
const unreadChannelName = `unread${randomId}`;
createChannel(teamId, readChannelName);
createChannel(teamId, unreadChannelName, 'test');
// * Verify that the channels are correctly read and unread
cy.get(`#sidebarItem_${readChannelName}`).should(beRead);
cy.get(`#sidebarItem_${unreadChannelName}`).should(beUnread);
enableUnreadFilter();
// * Verify that the read channel has been hidden
cy.get(`#sidebarItem_${readChannelName}`).should('not.exist');
// * Verify that the unread channel is still visible
cy.get(`#sidebarItem_${unreadChannelName}`).should('be.visible').should(beUnread);
disableUnreadFilter();
// * Verify that the read channel has reappeared
cy.get(`#sidebarItem_${readChannelName}`).should('be.visible').should(beRead);
});
it('MM-T3444 should always show the current channel, even if it is not unread', () => {
// * Verify that the unread filter is not enabled
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
// # Switch to the town square
cy.get('#sidebarItem_town-square').click();
cy.get('#channelHeaderTitle').should('contain', 'Town Square');
// * Verify that the Town Square is not unread
cy.get('#sidebarItem_town-square').should('be.visible').should(beRead);
enableUnreadFilter();
// * Verify that the Town Square is still visible
cy.get('#sidebarItem_town-square').should('be.visible').should(beRead);
disableUnreadFilter();
});
it('MM-T3445 should hide channels once they have been read', () => {
// * Verify that the unread filter is not enabled
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
// # Create a couple of new channels, both of which are unread
const channelName1 = `channel1${randomId}`;
const channelName2 = `channel2${randomId}`;
createChannel(teamId, channelName1, 'test');
createChannel(teamId, channelName2, 'test');
enableUnreadFilter();
// * Verify that both channels are visible
cy.get(`#sidebarItem_${channelName1}`).should('be.visible').should(beUnread);
cy.get(`#sidebarItem_${channelName2}`).should('be.visible').should(beUnread);
// # Visit the first channel
cy.get(`#sidebarItem_${channelName1}`).click();
// * Verify that both channels are still visible
cy.get(`#sidebarItem_${channelName1}`).should('be.visible').should(beRead);
cy.get(`#sidebarItem_${channelName2}`).should('be.visible').should(beUnread);
// # Visit the second channel
cy.get(`#sidebarItem_${channelName2}`).click();
// * Verify that the first channel has disappeared
cy.get(`#sidebarItem_${channelName1}`).should('not.exist');
cy.get(`#sidebarItem_${channelName2}`).should('be.visible').should(beRead);
disableUnreadFilter();
});
it('MM-T3446 should only show unread channels with filter enabled', () => {
// * Verify that the unread filter is not enabled
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
// # Create a couple of new channels
const mentionedChannelName = `mentioned${randomId}`;
const unreadChannelName = `muted${randomId}`;
[mentionedChannelName, unreadChannelName].forEach((channelName, index) => {
createChannel(teamId, channelName).then(({channel}) => {
// # Open and mute a channel
cy.uiGetChannelSidebarMenu(channel.display_name).within(() => {
cy.findByText('Mute Channel').should('be.visible').click();
});
// # Go to other channel
cy.get('#sidebarItem_town-square').click({force: true});
// # Post a message from other user
cy.postMessageAs({
sender: getAdminAccount(),
message: index === 0 ? `@${testUser.username}` : 'test',
channelId: channel.id,
});
});
});
// * Verify that the first channel has a mention and is muted
cy.get(`#sidebarItem_${mentionedChannelName}`).should(beUnread).should(beMuted);
cy.get(`#sidebarItem_${mentionedChannelName} .badge`).should('be.visible');
// * Verify that the second channel does not have a mention and is muted
cy.get(`#sidebarItem_${unreadChannelName}`).should(beRead).should(beMuted);
cy.get(`#sidebarItem_${unreadChannelName} .badge`).should('not.exist');
enableUnreadFilter();
// * Verify that the muted channel with a mention is still visible
cy.get(`#sidebarItem_${mentionedChannelName}`).should('be.visible');
// * Verify that the muted channel without a mention has been hidden
cy.get(`#sidebarItem_${unreadChannelName}`).should('not.exist');
disableUnreadFilter();
// * Verify that the muted channel without a mention has reappeared
cy.get(`#sidebarItem_${unreadChannelName}`).should('be.visible');
});
it('MM-T5192 should toggle between unreads and all channels with shortcut usage', () => {
// * Verify that the unread filter is not enabled
cy.get('.SidebarChannelGroupHeader:contains(CHANNELS)').should('be.visible');
// # Create a couple of new channels, one of which is unread and one of which is not
const readChannelName = `shortcutread${randomId}`;
const unreadChannelName = `shortcutunread${randomId}`;
createChannel(teamId, readChannelName);
createChannel(teamId, unreadChannelName, 'test');
// * Verify that the channels are correctly read and unread
cy.get(`#sidebarItem_${readChannelName}`).should(beRead);
cy.get(`#sidebarItem_${unreadChannelName}`).should(beUnread);
enableUnreadFilterWithShortcut();
// * Verify that the read channel has been hidden
cy.get(`#sidebarItem_${readChannelName}`).should('not.exist');
// * Verify that the unread channel is still visible
cy.get(`#sidebarItem_${unreadChannelName}`).should('be.visible').should(beUnread);
disableUnreadFilterWithShortcut();
// * Verify that the read channel has reappeared
cy.get(`#sidebarItem_${readChannelName}`).should('be.visible').should(beRead);
});
it('MM-T5208 continue to show global Threads item when unread filter is enabled', () => {
// # Verify there is no Unread category on the sidebar
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('not.exist');
// * Verify that the unread filter is in all channels state
cy.findByRole('application', {name: 'channel sidebar region'}).within(() => {
cy.findAllByText('UNREADS').should('not.exist');
cy.findAllByRole('button', {name: 'CHANNELS'}).should('be.visible');
cy.findAllByRole('button', {name: 'DIRECT MESSAGES'}).should('be.visible');
});
// * Verify Threads global item is present on the sidebar
cy.apiSaveCRTPreference(testUser.id, 'on');
cy.get('.SidebarGlobalThreads').should('exist');
// * The unreads tab button does NOT have a blue dot (unread indicator; no unread threads)
cy.get('#threads-list-unread-button .dot').should('not.exist');
// # Create a couple of new channels, one of which is unread and one of which is not
const readChannelName = `globalthreadread${randomId}`;
const unreadChannelName = `globalthreadunread${randomId}`;
createChannel(teamId, readChannelName);
createChannel(teamId, unreadChannelName, 'test in unread channel');
// * Verify that the channels are correctly read and unread
cy.get(`#sidebarItem_${readChannelName}`).should(beRead);
cy.get(`#sidebarItem_${unreadChannelName}`).should(beUnread);
// # Enable the unread filter
enableUnreadFilter();
// * Verify that the unread filter is in filter by unread state
cy.findByRole('application', {name: 'channel sidebar region'}).within(() => {
cy.findAllByText('UNREADS').should('be.visible');
cy.findAllByRole('button', {name: 'CHANNELS'}).should('not.exist');
cy.findAllByRole('button', {name: 'DIRECT MESSAGES'}).should('not.exist');
});
// * Verify that the read channel has been hidden
cy.get(`#sidebarItem_${readChannelName}`).should('not.exist');
// * Verify that the unread channel is still visible
cy.get(`#sidebarItem_${unreadChannelName}`).should('be.visible').should(beUnread);
// * Verify that Threads item is still visible on the sidebar despite not having any unread threads
cy.get('.SidebarGlobalThreads').should('exist');
// # Disable the unread filter
disableUnreadFilter();
// * Verify that the read channel has reappeared
cy.get(`#sidebarItem_${readChannelName}`).should('be.visible').should(beRead);
// * Verify that the unread filter is back in all channels state
cy.findByRole('application', {name: 'channel sidebar region'}).within(() => {
cy.findAllByText('UNREADS').should('not.exist');
cy.findAllByRole('button', {name: 'CHANNELS'}).should('be.visible');
cy.findAllByRole('button', {name: 'DIRECT MESSAGES'}).should('be.visible');
});
});
});
function enableUnreadFilter() {
// # Enable the unread filter
cy.get('.SidebarFilters_filterButton').click();
// * Verify that the unread filter is enabled
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('be.visible');
}
function disableUnreadFilter() {
// # Enable the unread filter
cy.get('.SidebarFilters_filterButton').click();
// * Verify that the unread filter is disabled
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('not.exist');
}
function enableUnreadFilterWithShortcut() {
// # Enable the unread filter with shorcut
cy.get('body').cmdOrCtrlShortcut('{shift}U');
// * Verify that the unread filter is enabled
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('be.visible');
}
function disableUnreadFilterWithShortcut() {
// # Enable the unread filter with shortcut
cy.get('body').cmdOrCtrlShortcut('{shift}U');
// * Verify that the unread filter is disabled
cy.get('.SidebarChannelGroupHeader:contains(UNREADS)').should('not.exist');
}
function createChannel(teamId, channelName, message?) {
return cy.apiCreateChannel(teamId, channelName, channelName, 'O', '', '', false).then(({channel}) => {
if (message) {
cy.wait(TIMEOUTS.THREE_SEC);
cy.postMessageAs({sender: getAdminAccount(), message, channelId: channel.id});
}
return cy.wrap({channel});
});
}