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

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

@@ -0,0 +1,126 @@
// 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 @emoji
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getCustomEmoji, verifyLastPostedEmoji} from './helpers';
describe('Custom emojis', () => {
let testTeam;
let testUser;
let otherUser;
let offTopicUrl;
const largeEmojiFile = 'gif-image-file.gif';
const largeEmojiFileResized = 'gif-image-file-resized.gif';
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiInitSetup().then(({team, user}) => {
testTeam = team;
testUser = user;
offTopicUrl = `/${team.name}/channels/off-topic`;
});
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
}).then(() => {
cy.apiLogin(testUser);
cy.visit(offTopicUrl);
});
});
it('MM-T2181 Custom emoji - add large -- KNOWN ISSUE: MM-44768', () => {
const {customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add custom emoji
cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Attached image file and wait to be loaded
cy.get('input#select-emoji').attachFile(largeEmojiFile);
cy.wait(TIMEOUTS.FIVE_SEC);
// # Save custom emoji
saveCustomEmoji(testTeam.name);
// # Go back to home channel
cy.visit(offTopicUrl);
// # Open emoji picker
cy.uiOpenEmojiPicker();
// # Search emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmojiWithColons, {delay: TIMEOUTS.QUARTER_SEC});
// * Get list of emojis based on search text
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
cy.findAllByTestId('emojiItem').children('img').first().should('have.class', 'emoji-category--custom');
// # Post a message with the emoji
cy.uiGetPostTextBox().clear({force: true}).type(customEmojiWithColons.substring(0, 10));
// * Suggestion list should appear
cy.get('#suggestionList').should('be.visible');
// * Emoji name should appear in the list
cy.findByText(customEmojiWithColons).should('be.visible');
// # Hit enter to select from suggestion list and enter to post
cy.uiGetPostTextBox().type('{enter}').type('{enter}');
// * Check that the emoji image appears in the message - extract the image url and compare with local image
verifyLastPostedEmoji(customEmojiWithColons, largeEmojiFileResized);
// # Reload the page
cy.reload();
// * Check that the emoji image appears in the message - extract the image url and compare with local image
verifyLastPostedEmoji(customEmojiWithColons, largeEmojiFileResized);
});
});
function saveCustomEmoji(teamName) {
// # Click on Save
cy.findByText('Save').click();
// # Wait until new custom emoji has been added
const checkFn = () => {
return cy.url().then((url) => {
return !url.includes('/emoji/add');
});
};
const options = {
timeout: TIMEOUTS.ONE_MIN,
interval: TIMEOUTS.FIVE_SEC,
errorMsg: 'Timeout error waiting for custom emoji to be saved',
};
cy.waitUntil(checkFn, options);
// * Should return to list of custom emojis
cy.url().should('include', `${teamName}/emoji`);
cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible');
}

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

