Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,78 @@
|
||||
// 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 @account_setting
|
||||
|
||||
describe('Profile > Profile Settings > Position', () => {
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
// # Visit off-topic channel
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2063 Position', () => {
|
||||
const position = 'Master hacker';
|
||||
|
||||
// # Open 'Profile' modal and view the default 'Profile Settings'
|
||||
cy.uiOpenProfileModal().within(() => {
|
||||
// # Open 'Position' setting
|
||||
cy.findByRole('heading', {name: 'Position'}).should('be.visible').click();
|
||||
|
||||
// # Enter new 'Position'
|
||||
cy.findByRole('textbox', {name: 'Position'}).should('be.visible').type(position);
|
||||
|
||||
// # Save and close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
|
||||
// # Post message in the main channel
|
||||
cy.postMessage('hello from master hacker');
|
||||
|
||||
// # Click on the profile image
|
||||
cy.get('.profile-icon > img').as('profileIconForPopover').click();
|
||||
|
||||
// # Verify that the popover is visible and contains position
|
||||
cy.contains('#user-profile-popover', position).should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T2064 Position / 128 characters', () => {
|
||||
const longPosition = 'Master Hacker II'.repeat(8);
|
||||
|
||||
// # Open 'Profile' modal and view the default 'Profile Settings'
|
||||
cy.uiOpenProfileModal().within(() => {
|
||||
const minPositionHeader = () => cy.findByRole('heading', {name: 'Position'});
|
||||
const maxPositionInput = () => cy.findByRole('textbox', {name: 'Position'});
|
||||
|
||||
// # Fill-in the position field with a value of 128 characters
|
||||
minPositionHeader().click();
|
||||
maxPositionInput().type(longPosition);
|
||||
cy.uiSave();
|
||||
maxPositionInput().should('not.exist');
|
||||
|
||||
minPositionHeader().click();
|
||||
maxPositionInput().invoke('val').then((val) => {
|
||||
// * Verify that the input value is 128 characters
|
||||
expect(val.toString().length).to.equal(128);
|
||||
});
|
||||
|
||||
// # Try to edit the field with maximum characters
|
||||
maxPositionInput().focus().type('random');
|
||||
maxPositionInput().invoke('val').then((val) => {
|
||||
// * Verify that the position hasn't changed
|
||||
expect(val).to.equal(longPosition);
|
||||
});
|
||||
|
||||
// # Save position
|
||||
cy.uiSave();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,233 @@
|
||||
// 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 @account_setting
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import {reUrl, getRandomId} from '../../../../utils';
|
||||
|
||||
describe('Profile > Profile Settings > Email', () => {
|
||||
let siteName;
|
||||
let testUser: Cypress.UserProfile;
|
||||
let otherUser;
|
||||
let offTopicUrl;
|
||||
let origConfig: Cypress.AdminConfig;
|
||||
|
||||
before(() => {
|
||||
// Get config
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
origConfig = config;
|
||||
const newConfig = {
|
||||
...origConfig,
|
||||
EmailSettings: {
|
||||
...origConfig.EmailSettings,
|
||||
RequireEmailVerification: true,
|
||||
},
|
||||
};
|
||||
|
||||
cy.apiUpdateConfig(newConfig).then(({config}) => {
|
||||
siteName = config.TeamSettings.SiteName;
|
||||
});
|
||||
|
||||
cy.apiInitSetup().then(({user, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
offTopicUrl = url;
|
||||
|
||||
cy.apiVerifyUserEmailById(testUser.id);
|
||||
|
||||
return cy.apiCreateUser({});
|
||||
}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// # Close modal
|
||||
cy.get('body').type('{esc}');
|
||||
});
|
||||
|
||||
it('MM-T2065 Email: Can "change" to existing email address and save', () => {
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
// # Type the same email
|
||||
cy.get('#primaryEmail').should('be.visible').type(testUser.email);
|
||||
cy.get('#confirmEmail').should('be.visible').type(testUser.email);
|
||||
cy.get('#currentPassword').should('be.visible').type('SampleUs@r-1');
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Check that the email verification message is not showed.
|
||||
cy.get('.announcement-bar').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T2066 email address required', () => {
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Check that the correct error message is shown.
|
||||
cy.get('#clientError').should('be.visible').should('have.text', 'Please enter a valid email address');
|
||||
});
|
||||
|
||||
it('MM-T2067 email address already taken error', () => {
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
// # Type different email
|
||||
cy.get('#primaryEmail').should('be.visible').type(otherUser.email);
|
||||
cy.get('#confirmEmail').should('be.visible').type(otherUser.email);
|
||||
cy.get('#currentPassword').should('be.visible').type(otherUser.password);
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Check that the correct error message is shown.
|
||||
cy.get('#serverError').should('be.visible').should('have.text', 'An account with that email already exists.');
|
||||
});
|
||||
|
||||
it('MM-T2068 email address and confirmation don\'t match', () => {
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
// # Type some random email
|
||||
cy.get('#primaryEmail').should('be.visible').type('random@example.com');
|
||||
cy.get('#confirmEmail').should('be.visible').clear();
|
||||
cy.get('#currentPassword').should('be.visible').type('randompass');
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Check that the correct error message is shown.
|
||||
cy.get('#clientError').should('be.visible').should('have.text', 'The new emails you entered do not match.');
|
||||
});
|
||||
|
||||
// This test is a combination of 4 sub-tests because they are sub-parts of the same test.
|
||||
// Doing them individually would have a dependency with the previous test.
|
||||
// Hence, a combined single test for everything is better.
|
||||
it('MM-T2069 Email: Can update email address and verify through email notification', () => {
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
const randomId = getRandomId();
|
||||
const username = `user-${randomId}`;
|
||||
const email = `${username}@example.com`;
|
||||
|
||||
// # Type new email
|
||||
cy.get('#primaryEmail').should('be.visible').type(email);
|
||||
cy.get('#confirmEmail').should('be.visible').type(email);
|
||||
cy.get('#currentPassword').should('be.visible').type(testUser.password);
|
||||
|
||||
// # Save the settings and close
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
cy.uiClose();
|
||||
|
||||
// * Verify the announcement bar
|
||||
cy.get('.announcement-bar').should('be.visible').should('contain.text', 'Check your email inbox to verify the address.');
|
||||
|
||||
// # Reload the page
|
||||
cy.reload();
|
||||
|
||||
// * Check that the email verification message is not showed.
|
||||
cy.get('.announcement-bar').should('not.exist');
|
||||
|
||||
cy.getRecentEmail({username, email}).then((data) => {
|
||||
// * Verify the subject
|
||||
expect(data.subject).to.equal(`[${siteName}] Verify new email address`);
|
||||
|
||||
// * Verify the body
|
||||
expect(data.body).to.contain('You successfully updated your email');
|
||||
const matched = data.body[6].match(reUrl);
|
||||
assert(matched.length > 0);
|
||||
|
||||
const permalink = matched[0];
|
||||
|
||||
// # Click on the link
|
||||
cy.visit(permalink);
|
||||
|
||||
// * Verify announcement bar
|
||||
cy.get('.announcement-bar').should('be.visible').should('contain.text', 'Email verified');
|
||||
|
||||
// # Wait for one second for the mail to be sent out.
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
cy.getRecentEmail(testUser).then(({subject}) => {
|
||||
// * Verify the subject
|
||||
expect(subject).to.equal(`[${siteName}] Your email address has changed`);
|
||||
});
|
||||
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// * Verify new email address
|
||||
cy.get('#emailDesc').should('be.visible').should('have.text', email);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2073 - Verify email verification message after logout', () => {
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
const randomId = getRandomId();
|
||||
const username = `user-${randomId}`;
|
||||
const email = `${username}@example.com`;
|
||||
|
||||
// # Type new email
|
||||
cy.get('#primaryEmail').should('be.visible').type(email);
|
||||
cy.get('#confirmEmail').should('be.visible').type(email);
|
||||
cy.get('#currentPassword').should('be.visible').type(testUser.password);
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Close modal then logout
|
||||
cy.get('body').type('{esc}');
|
||||
cy.uiOpenUserMenu('Log Out');
|
||||
|
||||
// # Wait for one second for the mail to be sent out.
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
cy.getRecentEmail({username, email}).then((data) => {
|
||||
// * Verify the subject
|
||||
expect(data.subject).to.equal(`[${siteName}] Verify new email address`);
|
||||
|
||||
// * Verify email body
|
||||
expect(data.body[1]).to.contain('You successfully updated your email');
|
||||
const matched = data.body[6].match(reUrl);
|
||||
assert(matched.length > 0);
|
||||
|
||||
const permalink = matched[0];
|
||||
cy.visit(permalink);
|
||||
|
||||
// * Verify login text
|
||||
cy.get('.AlertBanner.success').should('be.visible').within(() => {
|
||||
cy.get('.AlertBanner__title').should('contain.text', 'Email Verified');
|
||||
});
|
||||
|
||||
// # Do login
|
||||
cy.get('#input_loginId').should('be.visible').clear().type(email);
|
||||
cy.get('#input_password-input').should('be.visible').type(testUser.password);
|
||||
cy.get('#saveSetting').should('not.be.disabled').click();
|
||||
|
||||
// * Check that the email verification message is not showed.
|
||||
cy.get('.announcement-bar').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @account_setting
|
||||
|
||||
describe('Profile > Profile Settings > Full Name', () => {
|
||||
let testUser;
|
||||
|
||||
before(() => {
|
||||
// # Login as new user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({user, offTopicUrl}) => {
|
||||
testUser = user;
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2043 Enter first name', () => {
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Click "Edit" to the right of "Full Name"
|
||||
cy.get('#nameEdit').should('be.visible').click();
|
||||
|
||||
// # Clear the first name
|
||||
cy.get('#firstName').clear();
|
||||
|
||||
// # Type a new first name
|
||||
cy.get('#firstName').should('be.visible').type(testUser.first_name + '_new');
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave();
|
||||
|
||||
// * Check that the first name was correctly updated
|
||||
cy.get('#nameDesc').should('be.visible').should('contain', testUser.first_name + '_new ' + testUser.last_name);
|
||||
|
||||
// # Close the modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2042 Full Name starting blank stays blank', () => {
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Click "Edit" to the right of "Full Name"
|
||||
cy.get('#nameEdit').should('be.visible').click();
|
||||
|
||||
// # Clear the first name
|
||||
cy.get('#firstName').should('be.visible').clear();
|
||||
|
||||
// # Clear the last name
|
||||
cy.get('#lastName').should('be.visible').clear();
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave();
|
||||
|
||||
// # Click "Edit" to the right of "Full Name"
|
||||
cy.get('#nameEdit').should('be.visible').click();
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave();
|
||||
|
||||
// * Check that the full name was correctly cleared
|
||||
cy.findByText("Click 'Edit' to add your full name").should('be.visible');
|
||||
|
||||
// # Click "Edit" to the right of "Full Name"
|
||||
cy.get('#nameEdit').should('be.visible').click();
|
||||
|
||||
// * Check that first name is blank
|
||||
cy.get('#firstName').should('be.visible').should('have.value', '');
|
||||
|
||||
// * Check that last name is blank
|
||||
cy.get('#lastName').should('be.visible').should('have.value', '');
|
||||
|
||||
// # Close the modal
|
||||
cy.uiClose();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,81 @@
|
||||
// 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 @account_setting
|
||||
|
||||
import {getRandomId} from '../../../../utils';
|
||||
|
||||
describe('Profile > Profile Settings> Full Name', () => {
|
||||
let firstUser;
|
||||
let secondUser;
|
||||
const firstName = 'This Is a Long Name';
|
||||
const lastName = 'That Should Truncate';
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
|
||||
firstUser = user;
|
||||
cy.apiCreateUser().then(({user: user1}) => {
|
||||
secondUser = user1;
|
||||
cy.apiAddUserToTeam(team.id, secondUser.id);
|
||||
|
||||
cy.apiLogin(firstUser);
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2046 Full Name - Truncated in popover', () => {
|
||||
// # Go to Profile -> Profile Settings -> Full Name -> Edit
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Open Full Name section
|
||||
cy.get('#nameDesc').click();
|
||||
|
||||
// # Enter First Name `This Is a Very Long Name`
|
||||
cy.get('#firstName').clear().type(firstName);
|
||||
|
||||
// # Enter Last Name `That Should Truncate`
|
||||
cy.get('#lastName').clear().type(lastName);
|
||||
|
||||
// # Save
|
||||
cy.get('#saveSetting').click();
|
||||
|
||||
// * Full name field shows first and last name.
|
||||
cy.contains('#nameDesc', `${firstName} ${lastName}`);
|
||||
|
||||
// # Close account settings modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2047 Truncated in popover (visual verification)', () => {
|
||||
// # Open user profile popover
|
||||
cy.postMessage(`this is a test message ${getRandomId()}`);
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).should('be.visible');
|
||||
cy.get(`#post_${postId} img`).click();
|
||||
cy.get('#user-profile-popover').should('be.visible');
|
||||
|
||||
// * Popover user name should show truncated to 'This Is a Long Name That Should Tr...'
|
||||
cy.findByTestId(`popover-fullname-${firstUser.username}`).should('have.css', 'text-overflow', 'ellipsis');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2048 Empty full name: @ still displays before username', () => {
|
||||
// # Open any user list ("View Members", "Add Members", "Manage Members", ..)
|
||||
cy.uiOpenTeamMenu('View Members');
|
||||
|
||||
// # Find a user who hasn't set their full name
|
||||
cy.get('.modal-title').should('be.visible');
|
||||
cy.get('#searchUsersInput').should('be.visible').type(secondUser.nickname);
|
||||
|
||||
// * Username is preceded with `@`, consistent with other users
|
||||
cy.contains('button.user-popover', `@${secondUser.username}`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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 @account_setting
|
||||
|
||||
describe('Account Settings', () => {
|
||||
before(() => {
|
||||
// # Login as new user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2045 Full Name - Link in help text', () => {
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// * Ensure that the Profile tab is loaded
|
||||
cy.get('#generalSettingsTitle').should('be.visible').should('contain', 'Profile');
|
||||
|
||||
// # Click "Edit" to the right of Full Name
|
||||
cy.get('#nameEdit').click();
|
||||
|
||||
// # Click "Notifications" link in help text
|
||||
cy.get('#extraInfo').within(() => {
|
||||
cy.findByText('Notifications').click();
|
||||
});
|
||||
|
||||
// * Verify that the modal switched to "Profile" modal
|
||||
cy.findByRole('dialog', {name: 'Profile'}).should('be.visible');
|
||||
|
||||
// * Verify that the view switches to notifications tab
|
||||
cy.get('#notificationSettingsTitle').should('be.visible').should('contain', 'Notifications');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,181 @@
|
||||
// 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 @account_setting
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Settings > Sidebar > General', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
|
||||
before(() => {
|
||||
// # Login as new user and visit off-topic
|
||||
cy.apiInitSetup({loginAfter: true}).then(({team, user, offTopicUrl}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3848 No nickname is present', () => {
|
||||
// # Open 'Profile' modal and view the default 'Profile'
|
||||
cy.uiOpenProfileModal().within(() => {
|
||||
// # Open 'Nickname' setting
|
||||
cy.uiGetHeading('Nickname').click();
|
||||
|
||||
// # Clear the nickname text field contents
|
||||
cy.uiGetTextbox('Nickname').should('be.visible').clear();
|
||||
|
||||
// # Save and close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
|
||||
// # Open team menu and click "View Members"
|
||||
cy.uiOpenTeamMenu('View Members');
|
||||
|
||||
// # Search for username and check that no nickname is present
|
||||
cy.get('.modal-title').should('be.visible');
|
||||
cy.get('#searchUsersInput').should('be.visible').type(testUser.first_name).wait(TIMEOUTS.ONE_SEC);
|
||||
cy.findByTestId('userListItemDetails').find('.more-modal__name').should('be.visible').then((el) => {
|
||||
expect(getInnerText(el)).equal(`@${testUser.username} - ${testUser.first_name} ${testUser.last_name}`);
|
||||
});
|
||||
|
||||
// # Close Team Members modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T268 Profile > Profile Settings > Add Nickname', () => {
|
||||
const newNickname = 'victor_nick';
|
||||
|
||||
// # Open 'Profile' modal and view the default 'Profile Settings'
|
||||
cy.uiOpenProfileModal().within(() => {
|
||||
// # Open 'Nickname' setting
|
||||
cy.uiGetHeading('Nickname').click();
|
||||
|
||||
// # Clear the nickname text field contents
|
||||
cy.uiGetTextbox('Nickname').should('be.visible').clear().type('victor_nick');
|
||||
|
||||
// # Save and close the modal
|
||||
cy.uiSaveAndClose();
|
||||
});
|
||||
|
||||
// # Open team menu and click "View Members"
|
||||
cy.uiOpenTeamMenu('View Members');
|
||||
|
||||
// # Search for username and check that expected nickname is present
|
||||
cy.get('.modal-title').should('be.visible');
|
||||
cy.get('#searchUsersInput').should('be.visible').type(testUser.first_name).wait(TIMEOUTS.ONE_SEC);
|
||||
cy.findByTestId('userListItemDetails').find('.more-modal__name').should('be.visible').then((el) => {
|
||||
expect(getInnerText(el)).equal(`@${testUser.username} - ${testUser.first_name} ${testUser.last_name} (${newNickname})`);
|
||||
});
|
||||
|
||||
// # Close Channel Members modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2060 Nickname and username styles', () => {
|
||||
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
|
||||
// # Go to test channel
|
||||
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
|
||||
|
||||
// # Go to Settings > Display
|
||||
cy.uiOpenSettingsModal('Display');
|
||||
|
||||
// # Click Edit button beside Teammate Name Display
|
||||
cy.get('#name_formatEdit').click();
|
||||
|
||||
// # Choose Show first and last name
|
||||
cy.get('#name_formatFormatC').check();
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.uiSave();
|
||||
cy.uiClose();
|
||||
|
||||
// # Open channel menu and click 'Add Members'
|
||||
cy.uiOpenChannelMenu('Add Members');
|
||||
|
||||
// * Verify that the modal is open
|
||||
cy.get('#addUsersToChannelModal').should('be.visible').findByText(`Add people to ${channel.display_name}`);
|
||||
|
||||
// # Type into the input box to search for a user
|
||||
cy.get('#selectItems input').typeWithForce('sys').wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Verify that the username span contains the '@' symbol and the dark colour
|
||||
cy.get('#multiSelectList > div > .more-modal__details > .more-modal__name > span').should('contain', '@').and('have.css', 'color', 'rgb(63, 67, 80)');
|
||||
|
||||
// # Close modal
|
||||
cy.get('body').type('{esc}');
|
||||
|
||||
// # Open DM modal from the sidebar
|
||||
cy.uiAddDirectMessage().click();
|
||||
|
||||
// # Go to direct messages modal
|
||||
cy.get('.more-modal').should('be.visible').within(() => {
|
||||
cy.findByText('Direct Messages').click();
|
||||
cy.get('#selectItems input').typeWithForce('@');
|
||||
|
||||
// * Verify that the username span contains the '@' symbol and the dark colour
|
||||
cy.get('.more-modal__details > .more-modal__name').should('contain', '@').and('have.css', 'color', 'rgb(63, 67, 80)');
|
||||
});
|
||||
|
||||
// # Exit the modal
|
||||
cy.get('body').type('{esc}');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2061 Nickname should reset on cancel of edit', () => {
|
||||
// # Open 'Profile' modal and view the default 'Profile Settings'
|
||||
cy.uiOpenProfileModal().within(() => {
|
||||
// # Open 'Nickname' setting
|
||||
cy.uiGetHeading('Nickname').click();
|
||||
|
||||
// # Clear the nickname text field contents
|
||||
cy.uiGetTextbox('Nickname').should('be.visible').clear().type('nickname_edit');
|
||||
|
||||
// # Cancel the edit of nickname
|
||||
cy.uiCancelButton().click();
|
||||
});
|
||||
|
||||
// # Click edit of nickname
|
||||
cy.uiGetHeading('Nickname').click();
|
||||
|
||||
// * Check if element is present and contains old nickname
|
||||
cy.uiGetTextbox('Nickname').should('be.visible').should('contain', '');
|
||||
|
||||
// # Close the modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2062 Clear nickname and save', () => {
|
||||
// # Open 'Profile' modal and view the default 'Profile Settings'
|
||||
cy.uiOpenProfileModal().within(() => {
|
||||
// # Open 'Nickname' setting
|
||||
cy.uiGetHeading('Nickname').click();
|
||||
|
||||
// # Clear the nickname
|
||||
cy.uiGetTextbox('Nickname').clear();
|
||||
|
||||
// * Check if nickname element is present and it does not contain any nickname
|
||||
cy.uiGetTextbox('Nickname').should('contain', '');
|
||||
cy.uiSaveButton().click();
|
||||
});
|
||||
|
||||
// * Verify nickname help text is visible
|
||||
cy.get('#nicknameDesc').should('be.visible').should('contain', "Click 'Edit' to add a nickname");
|
||||
|
||||
// # Close the modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
function getInnerText(el) {
|
||||
return el[0].innerText.replace(/\n/g, '').replace(/\s/g, ' ');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @account_setting
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Account Settings', () => {
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin().apiInitSetup({loginAfter: true}).its('user').as('user');
|
||||
});
|
||||
|
||||
it('MM-T2079 Can remove profile pic then choose different pic without saving in between', function() {
|
||||
// # Add a profile picture (aka "old profile picture")
|
||||
setInitialPicture(this.user);
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
// # Save the id of the old picture
|
||||
getProfilePictureId().as('idOld');
|
||||
|
||||
// # Open Profile > Profile Settings > Profile Picture > Edit
|
||||
cy.uiOpenProfileModal().findByRole('button', {name: /picture edit/i}).click();
|
||||
|
||||
// # Click the X to remove the old profile picture but do not click save
|
||||
cy.findByRole('button', {name: /remove profile picture/i}).click();
|
||||
|
||||
// # Select a new profile picture and click Save
|
||||
cy.findByTestId('uploadPicture').attachFile('png-image-file.png');
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
cy.findByRole('button', {name: /close/i}).click();
|
||||
|
||||
// * Verify that new profile image exists and isn't equal to the old one
|
||||
getProfilePictureId().then((idNew) => expect(idNew).to.exist.and.not.to.be.equal(this.idOld));
|
||||
});
|
||||
|
||||
it('MM-T2075_1 Profile Picture: Cancel out of adding profile picture', () => {
|
||||
verifyProfilePictureDoesNotUpdateAfterCancel();
|
||||
});
|
||||
|
||||
it('MM-T2075_2 Profile Picture: Cancel out of changing profile picture ', function() {
|
||||
// # Add a profile picture (aka "old profile picture")
|
||||
setInitialPicture(this.user);
|
||||
|
||||
verifyProfilePictureDoesNotUpdateAfterCancel();
|
||||
});
|
||||
});
|
||||
|
||||
function getProfilePictureId() {
|
||||
return cy.uiGetProfileHeader().find('.Avatar').invoke('attr', 'src').then((urlString) => {
|
||||
const url = new URL(urlString);
|
||||
const params = new URLSearchParams(url.search);
|
||||
return params.get('_');
|
||||
});
|
||||
}
|
||||
|
||||
function setInitialPicture(user) {
|
||||
cy.apiUploadFile('image', 'mattermost-icon.png', {
|
||||
url: `/api/v4/users/${user.id}/image`,
|
||||
method: 'POST',
|
||||
successStatus: 200,
|
||||
});
|
||||
}
|
||||
|
||||
function verifyProfilePictureDoesNotUpdateAfterCancel() {
|
||||
let idOld;
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
// # Save the id of the old picture
|
||||
getProfilePictureId().then((id) => {
|
||||
idOld = id;
|
||||
});
|
||||
|
||||
// # Open Profile > Profile Settings > Profile Picture > Edit
|
||||
cy.uiOpenProfileModal().findByRole('button', {name: /picture edit/i}).click();
|
||||
|
||||
// # Select a new profile picture
|
||||
cy.findByTestId('uploadPicture').attachFile('png-image-file.png');
|
||||
|
||||
cy.uiCancel().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
cy.uiClose();
|
||||
|
||||
// * Verify that 'new' profile image exists and equal to the old one
|
||||
getProfilePictureId().then((idNew) => expect(idNew).to.equal(idOld));
|
||||
}
|
||||
@@ -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.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @account_setting
|
||||
|
||||
// TODO: Remove import once e2e/cypress/tests/support/index.ts is converted to Typescript.
|
||||
import 'cypress-file-upload';
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Profile > Profile Settings > Profile Picture', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2080 Can remove profile pic', () => {
|
||||
const customImageMatch = 'image?_=';
|
||||
|
||||
// * Verify the default profile image is shown first
|
||||
cy.uiGetProfileHeader().
|
||||
find('.Avatar').
|
||||
should('have.attr', 'src').
|
||||
and('not.include', customImageMatch);
|
||||
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Click "Edit" to the right of "Profile Picture"
|
||||
cy.get('#pictureEdit').should('be.visible').click();
|
||||
|
||||
// # Upload and save profile picture
|
||||
cy.findByTestId('uploadPicture').attachFile('mattermost-icon.png');
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Close modal
|
||||
cy.get('body').type('{esc}');
|
||||
|
||||
// * Profile picture is updated
|
||||
cy.uiGetProfileHeader().
|
||||
find('.Avatar').
|
||||
should('have.attr', 'src').
|
||||
and('include', customImageMatch);
|
||||
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Click "Edit" to the right of "Profile Picture"
|
||||
cy.get('#pictureEdit').should('be.visible').click();
|
||||
|
||||
// # Remove profile picture
|
||||
cy.findByTestId('removeSettingPicture').click();
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Check that we are back in the "General" section of the Profile
|
||||
cy.get('#pictureEdit').should('be.visible');
|
||||
|
||||
// # Close modal
|
||||
cy.get('body').type('{esc}');
|
||||
|
||||
// * Verify the default profile image is shown
|
||||
cy.uiGetProfileHeader().
|
||||
find('.Avatar').
|
||||
should('have.attr', 'src').
|
||||
and('not.include', customImageMatch);
|
||||
});
|
||||
|
||||
it('MM-T2077 Profile picture: non image file shows error', () => {
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Click "Edit" to the right of "Profile Picture"
|
||||
cy.get('#pictureEdit').should('be.visible').click();
|
||||
|
||||
// # Upload and save profile picture
|
||||
cy.findByTestId('uploadPicture').attachFile('txt-changed-as-png.png');
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Verify error message
|
||||
cy.get('.has-error').
|
||||
should('be.visible').
|
||||
and('contain', 'Image limits check failed. Resolution is too high.');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,246 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @account_setting
|
||||
|
||||
import {getRandomId} from '../../../../utils';
|
||||
|
||||
describe('Settings > Sidebar > General > Edit', () => {
|
||||
let testTeam;
|
||||
let testUser;
|
||||
let testChannel;
|
||||
let otherUser;
|
||||
let offTopicUrl;
|
||||
|
||||
before(() => {
|
||||
// # Login as admin and visit off-topic
|
||||
cy.apiInitSetup().then(({user, team, channel, offTopicUrl: url}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
testChannel = channel;
|
||||
offTopicUrl = url;
|
||||
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: user1}) => {
|
||||
otherUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
|
||||
});
|
||||
});
|
||||
|
||||
cy.visit(offTopicUrl);
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal();
|
||||
});
|
||||
|
||||
it('MM-T2050 Username cannot be blank', () => {
|
||||
// # Clear the username textfield contents
|
||||
cy.get('#usernameEdit').click();
|
||||
cy.get('#username').clear();
|
||||
cy.uiSave();
|
||||
|
||||
// * Check if element is present and contains expected text values
|
||||
cy.get('#clientError').should('be.visible').should('contain', 'Username must begin with a letter, and contain between 3 to 22 lowercase characters made up of numbers, letters, and the symbols \'.\', \'-\', and \'_\'.');
|
||||
|
||||
// # Click "x" button to close Profile modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2051 Username min 3 characters', () => {
|
||||
// # Edit the username field
|
||||
cy.get('#usernameEdit').click();
|
||||
|
||||
// # Add the username to textfield contents
|
||||
cy.get('#username').clear().type('te');
|
||||
cy.uiSave();
|
||||
|
||||
// * Check if element is present and contains expected text values
|
||||
cy.get('#clientError').should('be.visible').should('contain', 'Username must begin with a letter, and contain between 3 to 22 lowercase characters made up of numbers, letters, and the symbols \'.\', \'-\', and \'_\'.');
|
||||
|
||||
// # Click "x" button to close Profile modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2052 Username already taken', () => {
|
||||
// # Edit the username field
|
||||
cy.get('#usernameEdit').click();
|
||||
|
||||
// # Add the username to textfield contents
|
||||
cy.get('#username').clear().type(otherUser.username);
|
||||
cy.uiSave();
|
||||
|
||||
// * Check if element is present and contains expected text values
|
||||
cy.get('#serverError').should('be.visible').should('contain', 'An account with that username already exists.');
|
||||
|
||||
// # Click "x" button to close Profile modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2053 Username w/ dot, dash, underscore still searches', () => {
|
||||
let tempUser;
|
||||
|
||||
// # Create a temporary user
|
||||
cy.apiCreateUser({prefix: 'temp'}).then(({user: user1}) => {
|
||||
tempUser = user1;
|
||||
|
||||
cy.apiAddUserToTeam(testTeam.id, tempUser.id).then(() => {
|
||||
cy.apiAddUserToChannel(testChannel.id, tempUser.id);
|
||||
});
|
||||
|
||||
// # Login the temporary user
|
||||
cy.apiLogin(tempUser);
|
||||
cy.visit(offTopicUrl);
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Step 1
|
||||
// # Edit the username field
|
||||
cy.get('#usernameEdit').click();
|
||||
|
||||
// # Step 2
|
||||
// # Add the username to textfield contents
|
||||
const newTempUserName = 'a-' + tempUser.username;
|
||||
cy.get('#username').clear().type(newTempUserName);
|
||||
cy.uiSaveAndClose();
|
||||
|
||||
// # Step 3
|
||||
// * Verify that we've logged in as the temp user
|
||||
cy.visit(offTopicUrl);
|
||||
cy.uiOpenUserMenu().findByText(`@${newTempUserName}`);
|
||||
cy.uiGetSetStatusButton().click();
|
||||
|
||||
// # Step 4
|
||||
const text = `${newTempUserName} test message!`;
|
||||
|
||||
// # Post the user name mention declared earlier
|
||||
cy.postMessage(text);
|
||||
|
||||
// # Click on the @ button
|
||||
cy.uiGetRecentMentionButton().should('be.visible').click();
|
||||
|
||||
cy.get('#search-items-container').should('be.visible').within(() => {
|
||||
// * Ensure that the mentions are visible in the RHS
|
||||
cy.findByText(newTempUserName);
|
||||
cy.findByText(`${newTempUserName} test message!`);
|
||||
});
|
||||
|
||||
// # Click on the @ button to toggle off
|
||||
cy.uiGetRecentMentionButton().should('be.visible').click();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T2054 Username cannot start with dot, dash, or underscore', () => {
|
||||
// # Edit the username field
|
||||
cy.get('#usernameEdit').click();
|
||||
|
||||
const prefixes = [
|
||||
'.',
|
||||
'-',
|
||||
'_',
|
||||
];
|
||||
|
||||
for (const prefix of prefixes) {
|
||||
// # Add username to textfield contents
|
||||
cy.get('#username').clear().type(prefix).type('{backspace}.').type(otherUser.username);
|
||||
cy.uiSave();
|
||||
|
||||
// * Check if element is present and contains expected text values
|
||||
cy.get('#clientError').should('be.visible').should('contain', 'Username must begin with a letter, and contain between 3 to 22 lowercase characters made up of numbers, letters, and the symbols \'.\', \'-\', and \'_\'.');
|
||||
}
|
||||
|
||||
// # Click "x" button to close Profile modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2055 Usernames that are reserved', () => {
|
||||
// # Edit the username field
|
||||
cy.get('#usernameEdit').click();
|
||||
|
||||
const usernames = [
|
||||
'all',
|
||||
'channel',
|
||||
'here',
|
||||
'matterbot',
|
||||
];
|
||||
|
||||
for (const username of usernames) {
|
||||
// # Add username to textfield contents
|
||||
cy.get('#username').clear().type(username);
|
||||
cy.uiSave();
|
||||
|
||||
// * Check if element is present and contains expected text values
|
||||
cy.get('#clientError').should('be.visible').should('contain', 'This username is reserved, please choose a new one.');
|
||||
}
|
||||
|
||||
// # Click "x" button to close Profile modal
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
it('MM-T2056 Username changes when viewed by other user', () => {
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Post a message in off-topic
|
||||
cy.postMessage('Testing username update');
|
||||
|
||||
// # Login as other user
|
||||
cy.apiLogin(otherUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Get last post in off-topic for verifying username
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).within(() => {
|
||||
// # Open profile popover
|
||||
cy.get('.user-popover').click();
|
||||
});
|
||||
|
||||
// * Verify username in profile popover
|
||||
cy.get('#user-profile-popover').within(() => {
|
||||
cy.get('#userPopoverUsername').should('be.visible').and('contain', `${testUser.username}`);
|
||||
});
|
||||
});
|
||||
|
||||
// # Login as test user
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Open account settings modal
|
||||
cy.uiOpenProfileModal();
|
||||
|
||||
// # Open Full Name section
|
||||
cy.get('#usernameDesc').click();
|
||||
|
||||
const randomId = getRandomId();
|
||||
|
||||
// # Save username with a randomId
|
||||
cy.get('#username').clear().type(`${otherUser.username}-${randomId}`);
|
||||
|
||||
// # save form
|
||||
cy.uiSave();
|
||||
|
||||
cy.apiLogin(otherUser);
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Get last post in off-topic for verifying username
|
||||
cy.getLastPostId().then((postId) => {
|
||||
cy.get(`#post_${postId}`).within(() => {
|
||||
cy.get('.user-popover').click();
|
||||
});
|
||||
|
||||
// * Verify that new username is in profile popover
|
||||
cy.get('#user-profile-popover').within(() => {
|
||||
cy.get('#userPopoverUsername').should('be.visible').and('contain', `${otherUser.username}-${randomId}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Ссылка в новой задаче
Block a user