@@ -0,0 +1,184 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @emoji
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getCustomEmoji} from './helpers';
describe('Custom emojis', () => {
let testTeam;
let testUser;
let otherUser;
let offTopicUrl;
const tooLargeEmojiFile = 'huge-image.jpg';
const animatedGifEmojiFile = 'animated-gif-image-file.gif';
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiInitSetup().then(({team, user}) => {
testTeam = team;
testUser = user;
offTopicUrl = `/${team.name}/channels/off-topic`;
});
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
}).then(() => {
cy.apiLogin(testUser);
cy.visit(offTopicUrl);
});
});
it('MM-T3668 User cant add custom emoji with the same name as a system one', () => {
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name and click on save
cy.get('#name').type('croissant');
cy.get('.backstage-form__footer').within(($form) => {
cy.uiSave().wait(TIMEOUTS.FIVE_SEC);
// * Check for error saying that the emoji icon is a system one
cy.wrap($form).find('.has-error').should('be.visible').and('have.text', 'This name is already in use by a system emoji. Please choose another name.');
});
});
it('MM-T2180 Custom emoji - cancel out of add', () => {
const {customEmoji} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmoji);
// # Select emoji image
cy.get('input#select-emoji').attachFile('mattermost-icon.png');
// # Click on Cancel
cy.get('.backstage-form__footer').findByText('Cancel').click().wait(TIMEOUTS.FIVE_SEC);
// # Go back to home channel
cy.visit(offTopicUrl);
// # Open emoji picker
cy.uiOpenEmojiPicker();
// # Search emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmoji, {delay: TIMEOUTS.QUARTER_SEC});
// * Validate that we cannot find the emoji name in the search result list
cy.get('.no-results__title').should('be.visible').and('have.text', 'No results for "' + customEmoji + '"');
});
it('MM-T2182 Custom emoji - animated gif', () => {
const {customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add custom emoji
cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible').click();
// # Type emoji name
cy.get('#name').should('be.visible').type(customEmojiWithColons);
// # Attached image file and wait to be loaded
cy.get('input#select-emoji').attachFile(animatedGifEmojiFile);
cy.wait(TIMEOUTS.FIVE_SEC);
// # Save custom emoji
saveCustomEmoji(testTeam.name);
// # Go back to home channel
cy.visit(offTopicUrl);
// # Post a message with the emoji
cy.postMessage(customEmojiWithColons);
// # Open emoji picker
cy.uiOpenEmojiPicker();
// # Search emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmojiWithColons, {delay: TIMEOUTS.QUARTER_SEC});
// * Get list of emojis based on search text
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
cy.findAllByTestId('emojiItem').children('img').first().should('have.class', 'emoji-category--custom');
});
it('MM-T2183 Custom emoji - try to add too large', () => {
const {customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(tooLargeEmojiFile);
// * Is the image loaded?
cy.get('.add-emoji__filename').should('have.text', tooLargeEmojiFile);
cy.get('.backstage-form__footer').within(($form) => {
// # Click on Save
cy.uiSave().wait(TIMEOUTS.FIVE_SEC);
// * Check for error
cy.wrap($form).find('.has-error').should('be.visible').and('have.text', 'Unable to create emoji. Image must be less than 512 KiB in size.');
});
});
});
function saveCustomEmoji(teamName) {
// # Click on Save
cy.findByText('Save').click();
// # Wait until new custom emoji has been added
const checkFn = () => {
return cy.url().then((url) => {
return !url.includes('/emoji/add');
});
};
const options = {
timeout: TIMEOUTS.ONE_MIN,
interval: TIMEOUTS.FIVE_SEC,
errorMsg: 'Timeout error waiting for custom emoji to be saved',
};
cy.waitUntil(checkFn, options);
// * Should return to list of custom emojis
cy.url().should('include', `${teamName}/emoji`);
cy.findByRole('button', {name: 'Add Custom Emoji'}).should('be.visible');
}

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

@@ -0,0 +1,92 @@
// 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 @emoji
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getCustomEmoji, verifyLastPostedEmoji} from './helpers';
describe('Custom emojis', () => {
let testTeam;
let testUser;
let otherUser;
let townsquareLink;
const largeEmojiFile = 'gif-image-file.gif';
const largeEmojiFileResized = 'gif-image-file-resized.gif';
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiInitSetup().then(({team, user}) => {
testTeam = team;
testUser = user;
townsquareLink = `/${team.name}/channels/town-square`;
});
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
}).then(() => {
cy.apiLogin(testUser);
cy.visit(townsquareLink);
});
});
it('MM-T2185 Custom emoji - renders immediately for other user Custom emoji - renders after logging out and back in -- KNOWN ISSUE: MM-44768', () => {
const {customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Post a message with the emoji
cy.postMessage(customEmojiWithColons);
// # User2 logs in
cy.apiLogin(otherUser);
// # Navigate to a channel
cy.visit(townsquareLink);
// * The emoji should be displayed in the post
verifyLastPostedEmoji(customEmojiWithColons, largeEmojiFileResized);
// # User1 logs in
cy.apiLogin(testUser);
// # Navigate to a channel
cy.visit(townsquareLink);
// * The emoji should be displayed in the post
verifyLastPostedEmoji(customEmojiWithColons, largeEmojiFileResized);
});
});

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

@@ -0,0 +1,136 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @emoji
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getCustomEmoji} from './helpers';
describe('Custom emojis', () => {
let testTeam;
let testUser;
let otherUser;
let townsquareLink;
const largeEmojiFile = 'gif-image-file.gif';
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiInitSetup().then(({team, user}) => {
testTeam = team;
testUser = user;
townsquareLink = `/${team.name}/channels/town-square`;
});
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
}).then(() => {
cy.apiLogin(testUser);
cy.visit(townsquareLink);
});
});
it('MM-T2184 Custom emoji - filter list', () => {
const {customEmojiWithColons} = getCustomEmoji();
const emojiNameForSearch1 = 'alabala';
const emojiNameForSearch2 = customEmojiWithColons;
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Open emoji picker
cy.uiOpenEmojiPicker();
// # Search for a missing emoji in emoji picker
cy.findByPlaceholderText('Search emojis').should('be.visible').type(emojiNameForSearch1, {delay: TIMEOUTS.QUARTER_SEC});
// * Get list of emojis based on search text
cy.get('.no-results__title').should('be.visible').and('have.text', 'No results for "' + emojiNameForSearch1 + '"');
// # Search for an existing emoji
cy.findByPlaceholderText('Search emojis').should('be.visible').clear().type(emojiNameForSearch2, {delay: TIMEOUTS.QUARTER_SEC});
// * Get list of emojis based on search text
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
cy.findAllByTestId('emojiItem').children('img').first().should('have.class', 'emoji-category--custom');
});
it('MM-T4436 Emoji picker should show all custom emojis without overlaps', () => {
const {customEmojiWithColons: firstEmojiWithColon} = getCustomEmoji();
const {customEmojiWithColons: secondEmojiWithColon} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Add two custom emojis
[firstEmojiWithColon, secondEmojiWithColon].forEach((emojiWithColon) => {
// # Click on add new emoji for adding a custom emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(emojiWithColon);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
});
// # Go back to home channel
cy.visit(townsquareLink);
cy.reload().wait(TIMEOUTS.FIVE_SEC);
// # Open emoji picker
cy.uiOpenEmojiPicker();
cy.get('#emojiPicker').should('be.visible').within(() => {
// # Scroll to start of custom category section
cy.findByLabelText('emoji_picker.custom').should('exist').click().wait(TIMEOUTS.FIVE_SEC);
// * Verify custom category header is visible
cy.findByText('Custom').should('exist').and('is.visible');
// * Verify that first custom emoji exists and is visible to user
cy.findAllByAltText('custom emoji image').should('exist').eq(0).and('is.visible');
// * Verify second custom emoji exists and is visible to user,
// if both custom emojis are visible we can conclude that they are not overlapping
cy.findAllByAltText('custom emoji image').should('exist').eq(1).and('is.visible');
});
});
});

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

@@ -0,0 +1,316 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @emoji
import * as TIMEOUTS from '../../../fixtures/timeouts';
import * as MESSAGES from '../../../fixtures/messages';
import {doReactToLastMessageShortcut, checkReactionFromPost} from '../keyboard_shortcuts/ctrl_cmd_shift_slash/helpers';
import {getCustomEmoji} from './helpers';
describe('Custom emojis', () => {
let testTeam;
let testUser;
let otherUser;
let townsquareLink;
const builtinEmoji = 'taco';
const builtinEmojiWithColons = ':taco:';
const builtinEmojiUppercaseWithColons = ':TAco:';
const largeEmojiFile = 'gif-image-file.gif';
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiInitSetup().then(({team, user}) => {
testTeam = team;
testUser = user;
townsquareLink = `/${team.name}/channels/town-square`;
});
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
}).then(() => {
cy.apiLogin(testUser);
cy.visit(townsquareLink);
});
});
it('MM-T2186 Emoji picker - default and custom emoji reaction, case-insensitive', () => {
const {customEmoji, customEmojiWithColons} = getCustomEmoji();
const messageText = 'test message';
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Post a message
cy.postMessage(messageText);
// # Post the built-in emoji
cy.uiGetPostTextBox().type('+' + builtinEmojiWithColons).wait(TIMEOUTS.HALF_SEC).type('{enter}').type('{enter}');
cy.getLastPostId().then((postId) => {
const postText = `#postMessageText_${postId}`;
cy.get(postText).should('have.text', messageText);
cy.clickPostReactionIcon(postId);
// # Search emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(builtinEmojiUppercaseWithColons, {delay: TIMEOUTS.ONE_SEC}).wait(TIMEOUTS.ONE_SEC);
// * Get list of emojis based on the search text
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
// # Select the builtin emoji
cy.clickEmojiInEmojiPicker(builtinEmoji);
// # Search for the custom emoji
cy.clickPostReactionIcon(postId);
// # Search first three letters of the emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmoji.substring(0, 10), {delay: TIMEOUTS.HALF_SEC});
// * Get list of emojis based on the search text
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
cy.findAllByTestId('emojiItem').children('img').first().should('have.class', 'emoji-category--custom');
// * Select the custom emoji
cy.findAllByTestId('emojiItem').children().click();
});
cy.getLastPostId().then((postId) => {
cy.get(`#postReaction-${postId}-` + builtinEmoji).should('be.visible');
cy.get(`#postReaction-${postId}-` + customEmoji).should('be.visible');
});
cy.reload();
cy.getLastPostId().then((postId) => {
cy.get(`#postReaction-${postId}-` + builtinEmoji).should('be.visible');
cy.get(`#postReaction-${postId}-` + customEmoji).should('be.visible');
});
});
it('MM-T2187 Custom emoji reaction', () => {
const {customEmoji, customEmojiWithColons} = getCustomEmoji();
const messageText = 'test message';
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Post a message
cy.postMessage(messageText);
cy.getLastPostId().then((postId) => {
cy.clickPostReactionIcon(postId);
// # Search for the emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmoji, {delay: TIMEOUTS.HALF_SEC});
// * Get list of emojis based on the search text
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
cy.findAllByTestId('emojiItem').children('img').first().should('have.class', 'emoji-category--custom');
// # Select the custom emoji
cy.findAllByTestId('emojiItem').children().click();
});
});
it('MM-T2188 Custom emoji - delete emoji after using in post', () => {
const {customEmoji, customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Post a message with the emoji
cy.postMessage(customEmojiWithColons);
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Search for the custom emoji
cy.findByPlaceholderText('Search Custom Emoji').should('be.visible').type(customEmoji);
cy.get('.emoji-list__table').should('be.visible').within(() => {
// * Since we are searching exactly for that custom emoji, we should get only one result
cy.findByText('Delete').should('have.length', 1);
// # Delete the custom emoji
cy.findByText('Delete').should('have.length', 1).click({force: true});
});
// # Confirm deletion
cy.get('#confirmModalButton').should('be.visible').click();
// # Go back to home channel
cy.visit(townsquareLink);
cy.reload();
// * Show emoji list
cy.uiOpenEmojiPicker();
// # Search emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmojiWithColons, {delay: TIMEOUTS.HALF_SEC});
// * Get list of emojis based on search text
cy.get('.no-results__title').should('be.visible').and('have.text', 'No results for "' + customEmoji + '"');
// # Navigate to a channel
cy.visit(townsquareLink);
cy.getLastPost().within(() => {
// * Verify that only the plain message renders in the post and the emoji has been deleted
cy.get('p').should('have.html', '<span data-emoticon="' + customEmoji + '">' + customEmojiWithColons + '</span>');
});
});
it('MM-T4437 Custom emoji - delete emoji after reacting with it to a post', () => {
const {customEmoji, customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Post a message to which we will react with the custom emoji
cy.postMessage(MESSAGES.TINY);
// # Execute shortcut to open emoji picker for reacting to last message
doReactToLastMessageShortcut('CENTER');
cy.get('#emojiPicker').should('be.visible').within(() => {
// # Search for the same custom emoji
cy.findByPlaceholderText('Search emojis').type(customEmojiWithColons, {delay: TIMEOUTS.HALF_SEC}).wait(TIMEOUTS.HALF_SEC);
// * Since we are searching exactly for that custom emoji, we should get only one result
cy.findAllByTestId('emojiItem').children().should('have.length', 1);
cy.findAllByTestId('emojiItem').children('img').first().should('have.class', 'emoji-category--custom');
// # Select the custom emoji to add as the reaction to the last post
cy.findAllByTestId('emojiItem').children().click();
});
// * Verify that the custom emoji is added as a reaction to the last post
cy.getLastPostId().then((lastPostId) => {
checkReactionFromPost(lastPostId, customEmoji);
});
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Search for the custom emoji
cy.findByPlaceholderText('Search Custom Emoji').should('be.visible').type(customEmoji).wait(TIMEOUTS.HALF_SEC);
cy.get('.emoji-list__table').should('be.visible').within(() => {
// * Since we are searching exactly for that custom emoji, we should get only one result
cy.findAllByText(customEmojiWithColons).should('have.length', 1);
// # Delete the custom emoji
cy.findAllByText('Delete').should('have.length', 1).click();
});
// # Confirm deletion
cy.get('#confirmModalButton').should('be.visible').click();
// # Go back to home channel
cy.visit(townsquareLink);
cy.reload();
// * Show emoji list
cy.uiOpenEmojiPicker();
// # Search emoji name text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type(customEmojiWithColons, {delay: TIMEOUTS.HALF_SEC});
// * Get list of emojis based on search text
cy.get('.no-results__title').should('be.visible').and('have.text', 'No results for "' + customEmoji + '"');
// # Navigate to a channel
cy.visit(townsquareLink);
cy.getLastPost().within(() => {
// * Verify that the custom emoji as reaction is not present to last post
cy.findByLabelText('reactions').should('not.exist');
cy.findByLabelText(`remove reaction ${customEmoji}}`).should('not.exist');
});
});
});

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

@@ -0,0 +1,31 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {getRandomId} from '../../../utils';
export function getCustomEmoji() {
const customEmoji = `emoji${getRandomId()}`;
return {
customEmoji,
customEmojiWithColons: `:${customEmoji}:`,
};
}
export function verifyLastPostedEmoji(emojiName, emojiImageFile) {
cy.getLastPost().find('p').find('span > span').then((imageSpan) => {
cy.expect(imageSpan.attr('title')).to.equal(emojiName);
// # Filter out the url from the css background property
// url("https://imageurl") => https://imageurl
const url = imageSpan.css('background-image').split('"')[1];
// * Verify that the emoji image is the correct one
cy.fixture(emojiImageFile).then((overrideImage) => {
cy.request({url, encoding: 'base64'}).then((response) => {
expect(response.status).to.equal(200);
expect(response.body).to.eq(overrideImage);
});
});
});
}

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

@@ -0,0 +1,171 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @emoji @timeout_error
import * as TIMEOUTS from '../../../fixtures/timeouts';
import * as MESSAGES from '../../../fixtures/messages';
import {getCustomEmoji} from './helpers';
describe('Recent Emoji', () => {
const largeEmojiFile = 'gif-image-file.gif';
let townsquareLink;
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiInitSetup().then(({team, user}) => {
cy.apiLogin(user);
townsquareLink = `/${team.name}/channels/town-square`;
cy.visit(townsquareLink);
});
});
it('MM-T155 Recently used emoji reactions are shown first', () => {
const firstEmoji = 'joy';
const secondEmoji = 'grin';
// # Show emoji list
cy.uiOpenEmojiPicker();
// * Verify emoji picker is opened
cy.get('#emojiPicker').should('be.visible');
// # Add first emoji
cy.clickEmojiInEmojiPicker(firstEmoji);
// # Submit post
const message = 'hi';
cy.uiGetPostTextBox().and('have.value', `:${firstEmoji}: `).type(`${message} {enter}`);
cy.uiWaitUntilMessagePostedIncludes(message);
// # Post reaction to post
cy.clickPostReactionIcon();
// # Click second emoji
cy.clickEmojiInEmojiPicker(secondEmoji);
// # Show emoji list
cy.uiOpenEmojiPicker().wait(TIMEOUTS.HALF_SEC);
// * Verify recently used category is present in emoji picker
cy.findByText(/Recently Used/i).should('exist').and('be.visible');
// * Assert first emoji should equal with second recent emoji
cy.findAllByTestId('emojiItem').eq(0).find('img').should('have.attr', 'aria-label', 'grin emoji');
// * Assert second emoji should equal with first recent emoji
cy.findAllByTestId('emojiItem').eq(1).find('img').should('have.attr', 'aria-label', 'joy emoji');
});
it('MM-T4463 Recently used custom emoji, when is deleted should be removed from recent emoji category and quick reactions', () => {
const {customEmoji, customEmojiWithColons} = getCustomEmoji();
// # Open custom emoji
cy.uiOpenCustomEmoji();
// # Click on add new emoji button on custom emoji page
cy.findByText('Add Custom Emoji').should('be.visible').click();
// # Type emoji name
cy.get('#name').type(customEmojiWithColons);
// # Select emoji image
cy.get('input#select-emoji').attachFile(largeEmojiFile).wait(TIMEOUTS.THREE_SEC);
// # Click on Save
cy.uiSave().wait(TIMEOUTS.THREE_SEC);
// # Go back to home channel
cy.visit(townsquareLink);
// # Post a system emoji
cy.postMessage(`${MESSAGES.TINY}-second :lemon:`);
// # Post a custom emoji
// We let autocomplete emoji to be shown as this is a custom emoji, properties are loaded then we press enter twice, first one to auto complete add, next for post enter
cy.uiGetPostTextBox().clear().type(`${MESSAGES.TINY}-recent ${customEmojiWithColons.slice(0, -1)}`).wait(TIMEOUTS.TWO_SEC);
cy.uiGetPostTextBox().type('{enter} {enter}').wait(TIMEOUTS.TWO_SEC);
// # Hover over the last post by opening dot menu on it
cy.clickPostDotMenu();
cy.get('#recent_reaction_0').should('exist').then((recentReaction) => {
// * Assert that custom emoji is present as most recent in quick reaction menu
expect(recentReaction[0].style.backgroundImage).to.include('api/v4/emoji');
});
cy.get('#recent_reaction_1').should('exist').then((recentReaction) => {
// * Assert that system emoji is present as second recent in quick reaction menu
expect(recentReaction[0].style.backgroundImage).to.include('static/emoji/');
});
// # Open emoji picker
cy.uiOpenEmojiPicker();
// * Verify recently used category is present in emoji picker
cy.findByText('Recently Used').should('exist').and('be.visible');
// * Verify most recent one is the custom emoji in emoji picker
cy.findAllByTestId('emojiItem').eq(0).find('img').should('have.attr', 'class', 'emoji-category--custom');
// * Verify second most recent one is the system emoji in emoji picker
cy.findAllByTestId('emojiItem').eq(1).find('img').should('have.attr', 'aria-label', 'lemon emoji');
// # Go to custom emoji page
cy.findByText('Custom Emoji').should('be.visible').click();
// # Search for the custom emoji
cy.findByPlaceholderText('Search Custom Emoji').should('be.visible').type(customEmoji).wait(TIMEOUTS.HALF_SEC);
cy.get('.emoji-list__table').should('be.visible').within(() => {
// * Since we are searching exactly for that custom emoji, we should get only one result
cy.findAllByText(customEmojiWithColons).should('have.length', 1);
// # Delete the custom emoji
cy.findAllByText('Delete').should('have.length', 1).click();
});
// # Confirm deletion
cy.get('#confirmModalButton').should('be.visible').click();
// # Go back to home channel
cy.visit(townsquareLink);
cy.reload();
// # Hover over the last post by opening dot menu on it
cy.clickPostDotMenu();
cy.get('#recent_reaction_0').should('exist').then((recentReaction) => {
// * Assert that instead of custom emoji the system emoji is present as most recent in quick reaction menu
expect(recentReaction[0].style.backgroundImage).to.include('static/emoji/');
});
// # Open emoji picker again
cy.uiOpenEmojiPicker();
// * Verify recently used category is present in emoji picker
cy.findByText('Recently Used').should('exist').and('be.visible');
// * Verify most recent one is the system emoji in emoji picker and not the custom emoji
cy.findAllByTestId('emojiItem').eq(0).find('img').should('have.attr', 'aria-label', 'lemon emoji');
});
});

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

@@ -0,0 +1,74 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @emoji @timeout_error
import * as TIMEOUTS from '../../../fixtures/timeouts';
import * as MESSAGES from '../../../fixtures/messages';
describe('Recent Emoji', () => {
before(() => {
cy.apiUpdateConfig({
ServiceSettings: {
EnableCustomEmoji: true,
},
});
cy.apiInitSetup().then(({team, user}) => {
cy.apiLogin(user);
cy.visit(`/${team.name}/channels/town-square`);
});
});
it('MM-T4438 Changing the skin of emojis should apply the same skin to emojis in recent section', () => {
// # Post a sample message
cy.postMessage(MESSAGES.TINY);
// # Post reaction to post
cy.clickPostReactionIcon();
cy.get('#emojiPicker').should('be.visible').within(() => {
// # Open skin picker
cy.findByAltText('emoji skin tone picker').should('exist').parent().click().wait(TIMEOUTS.ONE_SEC);
// # Select default yellow skin
cy.findByTestId('skin-pick-default').should('exist').click();
// # Search for a system emoji with skin
cy.findByPlaceholderText('Search emojis').should('exist').type('thumbsup').wait(TIMEOUTS.HALF_SEC);
// # Select the emoji to add to post with default skin
cy.findByTestId('+1,thumbsup').parent().click();
});
// # Open emoji picker again to check if thumbsup emoji is present in recent section
cy.uiOpenEmojiPicker().wait(TIMEOUTS.TWO_SEC);
cy.get('#emojiPicker').should('be.visible').within(() => {
// * Verify recently used category is present in emoji picker
cy.findByText('Recently Used').should('exist').and('be.visible');
// * Verify most recent one is the thumbsup emoji with default skin
cy.findAllByTestId('emojiItem').eq(0).find('img').should('have.attr', 'aria-label', '+1 emoji');
// # Open skin picker again to change the skin
cy.findByAltText('emoji skin tone picker').should('exist').parent().click().wait(TIMEOUTS.ONE_SEC);
// # Select a dark skin tone
cy.findByTestId('skin-pick-1F3FF').should('exist').click();
// * Verify most recent one is the same thumbsup emoji but now with a dark skin tone
cy.findAllByTestId('emojiItem').eq(0).find('img').should('have.attr', 'aria-label', '+1 dark skin tone emoji');
});
// # Close emoji picker
cy.get('body').type('{esc}', {force: true});
});
});

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

@@ -0,0 +1,76 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @emoji
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Emoji sorting', () => {
before(() => {
// # Login as test user and visit town-square
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T157 Filtered emojis are sorted by recency, then begins with, then contains (alphabetically within each)', () => {
// # Post a dog emoji
cy.postMessage(':dog:');
// # Post a cat emoji
cy.postMessage(':cat:');
// # Open emoji picker
cy.uiOpenEmojiPicker();
// # Assert first recently used emoji has the data-test-id value of 'cat' which was the last one we sent
cy.findAllByTestId('emojiItem').
findByRole('button', {name: 'cat emoji'}).
should('exist');
const emojiList = [];
// # Post a guardsman emoji
cy.postMessage(':guardsman:');
// # Post a white small square emoji
cy.postMessage(':white_small_square:');
// # Open emoji picker
cy.uiOpenEmojiPicker();
// # Search sma text in emoji searching input
cy.findByPlaceholderText('Search emojis').should('be.visible').type('sma', {delay: TIMEOUTS.HALF_SEC});
// # Get list of recent emojis based on search text
cy.findAllByTestId('emojiItem').children('img').each(($el) => {
const emojiName = $el.get(0);
emojiList.push(emojiName.dataset.testid);
}).then(() => {
// # Comparing list of emojis obtained from search above and making sure order is same as requirement describes
expect(emojiList).to.deep.equal([
'guardsman',
'white_small_square',
'small_airplane',
'small_blue_diamond',
'small_orange_diamond',
'small_red_triangle',
'small_red_triangle_down',
'arrow_down_small',
'arrow_up_small',
'black_medium_small_square',
'black_small_square',
'mostly_sunny,sun_small_cloud,sun_behind_small_cloud',
'white_medium_small_square',
'zany_face,grinning_face_with_one_large_and_one_small_eye',
]);
});
});
});