Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,24 @@
|
||||
// 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 @not_cloud @system_console @restrict_system_admin
|
||||
|
||||
describe('Password settings', () => {
|
||||
it('MM-T4679 - Should NOT show MaximumLoginAttempts when ExperimentalSettings.RestrictSystemAdmin is true', () => {
|
||||
cy.apiUpdateConfig({
|
||||
ExperimentalSettings: {
|
||||
RestrictSystemAdmin: true,
|
||||
},
|
||||
}).then(() => {
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
cy.get('#maximumLoginAttempts').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,146 @@
|
||||
// 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 @system_console
|
||||
|
||||
describe('Custom Terms of Service', () => {
|
||||
let testUser;
|
||||
let testTeam;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, user}) => {
|
||||
testUser = user;
|
||||
testTeam = team;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1190 - Appears after creating new account and verifying email address', () => {
|
||||
const customTermsOfServiceText = 'Test custom terms of service';
|
||||
|
||||
// # Verify new user email
|
||||
cy.apiVerifyUserEmailById(testUser.id);
|
||||
|
||||
// # Login as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: true,
|
||||
},
|
||||
});
|
||||
|
||||
// # Visit custom terms of service page
|
||||
cy.visit('/admin_console/compliance/custom_terms_of_service');
|
||||
|
||||
// # Enable custom terms of service
|
||||
cy.findByTestId('SupportSettings.CustomTermsOfServiceEnabledtrue').click();
|
||||
|
||||
// # Set the terms of service to the first value
|
||||
cy.findByTestId('SupportSettings.CustomTermsOfServiceTextinput').clear().type(customTermsOfServiceText);
|
||||
|
||||
// # Save config
|
||||
cy.get('#saveSetting').click();
|
||||
|
||||
// # Login as the test user
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the test team town square
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
|
||||
// * Ensure that the terms of service text shows as expected
|
||||
cy.findByTestId('termsOfService').should('be.visible').and('contain.text', customTermsOfServiceText);
|
||||
|
||||
// * Ensure that the accept terms button is visible and click it
|
||||
cy.get('#acceptTerms').should('be.visible').click();
|
||||
|
||||
// * Ensure the user is redirected to the appropriate team after terms are accepted
|
||||
cy.url().should('include', `/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
|
||||
it('MM-T1191 - Repeated edits must be agreed to', () => {
|
||||
const firstTOS = 'First custom terms of service';
|
||||
const secondTOS = 'Second custom terms of service';
|
||||
|
||||
// # Login as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Reset config via the API from previous test
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
SupportSettings: {
|
||||
CustomTermsOfServiceEnabled: false,
|
||||
},
|
||||
});
|
||||
|
||||
// # Visit custom terms of service page
|
||||
cy.visit('/admin_console/compliance/custom_terms_of_service');
|
||||
|
||||
// # Enable custom terms of service
|
||||
cy.findByTestId('SupportSettings.CustomTermsOfServiceEnabledtrue').click();
|
||||
|
||||
// # Set the terms of service to the first value
|
||||
cy.findByTestId('SupportSettings.CustomTermsOfServiceTextinput').clear().type(firstTOS);
|
||||
|
||||
// # Save config
|
||||
cy.get('#saveSetting').click();
|
||||
|
||||
// # Accept the terms as sysadmin
|
||||
cy.get('#acceptTerms').should('be.visible').click();
|
||||
|
||||
// * Should be redirected back to custom terms of service page
|
||||
cy.url().should('include', '/admin_console/compliance/custom_terms_of_service');
|
||||
|
||||
// # Login as the test user
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the test team town square
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
|
||||
// * Ensure that the first terms of service is visible
|
||||
cy.findByTestId('termsOfService').should('be.visible').and('contain.text', firstTOS);
|
||||
|
||||
// # Login as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Visit custom terms of service page
|
||||
cy.visit('/admin_console/compliance/custom_terms_of_service');
|
||||
|
||||
// # Set the terms of service to the first value
|
||||
cy.findByTestId('SupportSettings.CustomTermsOfServiceTextinput').clear().type(secondTOS);
|
||||
|
||||
// # Save config
|
||||
cy.get('#saveSetting').click();
|
||||
|
||||
// * Ensure that the terms of service text shows as expected
|
||||
cy.findByTestId('termsOfService').should('be.visible').and('contain.text', secondTOS);
|
||||
|
||||
// # Accept the terms as sysadmin
|
||||
cy.get('#acceptTerms').should('be.visible').click();
|
||||
|
||||
// * Should be redirected back to custom terms of service page
|
||||
cy.url().should('include', '/admin_console/compliance/custom_terms_of_service');
|
||||
|
||||
// # Login as the test user
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Visit the test team town square
|
||||
cy.visit(`/${testTeam.name}/channels/town-square`);
|
||||
|
||||
// * Ensure that the new terms of service is visible
|
||||
cy.findByTestId('termsOfService').should('be.visible').and('contain.text', secondTOS);
|
||||
|
||||
// * Ensure that the accept terms button is visible and click it
|
||||
cy.get('#acceptTerms').should('be.visible').click();
|
||||
|
||||
// * Ensure the user is redirected to the appropriate team after terms are accepted
|
||||
cy.url().should('include', `/${testTeam.name}/channels/town-square`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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 @system_console @smoke
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {getAdminAccount} from '../../../support/env';
|
||||
|
||||
describe('System Console', () => {
|
||||
const sysadmin = getAdminAccount();
|
||||
let testUser;
|
||||
|
||||
before(() => {
|
||||
// # Create new team and login
|
||||
cy.apiInitSetup({loginAfter: true}).then(({user}) => {
|
||||
testUser = user;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T922 Demoted user cannot continue to view System Console', () => {
|
||||
const baseUrl = Cypress.config('baseUrl');
|
||||
|
||||
// # Set user to be a sysadmin, so it can access the system console
|
||||
cy.externalRequest({user: sysadmin, method: 'put', baseUrl, path: `users/${testUser.id}/roles`, data: {roles: 'system_user system_admin'}});
|
||||
|
||||
// # Visit a page on the system console
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.get('#adminConsoleWrapper').should('be.visible');
|
||||
cy.url().should('include', '/admin_console/reporting/system_analytics');
|
||||
|
||||
// # Change the role of the user back to user
|
||||
cy.externalRequest({user: sysadmin, method: 'put', baseUrl, path: `users/${testUser.id}/roles`, data: {roles: 'system_user'}});
|
||||
|
||||
// # User should get redirected to town square
|
||||
cy.get('#adminConsoleWrapper').should('not.exist');
|
||||
cy.get('#postListContent', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible');
|
||||
cy.url().should('include', 'town-square');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,303 @@
|
||||
// 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 @not_cloud
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('Environment', () => {
|
||||
let townsquareLink;
|
||||
let testTeam;
|
||||
|
||||
const mattermostIcon = 'mattermost-icon_128x128.png';
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
testTeam = team;
|
||||
townsquareLink = `/${team.name}/channels/town-square`;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T959 - Web server mode - Webserver gzip', () => {
|
||||
cy.visit('/admin_console/environment/web_server');
|
||||
|
||||
// # Click dropdown to open selection
|
||||
cy.findByTestId('ServiceSettings.WebserverModedropdown').should('have.value', 'gzip');
|
||||
|
||||
// # Navigate to a channel
|
||||
cy.visit(townsquareLink);
|
||||
|
||||
// # Open team menu and click "Team Settings"
|
||||
cy.uiOpenTeamMenu('Team Settings');
|
||||
|
||||
// * Check that the 'Team Settings' modal was opened
|
||||
cy.get('#teamSettingsModal').should('exist').within(() => {
|
||||
// clicking on edit button
|
||||
cy.get('#team_iconEdit').should('be.visible').click();
|
||||
|
||||
// verify the settings picture button is visible to click
|
||||
cy.findByTestId('inputSettingPictureButton').should('be.visible').click();
|
||||
|
||||
// * Before uploading the picture the save button must be disabled
|
||||
cy.uiSaveButton().should('be.disabled');
|
||||
|
||||
// # Upload a file on center view
|
||||
cy.findByTestId('uploadPicture').attachFile(mattermostIcon);
|
||||
|
||||
// after uploading the picture the save button must be disabled
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Close the modal
|
||||
cy.get('#teamSettingsModalLabel').find('button').should('be.visible').click();
|
||||
});
|
||||
|
||||
// Validate that the image is being displayed
|
||||
cy.get(`#${testTeam.name}TeamButton`).scrollIntoView().within(() => {
|
||||
cy.findByTestId('teamIconImage').then((imageDiv) => {
|
||||
const url = imageDiv.css('background-image').split('"')[1];
|
||||
|
||||
// # Verify that the response to fetch image is successful and not emmpty
|
||||
cy.request({url, encoding: 'base64'}).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
expect(response.body).to.not.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T960 - Web server mode - Webserver Uncompressed', () => {
|
||||
cy.visit('/admin_console/environment/web_server');
|
||||
|
||||
// # Click dropdown to open selection
|
||||
cy.findByTestId('ServiceSettings.WebserverModedropdown').select('Uncompressed');
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click().wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Navigate to a channel
|
||||
cy.visit(townsquareLink);
|
||||
|
||||
// # Open team menu and click "Team Settings"
|
||||
cy.uiOpenTeamMenu('Team Settings');
|
||||
|
||||
// * Check that the 'Team Settings' modal was opened
|
||||
cy.get('#teamSettingsModal').should('exist').within(() => {
|
||||
// clicking on edit button
|
||||
cy.get('#team_iconEdit').should('be.visible').click();
|
||||
|
||||
// verify the settings picture button is visible to click
|
||||
cy.findByTestId('inputSettingPictureButton').should('be.visible').click();
|
||||
|
||||
// * Before uploading the picture the save button must be disabled
|
||||
cy.uiSaveButton().should('be.disabled');
|
||||
|
||||
// # Upload a file on center view
|
||||
cy.findByTestId('uploadPicture').attachFile(mattermostIcon);
|
||||
|
||||
// * After uploading the picture the save button must be disabled
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Close the modal
|
||||
cy.get('#teamSettingsModalLabel').find('button').should('be.visible').click();
|
||||
});
|
||||
|
||||
// Validate that the image is being displayed
|
||||
cy.get(`#${testTeam.name}TeamButton`).scrollIntoView().within(() => {
|
||||
cy.findByTestId('teamIconImage').then((imageDiv) => {
|
||||
const url = imageDiv.css('background-image').split('"')[1];
|
||||
|
||||
// # Verify that the response to fetch image is successful and not emmpty
|
||||
cy.request({url, encoding: 'base64'}).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
expect(response.body).to.not.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T961 - Web server mode - Webserver Disabled', () => {
|
||||
cy.visit('/admin_console/environment/web_server');
|
||||
|
||||
// # Click dropdown to open selection
|
||||
cy.findByTestId('ServiceSettings.WebserverModedropdown').select('Disabled');
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click().wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Navigate to a channel
|
||||
cy.visit(townsquareLink);
|
||||
|
||||
// # Open team menu and click "Team Settings"
|
||||
cy.uiOpenTeamMenu('Team Settings');
|
||||
|
||||
// * Check that the 'Team Settings' modal was opened
|
||||
cy.get('#teamSettingsModal').should('exist').within(() => {
|
||||
// clicking on edit button
|
||||
cy.get('#team_iconEdit').should('be.visible').click();
|
||||
|
||||
// verify the settings picture button is visible to click
|
||||
cy.findByTestId('inputSettingPictureButton').should('be.visible').click();
|
||||
|
||||
// * Before uploading the picture the save button must be disabled
|
||||
cy.uiSaveButton().should('be.disabled');
|
||||
|
||||
// # Upload a file on center view
|
||||
cy.findByTestId('uploadPicture').attachFile(mattermostIcon);
|
||||
|
||||
// * After uploading the picture the save button must be disabled
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Close the modal
|
||||
cy.get('#teamSettingsModalLabel').find('button').should('be.visible').click();
|
||||
});
|
||||
|
||||
// Validate that the image is being displayed
|
||||
cy.get(`#${testTeam.name}TeamButton`).scrollIntoView().within(() => {
|
||||
cy.findByTestId('teamIconImage').then((imageDiv) => {
|
||||
const url = imageDiv.css('background-image').split('"')[1];
|
||||
|
||||
// # Verify that the response to fetch image is successful not emmpty
|
||||
cy.request({url, encoding: 'base64'}).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
expect(response.body).to.not.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T991 - Database fields can be edited and saved', () => {
|
||||
cy.visit('/admin_console/environment/database');
|
||||
|
||||
const queryTimeoutValue = 100;
|
||||
const maxOpenConnsValue = 1000;
|
||||
cy.findByTestId('queryTimeoutinput').clear().type(queryTimeoutValue);
|
||||
cy.findByTestId('maxOpenConnsinput').clear().type(maxOpenConnsValue);
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click().wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the database setting values are saved
|
||||
expect(config.SqlSettings.QueryTimeout).to.eq(queryTimeoutValue);
|
||||
expect(config.SqlSettings.MaxOpenConns).to.eq(maxOpenConnsValue);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T993 - Minimum hashtag length at least 2', () => {
|
||||
const defaultHashtagLength = 3;
|
||||
const minimumHashtagLength = 2;
|
||||
|
||||
function setAndVerifyHashtagLength(length) {
|
||||
cy.findByTestId('minimumHashtagLengthinput').clear().type(length);
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click({force: true}).wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Verify saved config value
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const expectedLength = length < minimumHashtagLength ? defaultHashtagLength : length;
|
||||
expect(config.ServiceSettings.MinimumHashtagLength).to.eq(expectedLength);
|
||||
});
|
||||
}
|
||||
|
||||
cy.visit('/admin_console/environment/database');
|
||||
|
||||
setAndVerifyHashtagLength(4);
|
||||
setAndVerifyHashtagLength(1);
|
||||
setAndVerifyHashtagLength(2);
|
||||
});
|
||||
|
||||
it('MM-T995 - Amazon S3 settings', () => {
|
||||
cy.visit('/admin_console/environment/file_storage');
|
||||
|
||||
// # CLick dropdown to open selection
|
||||
cy.findByTestId('FileSettings.DriverNamedropdown').select('Amazon S3');
|
||||
|
||||
// Check that these fields are disabled
|
||||
cy.findByTestId('FileSettings.Directoryinput').should('be.disabled');
|
||||
|
||||
// Check that these fields are not disabled
|
||||
cy.findByTestId('FileSettings.MaxFileSizenumber').should('not.be.disabled');
|
||||
cy.findByTestId('FileSettings.AmazonS3Bucketinput').should('not.be.disabled');
|
||||
cy.findByTestId('FileSettings.AmazonS3PathPrefixinput').should('not.be.disabled');
|
||||
cy.findByTestId('FileSettings.AmazonS3Regioninput').should('not.be.disabled');
|
||||
cy.findByTestId('FileSettings.AmazonS3AccessKeyIdinput').should('not.be.disabled');
|
||||
|
||||
const amazonS3BucketName = 'test';
|
||||
const amazonS3PathPrefix = 'test';
|
||||
cy.findByTestId('FileSettings.MaxFileSizenumber').clear().type(52428800);
|
||||
cy.findByTestId('FileSettings.AmazonS3Bucketinput').clear().type(amazonS3BucketName);
|
||||
cy.findByTestId('FileSettings.AmazonS3PathPrefixinput').clear().type(amazonS3PathPrefix);
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click().wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the database setting values are saved
|
||||
expect(config.FileSettings.AmazonS3Bucket).to.eq(amazonS3BucketName);
|
||||
expect(config.FileSettings.AmazonS3PathPrefix).to.eq(amazonS3PathPrefix);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T996 - Amazon S3 connection error messaging', () => {
|
||||
cy.visit('/admin_console/environment/file_storage');
|
||||
|
||||
// # CLick dropdown to open selection
|
||||
cy.findByTestId('FileSettings.DriverNamedropdown').select('Amazon S3');
|
||||
|
||||
const amazonS3PathPrefix = 'test';
|
||||
cy.findByTestId('FileSettings.AmazonS3Bucketinput').clear();
|
||||
cy.findByTestId('FileSettings.AmazonS3PathPrefixinput').scrollIntoView().clear().type(amazonS3PathPrefix);
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click().wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
cy.get('#TestS3Connection').scrollIntoView().should('be.visible').within(() => {
|
||||
cy.findByText('Test Connection').should('be.visible').click().wait(TIMEOUTS.ONE_SEC);
|
||||
waitForAlert('Connection unsuccessful: S3 Bucket is required');
|
||||
});
|
||||
|
||||
const amazonS3BucketName = '12';
|
||||
cy.findByTestId('FileSettings.AmazonS3Bucketinput').clear().type(amazonS3BucketName);
|
||||
|
||||
// # Click Save button to save the settings
|
||||
cy.get('#saveSetting').click().wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
cy.get('#TestS3Connection').scrollIntoView().should('be.visible').within(() => {
|
||||
cy.findByText('Test Connection').should('be.visible').click().wait(TIMEOUTS.ONE_SEC);
|
||||
waitForAlert('Connection unsuccessful: Unable to connect to S3. Verify your Amazon S3 connection authorization parameters and authentication settings.');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T963 - Configuration - Purge caches', () => {
|
||||
cy.visit('/admin_console/environment/web_server');
|
||||
|
||||
// # Find the purge all caches button on the page and click it
|
||||
cy.get('#PurgeButton').scrollIntoView().should('be.visible').within(() => {
|
||||
cy.findByText('Purge All Caches').should('be.visible').click().wait(TIMEOUTS.ONE_SEC);
|
||||
});
|
||||
|
||||
// # Reload the page
|
||||
cy.reload();
|
||||
|
||||
// * Verify app continues to run successfully by querying for the header
|
||||
cy.get('.admin-console', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').within(() => {
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Web Server');
|
||||
});
|
||||
});
|
||||
|
||||
function waitForAlert(message) {
|
||||
cy.waitUntil(() => cy.get('.alert').scrollIntoView().should('be.visible').then((alert) => {
|
||||
return alert[0].innerText === message;
|
||||
}));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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 @cloud_only
|
||||
|
||||
const professionalPaidFeatures = [
|
||||
{sidebarName: 'Announcement Banner', featureDiscoveryTitle: 'custom announcement banners'},
|
||||
{sidebarName: 'AD/LDAP', featureDiscoveryTitle: 'LDAP'},
|
||||
{sidebarName: 'SAML 2.0', featureDiscoveryTitle: 'SAML'},
|
||||
{sidebarName: 'OpenID Connect', featureDiscoveryTitle: 'OpenID Connect'},
|
||||
{sidebarName: 'Guest Access', featureDiscoveryTitle: 'guest accounts'},
|
||||
];
|
||||
|
||||
const enterprisePaidFeatures = [
|
||||
{sidebarName: 'Groups', featureDiscoveryTitle: 'Active Directory/LDAP groups'},
|
||||
{sidebarName: 'System Roles', featureDiscoveryTitle: 'controlled access to the System Console'},
|
||||
{sidebarName: 'Data Retention Policy', featureDiscoveryTitle: 'Create data retention schedules with Mattermost Enterprise'},
|
||||
{sidebarName: 'Compliance Export', featureDiscoveryTitle: 'Run compliance exports with Mattermost Enterprise'},
|
||||
{sidebarName: 'Custom Terms of Service', featureDiscoveryTitle: 'Create custom terms of service with Mattermost Enterprise'},
|
||||
];
|
||||
|
||||
function simulateSubscription(subscription) {
|
||||
cy.intercept('GET', '**/api/v4/cloud/subscription', {
|
||||
statusCode: 200,
|
||||
body: subscription,
|
||||
});
|
||||
}
|
||||
|
||||
function withTrialBefore(trialed) {
|
||||
cy.intercept('GET', '**/api/v4/trial-license/prev', {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
IsLicensed: trialed,
|
||||
IsTrial: trialed,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe('Feature discovery cloud', () => {
|
||||
beforeEach(() => {
|
||||
// * Check if server has license for Cloud
|
||||
cy.apiRequireLicenseForFeature('Cloud');
|
||||
|
||||
// # Visit admin console
|
||||
cy.visit('/admin_console');
|
||||
});
|
||||
|
||||
const testForTrialButton = () => {
|
||||
cy.get('#start_cloud_trial_btn').should('exist');
|
||||
cy.get('#start_cloud_trial_btn').contains('Try free for 30 days');
|
||||
};
|
||||
|
||||
const testForUpgradeToProfessionalOption = () => {
|
||||
cy.get("button[data-testid='featureDiscovery_primaryCallToAction']").should('contain', 'Upgrade now');
|
||||
cy.get("button[data-testid='featureDiscovery_primaryCallToAction']").click();
|
||||
|
||||
cy.get('.PurchaseModal').should('exist');
|
||||
|
||||
// *Close PurchaseModal
|
||||
cy.get('.close-x').click();
|
||||
};
|
||||
|
||||
it('MM-T5120 Cloud | Ensure feature discovery shows option to start trial when no trial has ever been done before', () => {
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_1',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
simulateSubscription(subscription);
|
||||
withTrialBefore('false');
|
||||
[...professionalPaidFeatures, ...enterprisePaidFeatures].forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
testForTrialButton();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T5121 Cloud | Ensure feature discovery for professional features shows option to upgrade to professional', () => {
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_1',
|
||||
is_free_trial: 'false',
|
||||
trial_end_at: 1,
|
||||
};
|
||||
simulateSubscription(subscription);
|
||||
withTrialBefore('false');
|
||||
professionalPaidFeatures.forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
testForUpgradeToProfessionalOption();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T5122 Cloud | Ensure feature discovery for enterprise features shows option to contact sales', () => {
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_1',
|
||||
is_free_trial: 'false',
|
||||
trial_end_at: 1,
|
||||
};
|
||||
simulateSubscription(subscription);
|
||||
withTrialBefore('false');
|
||||
enterprisePaidFeatures.forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
cy.get("button[data-testid='featureDiscovery_primaryCallToAction']").should('contain', 'Contact sales');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @system_console @not_cloud
|
||||
|
||||
const professionalPaidFeatures = [
|
||||
{sidebarName: 'Announcement Banner', featureDiscoveryTitle: 'custom announcement banners'},
|
||||
{sidebarName: 'AD/LDAP', featureDiscoveryTitle: 'LDAP'},
|
||||
{sidebarName: 'SAML 2.0', featureDiscoveryTitle: 'SAML'},
|
||||
{sidebarName: 'OpenID Connect', featureDiscoveryTitle: 'OpenID Connect'},
|
||||
{sidebarName: 'Guest Access', featureDiscoveryTitle: 'guest accounts'},
|
||||
];
|
||||
|
||||
const enterprisePaidFeatures = [
|
||||
{sidebarName: 'Groups', featureDiscoveryTitle: 'Active Directory/LDAP groups'},
|
||||
{sidebarName: 'System Roles', featureDiscoveryTitle: 'controlled access to the System Console'},
|
||||
{sidebarName: 'Data Retention Policy', featureDiscoveryTitle: 'Create data retention schedules with Mattermost Enterprise'},
|
||||
{sidebarName: 'Compliance Export', featureDiscoveryTitle: 'Run compliance exports with Mattermost Enterprise'},
|
||||
{sidebarName: 'Custom Terms of Service', featureDiscoveryTitle: 'Create custom terms of service with Mattermost Enterprise'},
|
||||
];
|
||||
|
||||
function withTrialBefore(trialed) {
|
||||
cy.intercept('GET', '**/api/v4/trial-license/prev', {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
IsLicensed: trialed,
|
||||
IsTrial: trialed,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe('Feature discovery self hosted', () => {
|
||||
beforeEach(() => {
|
||||
cy.shouldRunOnTeamEdition();
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// # Visit admin console
|
||||
cy.visit('/admin_console');
|
||||
});
|
||||
|
||||
it('MM-T5123 Self-Hosted | Ensure feature discovery shows option to start trial when no trial has ever been done before', () => {
|
||||
withTrialBefore('false');
|
||||
[...professionalPaidFeatures, ...enterprisePaidFeatures].forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
cy.get('#start_trial_btn').should('exist');
|
||||
cy.get('#start_trial_btn').contains('Start trial');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T5124 Self-Hosted | Ensure feature discovery for professional features shows option to purchase when a trial has been done before', () => {
|
||||
withTrialBefore('true');
|
||||
professionalPaidFeatures.forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
cy.get('#post_trial_purchase_license').should('contain', 'Purchase a license');
|
||||
cy.get('#post_trial_purchase_license').should('be.enabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T5125 Self-Hosted | Ensure feature discovery for enterprise features shows option to contact sales when a trial has been done before', () => {
|
||||
withTrialBefore('true');
|
||||
enterprisePaidFeatures.forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
cy.get("button[data-testid='featureDiscovery_primaryCallToAction']").should('contain', 'Contact sales');
|
||||
cy.get("button[data-testid='featureDiscovery_primaryCallToAction']").should('be.enabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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 @te_only @system_console
|
||||
|
||||
describe('Feature discovery', () => {
|
||||
before(() => {
|
||||
cy.shouldRunOnTeamEdition();
|
||||
|
||||
// # Visit admin console
|
||||
cy.visit('/admin_console');
|
||||
});
|
||||
|
||||
const testCallsToAction = () => {
|
||||
cy.get("a[data-testid$='CallToAction']").each(($el) => {
|
||||
cy.wrap($el).should('have.attr', 'href').and('not.eq', '');
|
||||
cy.wrap($el).should('have.attr', 'target', '_blank');
|
||||
});
|
||||
};
|
||||
|
||||
it('MM-T4035 - Make Sure All Feature Discoveries Exist', () => {
|
||||
[
|
||||
{sidebarName: 'AD/LDAP', featureDiscoveryTitle: 'LDAP'},
|
||||
{sidebarName: 'SAML 2.0', featureDiscoveryTitle: 'SAML'},
|
||||
{sidebarName: 'OpenID Connect', featureDiscoveryTitle: 'OpenID Connect'},
|
||||
{sidebarName: 'Groups', featureDiscoveryTitle: 'Active Directory/LDAP groups'},
|
||||
{sidebarName: 'Compliance Export', featureDiscoveryTitle: 'compliance exports'},
|
||||
{sidebarName: 'System Roles', featureDiscoveryTitle: 'controlled access to the System Console'},
|
||||
{sidebarName: 'Permissions', featureDiscoveryTitle: 'role-based permissions'},
|
||||
{sidebarName: 'Channels', featureDiscoveryTitle: 'read-only channels'},
|
||||
{sidebarName: 'Custom Terms of Service', featureDiscoveryTitle: 'custom terms of service'},
|
||||
{sidebarName: 'Announcement Banner', featureDiscoveryTitle: 'custom announcement banners'},
|
||||
{sidebarName: 'Guest Access', featureDiscoveryTitle: 'guest accounts'},
|
||||
].forEach(({sidebarName, featureDiscoveryTitle}) => {
|
||||
cy.get('li').contains(sidebarName).click();
|
||||
cy.get("div[data-testid='featureDiscovery_title']").should('contain', featureDiscoveryTitle);
|
||||
testCallsToAction();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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 @system_console
|
||||
|
||||
/**
|
||||
* Note: This test requires hundreds of deactivated users
|
||||
* May generate by modifying `make test-data` command at `./mattermost-server/Makefile`
|
||||
* Should change to `sampledata -w 4 -u 60 --deactivated-users 200`
|
||||
*/
|
||||
|
||||
const perPage = 50;
|
||||
|
||||
describe('System Console', () => {
|
||||
it('SC18512 List pages of inactive users', () => {
|
||||
// # Go to users management page
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// # Select inactive users
|
||||
cy.get('#selectUserStatus').select('Inactive');
|
||||
|
||||
cy.apiGetAnalytics().then(({analytics}) => {
|
||||
const inactiveUsers = analytics.filter((d) => {
|
||||
return d.name === 'inactive_user_count';
|
||||
}).reduce((_, item) => {
|
||||
return item.value;
|
||||
}, 0);
|
||||
|
||||
const pages = Math.floor(inactiveUsers / perPage);
|
||||
const remainder = inactiveUsers % perPage;
|
||||
Cypress._.forEach(Array(pages), (_, index) => {
|
||||
if (pages === index) {
|
||||
// * This is the last page, so:
|
||||
// * - number of users should match the remainder
|
||||
// * - no next button since no more inactive users to load
|
||||
cy.findAllByTestId('userListRow').should('have.length', remainder);
|
||||
cy.get('#searchableUserListNextBtn').should('not.exist');
|
||||
} else {
|
||||
// * There are still next page to load, so:
|
||||
// * - number of users should match per page
|
||||
// * - next button is visible
|
||||
// # Click "Next" to load more.
|
||||
cy.findAllByTestId('userListRow').should('have.length', perPage);
|
||||
cy.get('#searchableUserListNextBtn').should('be.visible').click();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @system_console
|
||||
|
||||
describe('System Console', () => {
|
||||
let townSquareUrl;
|
||||
|
||||
before(() => {
|
||||
// # Initialize setup and visit town-square
|
||||
cy.apiInitSetup().then((out) => {
|
||||
townSquareUrl = out.townSquareUrl;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1100 Lock Teammate Name Display for all users', () => {
|
||||
// # Go to system admin page
|
||||
cy.visit('/admin_console/site_config/users_and_teams');
|
||||
|
||||
// # Set Teammate Name Display dropdown to 'Show nickname if one exists, otherwise show first and last name' and set Lock Teammate Name Display to false
|
||||
cy.findByTestId('TeamSettings.TeammateNameDisplaydropdown').select('nickname_full_name');
|
||||
cy.findByTestId('TeamSettings.LockTeammateNameDisplayfalse').click();
|
||||
|
||||
// * Assert that there exists a description underneath the Teammate Name Display lock setting with the following text
|
||||
cy.findByTestId('TeamSettings.LockTeammateNameDisplayhelp-text').contains('When true, disables users\' ability to change settings under Settings > Display > Teammate Name Display.').should('be.visible');
|
||||
|
||||
// # Click save button
|
||||
cy.get('#saveSetting').click();
|
||||
|
||||
// # Go to main page
|
||||
cy.visit(townSquareUrl);
|
||||
|
||||
// # 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();
|
||||
|
||||
// * Assert the description under the Teammate Name Display title has changed to Show first and last name
|
||||
cy.get('#name_formatDesc').contains('Show first and last name').should('be.visible');
|
||||
|
||||
// # Go back to System Admin console page
|
||||
cy.visit('/admin_console/site_config/users_and_teams');
|
||||
|
||||
// # Set Teammate Name Display dropdown to 'Show by username' and set Lock Teammate Name Display to true
|
||||
cy.findByTestId('TeamSettings.TeammateNameDisplaydropdown').select('username');
|
||||
cy.findByTestId('TeamSettings.LockTeammateNameDisplaytrue').click();
|
||||
|
||||
// # Click save button
|
||||
cy.uiSave();
|
||||
|
||||
// # Go to main page
|
||||
cy.visit(townSquareUrl);
|
||||
|
||||
// # Go to Settings > Display
|
||||
cy.uiOpenSettingsModal('Display');
|
||||
|
||||
// * Assert the description under the Teammate Name Display title has changed to Show username
|
||||
cy.get('#name_formatDesc').contains('Show username').should('be.visible');
|
||||
|
||||
// # Click edit button for Teammate Name Display
|
||||
cy.get('#name_formatEdit').click();
|
||||
|
||||
// * Assert that there exists a description noting that this feature has been locked and can only be changed by system admin
|
||||
cy.get('#extraInfo').contains('This field is handled through your System Administrator. If you want to change it, you need to do so through your System Administrator.').should('be.visible');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
// 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 @system_console
|
||||
|
||||
describe('Main menu', () => {
|
||||
before(() => {
|
||||
cy.visit('/admin_console');
|
||||
|
||||
// # Open the hamburger menu
|
||||
cy.get('button > span[class="menu-icon"]').click();
|
||||
});
|
||||
|
||||
const verifyLink = (text, link) => {
|
||||
// * Verify link opens in new tab
|
||||
cy.get('a[href="' + link + '"]').scrollIntoView().should('have.attr', 'target', '_blank');
|
||||
|
||||
// * Verify link text matches correct href value
|
||||
cy.get('a[href="' + link + '"]').contains(text);
|
||||
};
|
||||
|
||||
it('MM-T909 Can switch to team', () => {
|
||||
// * Verify teams are visible
|
||||
cy.findByText('Switch to eligendi').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T910 Can open Administrators Guide', () => {
|
||||
cy.apiGetClientLicense().then(({isCloudLicensed}) => {
|
||||
const guideLink = isCloudLicensed ?
|
||||
'https://docs.mattermost.com/guides/administration.html#cloud-workspace-management' :
|
||||
'https://docs.mattermost.com/guides/administration.html';
|
||||
|
||||
// * Verify administrator's guide link
|
||||
verifyLink("Administrator's Guide", guideLink);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T911 Can open Troubleshooting Forum', () => {
|
||||
// * Verify troubleshooting forum link
|
||||
verifyLink('Troubleshooting Forum', 'https://forum.mattermost.com/t/how-to-use-the-troubleshooting-forum/150');
|
||||
});
|
||||
|
||||
it('MM-T914 Can log out from system console', () => {
|
||||
// * Verify log out button is visible
|
||||
cy.findByText('Log Out').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T912 Can open Commercial Support', () => {
|
||||
// * Verify commercial support
|
||||
cy.findByText('Commercial Support').click();
|
||||
cy.get('#commercialSupportModal').should('be.visible');
|
||||
cy.uiClose();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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 @system_console @te_only
|
||||
|
||||
describe('Settings', () => {
|
||||
before(() => {
|
||||
cy.shouldRunOnTeamEdition();
|
||||
});
|
||||
|
||||
it('MM-T1149 Hide mobile-specific settings', () => {
|
||||
cy.visit('/admin_console/site_config/file_sharing_downloads');
|
||||
|
||||
// * Check buttons
|
||||
cy.get('#adminConsoleWrapper .wrapper--fixed > .admin-console__wrapper').
|
||||
should('be.visible').
|
||||
and('contain.text', 'Allow File Sharing');
|
||||
|
||||
cy.get('#adminConsoleWrapper .wrapper--fixed > .admin-console__wrapper').
|
||||
should('be.visible').
|
||||
and('not.contain.text', 'Allow File Uploads on Mobile');
|
||||
|
||||
cy.get('#adminConsoleWrapper .wrapper--fixed > .admin-console__wrapper').
|
||||
should('be.visible').
|
||||
and('not.contain.text', 'Allow File Downloads on Mobile');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
// ***************************************************************
|
||||
|
||||
// - Requires mmctl at fixtures folder
|
||||
// -> copy ./mmctl/mmctl to ./mattermost-webapp/e2e/cypress/tests/fixtures/mmctl
|
||||
|
||||
// Group: @channels @plugin @system_console
|
||||
|
||||
describe('System Console > Plugin Management ', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
});
|
||||
|
||||
it('MM-T4742 Plugin Marketplace URL should be disabled if EnableUploads are disabled', () => {
|
||||
// # Set plugin settings
|
||||
const newSettings = {
|
||||
PluginSettings: {
|
||||
Enable: true,
|
||||
},
|
||||
};
|
||||
cy.apiUpdateConfig(newSettings);
|
||||
|
||||
cy.exec('tests/fixtures/mmctl --local config set PluginSettings.EnableUploads false');
|
||||
|
||||
cy.visit('/admin_console/plugins/plugin_management');
|
||||
|
||||
// * Verify marketplace URL is disabled.
|
||||
cy.findByTestId('marketplaceUrlinput').should('be.disabled');
|
||||
|
||||
cy.exec('tests/fixtures/mmctl --local config set PluginSettings.EnableUploads true');
|
||||
|
||||
cy.reload();
|
||||
|
||||
// * Verify marketplace URL is enabled.
|
||||
cy.findByTestId('marketplaceUrlinput').should('be.enabled');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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 @system_console @not_cloud
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('System Console > Server Logs', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// # Visit the system console.
|
||||
cy.visit('/admin_console');
|
||||
|
||||
// # Go to the Server Logs section.
|
||||
cy.get('#reporting\\/server_logs').click().wait(TIMEOUTS.TWO_SEC);
|
||||
});
|
||||
|
||||
it('MM-T908 Logs - Verify content categories', () => {
|
||||
// * Verify the banner is showed.
|
||||
cy.get('.banner__content span').should('not.empty');
|
||||
|
||||
// * Verify reload button is showed.
|
||||
cy.get('.admin-logs-content button span').should('be.visible').and('contain', 'Reload');
|
||||
|
||||
// * Verify that server logs are showed correctly.
|
||||
cy.get('.admin-logs-content div.LogTable').should('be.visible').and('not.empty');
|
||||
cy.get('.admin-logs-content div.LogTable span').eq(0).should('not.empty');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
// 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 @system_console @not_cloud
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('System Console > Site Statistics', () => {
|
||||
let testUser;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
cy.apiInitSetup({loginAfter: true}).then(({user, offTopicUrl}) => {
|
||||
// # Login as test user and visit off-topic
|
||||
testUser = user;
|
||||
cy.visit(offTopicUrl);
|
||||
|
||||
// # Post a message as testUser to make them daily/monthly active
|
||||
cy.postMessage('New Daily Message');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T903 - Site Statistics > Deactivating a user increments the Daily and Monthly Active Users counts down', () => {
|
||||
let totalActiveUsersInitial;
|
||||
let dailyActiveUsersInitial;
|
||||
let monthlyActiveUsersInitial;
|
||||
let totalActiveUsersFinal;
|
||||
let dailyActiveUsersFinal;
|
||||
let monthlyActiveUsersFinal;
|
||||
|
||||
// # Go to admin console
|
||||
cy.apiAdminLogin();
|
||||
cy.visit('/admin_console');
|
||||
|
||||
// # Go to system analytics
|
||||
cy.findByTestId('reporting.system_analytics', {timeout: TIMEOUTS.ONE_MIN}).click();
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Get the number text and turn them into numbers
|
||||
cy.findByTestId('totalActiveUsers').invoke('text').then((totalActiveText) => {
|
||||
totalActiveUsersInitial = parseInt(totalActiveText, 10);
|
||||
});
|
||||
cy.findByTestId('dailyActiveUsers').invoke('text').then((dailyActiveText) => {
|
||||
dailyActiveUsersInitial = parseInt(dailyActiveText, 10);
|
||||
});
|
||||
cy.findByTestId('monthlyActiveUsers').invoke('text').then((monthlyActiveText) => {
|
||||
monthlyActiveUsersInitial = parseInt(monthlyActiveText, 10);
|
||||
|
||||
// # Deactivate user and reload page and then wait 2 seconds
|
||||
cy.externalActivateUser(testUser.id, false);
|
||||
cy.reload();
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
});
|
||||
|
||||
// # Get the numbers required again
|
||||
cy.findByTestId('totalActiveUsers').invoke('text').then((totalActiveFinalText) => {
|
||||
totalActiveUsersFinal = parseInt(totalActiveFinalText, 10);
|
||||
});
|
||||
cy.findByTestId('dailyActiveUsers').invoke('text').then((dailyActiveFinalText) => {
|
||||
dailyActiveUsersFinal = parseInt(dailyActiveFinalText, 10);
|
||||
});
|
||||
cy.findByTestId('monthlyActiveUsers').invoke('text').then((monthlyActiveFinalText) => {
|
||||
monthlyActiveUsersFinal = parseInt(monthlyActiveFinalText, 10);
|
||||
|
||||
// * Assert that the final number is the initial number minus one
|
||||
expect(totalActiveUsersFinal).equal(totalActiveUsersInitial - 1);
|
||||
expect(dailyActiveUsersFinal).equal(dailyActiveUsersInitial - 1);
|
||||
expect(monthlyActiveUsersFinal).equal(monthlyActiveUsersInitial - 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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 @te_only @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('System Console > Site Statistics', () => {
|
||||
before(() => {
|
||||
cy.shouldRunOnTeamEdition();
|
||||
});
|
||||
|
||||
it('MM-T3804 Site Statistics displays expected content categories', () => {
|
||||
// # Visit site statistics page.
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
|
||||
// * Check that the header has loaded correctly and contains the expected text.
|
||||
cy.get('.admin-console__header span', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').should('contain', 'System Statistics');
|
||||
|
||||
// * Check that the rows for the table were generated.
|
||||
cy.get('.admin-console__content .row').should('have.length', 4);
|
||||
|
||||
// * Check that the title content for the stats is as expected.
|
||||
cy.get('.admin-console__content .row').eq(0).find('.title').eq(0).should('contain', 'Total Active Users');
|
||||
cy.get('.admin-console__content .row').eq(0).find('.title').eq(1).should('contain', 'Total Teams');
|
||||
cy.get('.admin-console__content .row').eq(0).find('.title').eq(2).should('contain', 'Total Channels');
|
||||
cy.get('.admin-console__content .row').eq(0).find('.title').eq(3).should('contain', 'Total Posts');
|
||||
cy.get('.admin-console__content .row').eq(0).find('.title').eq(4).should('contain', 'Daily Active Users');
|
||||
cy.get('.admin-console__content .row').eq(0).find('.title').eq(5).should('contain', 'Monthly Active Users');
|
||||
|
||||
// * Check that the values for the stats are valid.
|
||||
cy.get('.admin-console__content .row').eq(0).find('.content').each((el) => {
|
||||
cy.waitUntil(() => cy.wrap(el).then((content) => {
|
||||
return content[0].innerText !== 'Loading...';
|
||||
}));
|
||||
cy.wrap(el).eq(0).invoke('text').then(parseFloat).should('be.gt', 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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 @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('System Console > Team Statistics', () => {
|
||||
before(() => {
|
||||
// # Create team.
|
||||
cy.apiCreateTeam('mmt906-team', 'mmt906-team').then(({team}) => {
|
||||
// # Create private channel.
|
||||
cy.apiCreateChannel(team.id, 'mmt906-ch', 'mmt906-ch', 'P');
|
||||
|
||||
// # Visit team statistics page.
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
|
||||
// # Select created team.
|
||||
cy.get('select.team-statistics__team-filter__dropdown').select(team.id);
|
||||
|
||||
// # Explicit wait to allow stats to get loaded
|
||||
cy.wait(TIMEOUTS.TWO_SEC);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T906 Team Statistics displays expected content categories', () => {
|
||||
// * Check that the header has loaded correctly and contains the expected text.
|
||||
cy.get('.team-statistics__header span').should('be.visible').should('contain', 'Team Statistics for');
|
||||
|
||||
// * Check that the rows for the table were generated.
|
||||
cy.get('.grid-statistics__card').should('have.length', 4);
|
||||
|
||||
// * Check that the title content for the stats is as expected.
|
||||
cy.get('.admin-console__content').eq(0).find('.title').eq(0).should('contain', 'Total Active Users');
|
||||
cy.get('.admin-console__content').eq(0).find('.title').eq(1).should('contain', 'Public Channels');
|
||||
cy.get('.admin-console__content').eq(0).find('.title').eq(2).should('contain', 'Private Channels');
|
||||
cy.get('.admin-console__content').eq(0).find('.title').eq(3).should('contain', 'Total Posts');
|
||||
|
||||
cy.get('.total-count.by-day').eq(0).find('.title').should('contain', 'Total Posts');
|
||||
cy.get('.total-count.by-day').eq(1).find('.title').should('contain', 'Active Users With Posts');
|
||||
cy.get('.total-count.recent-active-users').eq(0).find('.title').should('contain', 'Recent Active Users');
|
||||
cy.get('.total-count.recent-active-users').eq(1).find('.title').should('contain', 'Newly Created Users');
|
||||
|
||||
// * Check that the values for the stats are valid.
|
||||
cy.get('.grid-statistics__card').each((el) => {
|
||||
cy.wrap(el).find('.content').invoke('text').then(parseFloat).should('be.gt', 0);
|
||||
});
|
||||
|
||||
// * Check that the generated tables are not empty.
|
||||
cy.get('.recent-active-users').find('table').eq(0).should('not.empty');
|
||||
cy.get('.recent-active-users').find('table').eq(1).should('not.empty');
|
||||
});
|
||||
|
||||
it('MM-T907 - Reporting ➜ Team Statistics - teams listed in alphabetical order', () => {
|
||||
cy.visit('/admin_console');
|
||||
cy.get('#reporting\\/team_statistics').click();
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Verify Teams are listed in alphabetical order, regardless of who created the team
|
||||
cy.findByTestId('teamFilter').then((el) => {
|
||||
// # Get the options and append them to a unsorted array (assume unsorted)
|
||||
const unsortedOptionsText = [];
|
||||
el[0].childNodes.forEach((child) => unsortedOptionsText.push(child.innerText));
|
||||
|
||||
// # Make a copy of the above array and then we sort them
|
||||
const sortedOptionsText = [...unsortedOptionsText].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}));
|
||||
|
||||
// * Compare the unsorted array and sorted array and if it initially was sorted, these should match
|
||||
for (let i = 0; i < unsortedOptionsText.length; i++) {
|
||||
expect(unsortedOptionsText[i]).equal(sortedOptionsText[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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 @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {getAdminAccount} from '../../../support/env';
|
||||
|
||||
describe('System Console > User Management > Users', () => {
|
||||
const admin = getAdminAccount();
|
||||
|
||||
it('MM-T940 Users - Revoke all sessions', () => {
|
||||
// # Login as System Admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// * Verify the presence of Revoke All Sessions button
|
||||
cy.get('#revoke-all-users').should('be.visible').and('not.have.class', 'btn-danger').click();
|
||||
|
||||
// * Verify the confirmation message when users clicks on the Revoke All Sessions button
|
||||
cy.get('#confirmModalLabel').should('be.visible').and('have.text', 'Revoke all sessions in the system');
|
||||
cy.get('.modal-body').should('be.visible').and('have.text', 'This action revokes all sessions in the system. All users will be logged out from all devices. Are you sure you want to revoke all sessions?');
|
||||
cy.get('#confirmModalButton').should('be.visible').and('have.class', 'btn-danger');
|
||||
|
||||
// # Click on Cancel button in the confirmation message
|
||||
cy.get('#cancelModalButton').click();
|
||||
|
||||
// * Verify if Confirmation message is closed
|
||||
cy.get('#confirmModal').should('not.exist');
|
||||
|
||||
// * Verify if the Admin's session is still active and user is still in the same page
|
||||
cy.url().should('contain', '/admin_console/user_management/users');
|
||||
|
||||
// * Verify if the Admin's Session is still active and click on it and then confirm
|
||||
cy.get('#revoke-all-users').should('be.visible').click();
|
||||
cy.get('#confirmModalButton').click();
|
||||
|
||||
// * Verify if Admin User's session is expired and is redirected to login page
|
||||
cy.url({timeout: TIMEOUTS.HALF_MIN}).should('include', '/login');
|
||||
cy.get('.login-body-card', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible');
|
||||
});
|
||||
|
||||
it('Verify for Regular Member', () => {
|
||||
// # Login as System Admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Create new setup, login as test user and visit town-square
|
||||
cy.apiInitSetup({loginAfter: true}).then(({team}) => {
|
||||
cy.visit(`/${team.name}/channels/town-square`);
|
||||
cy.get('#sidebarItem_off-topic').click({force: true});
|
||||
|
||||
// # Issue a Request to Revoke All Sessions as SysAdmin
|
||||
const baseUrl = Cypress.config('baseUrl');
|
||||
cy.externalRequest({user: admin, method: 'post', baseUrl, path: 'users/sessions/revoke/all'}).then(() => {
|
||||
// # Initiate browser activity like visit to town-square
|
||||
cy.visit(`/${team.name}/channels/town-square`);
|
||||
|
||||
// * Verify if the regular member is logged out and redirected to login page
|
||||
cy.url({timeout: TIMEOUTS.HALF_MIN}).should('include', '/login');
|
||||
cy.get('.login-body-card', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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 @not_cloud @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
|
||||
describe('System console', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.shouldHavePluginUploadEnabled();
|
||||
});
|
||||
|
||||
it('MM-T898 - Individual plugins can be searched for via the System Console search box', () => {
|
||||
cy.visit('/admin_console');
|
||||
|
||||
// # Enable Plugin Marketplace and Remote Marketplace
|
||||
cy.apiUpdateConfig({
|
||||
PluginSettings: {
|
||||
Enable: true,
|
||||
EnableMarketplace: true,
|
||||
EnableRemoteMarketplace: true,
|
||||
MarketplaceURL: 'https://api.integrations.mattermost.com',
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiInstallPluginFromUrl('https://github.com/mattermost/mattermost-plugin-antivirus/releases/download/v0.1.2/antivirus-0.1.2.tar.gz', true);
|
||||
cy.apiInstallPluginFromUrl('https://github.com/mattermost/mattermost-plugin-autolink/releases/download/v1.2.1/mattermost-autolink-1.2.1.tar.gz', true);
|
||||
cy.apiInstallPluginFromUrl('https://github.com/mattermost/mattermost-plugin-aws-SNS/releases/download/v1.1.0/com.mattermost.aws-sns-1.1.0.tar.gz', true);
|
||||
|
||||
// # A bug with the endpoint used for downloading plugins which doesn't send websocket events out so state is not updated
|
||||
// # Therefore, we visit town-square to update the state of our app then re-visit admin console
|
||||
cy.visit('ad-1/channels/town-square');
|
||||
cy.visit('/admin_console');
|
||||
|
||||
// # Type first plugin name
|
||||
cy.get('#adminSidebarFilter').type('Anti');
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Ensure anti virus plugin is highlighted
|
||||
cy.get('#plugins\\/plugin_antivirus').then((el) => {
|
||||
expect(el[0].innerHTML).includes('markjs');
|
||||
});
|
||||
|
||||
// # Type second plugin name
|
||||
cy.get('#adminSidebarFilter').clear().type('Auto');
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Ensure autolink plugin is highlighted
|
||||
cy.get('#plugins\\/plugin_mattermost-autolink').then((el) => {
|
||||
expect(el[0].innerHTML).includes('markjs');
|
||||
});
|
||||
|
||||
// # Type third plugin name
|
||||
cy.get('#adminSidebarFilter').clear().type('AWS SN');
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Ensure aws sns plugin is highlighted
|
||||
cy.get('#plugins\\/plugin_com\\.mattermost\\.aws-sns').then((el) => {
|
||||
expect(el[0].innerHTML).includes('markjs');
|
||||
});
|
||||
|
||||
cy.apiUninstallAllPlugins();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,139 @@
|
||||
// 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 @not_cloud @system_console
|
||||
|
||||
// # Goes to the System Scheme page as System Admin
|
||||
const goToSessionLengths = () => {
|
||||
cy.apiAdminLogin();
|
||||
cy.visit('/admin_console/environment/session_lengths');
|
||||
};
|
||||
|
||||
// # Wait's until the Saving text becomes Save
|
||||
const waitUntilConfigSave = () => {
|
||||
cy.waitUntil(() => cy.get('#saveSetting').then((el) => {
|
||||
return el[0].innerText === 'Save';
|
||||
}));
|
||||
};
|
||||
|
||||
// Clicks the save button in the system console page.
|
||||
// waitUntilConfigSaved: If we need to wait for the save button to go from saving -> save.
|
||||
// Usually we need to wait unless we are doing this in team override scheme
|
||||
const saveConfig = (waitUntilConfigSaved = true, clickConfirmationButton = false) => {
|
||||
// # Save if possible (if previous test ended abruptly all permissions may already be enabled)
|
||||
cy.get('#saveSetting').then((btn) => {
|
||||
if (btn.is(':enabled')) {
|
||||
btn.click();
|
||||
}
|
||||
});
|
||||
if (clickConfirmationButton) {
|
||||
cy.get('#confirmModalButton').click();
|
||||
}
|
||||
if (waitUntilConfigSaved) {
|
||||
waitUntilConfigSave();
|
||||
}
|
||||
};
|
||||
|
||||
describe('MM-T2574 Session Lengths', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
goToSessionLengths();
|
||||
});
|
||||
|
||||
describe('"Extend session length with activity" defaults to true', () => {
|
||||
it('"Extend session length with activity" radio is checked', () => {
|
||||
cy.get('#extendSessionLengthWithActivitytrue').check().should('be.checked');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Setting "Extend session length with activity" to false alters subsequent settings', () => {
|
||||
before(() => cy.get('#extendSessionLengthWithActivityfalse').check());
|
||||
it('In team edition, "Session idle timeout" setting should not exist', () => {
|
||||
cy.get('#sessionIdleTimeoutInMinutesinput').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Session Lengths settings should save successfully', () => {
|
||||
it('Setting "Extend session length with activity" to TRUE should save in UI', () => {
|
||||
cy.get('#extendSessionLengthWithActivitytrue').check();
|
||||
saveConfig();
|
||||
cy.get('#extendSessionLengthWithActivitytrue').should('be.checked');
|
||||
});
|
||||
it('Setting "Extend session length with activity" to TRUE is saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.ExtendSessionLengthWithActivity;
|
||||
expect(setting).to.be.true;
|
||||
});
|
||||
});
|
||||
it('Setting "Extend session length with activity" to FALSE should save in UI', () => {
|
||||
cy.get('#extendSessionLengthWithActivityfalse').check();
|
||||
saveConfig();
|
||||
cy.get('#extendSessionLengthWithActivityfalse').should('be.checked');
|
||||
});
|
||||
it('Setting "Extend session length with activity" to FALSE is saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.ExtendSessionLengthWithActivity;
|
||||
expect(setting).to.be.false;
|
||||
});
|
||||
});
|
||||
it('Setting "Session Length AD/LDAP and Email (hours)" should save in UI', () => {
|
||||
cy.findByTestId('sessionLengthWebInHoursinput').
|
||||
should('have.value', '720').
|
||||
clear().type('744');
|
||||
saveConfig();
|
||||
cy.findByTestId('sessionLengthWebInHoursinput').should('have.value', '744');
|
||||
});
|
||||
it('Setting "Session Length AD/LDAP and Email (hours)" should be saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.SessionLengthWebInHours;
|
||||
expect(setting).to.equal(744);
|
||||
});
|
||||
});
|
||||
it('Setting "Session Length Mobile (hours)" should save in UI', () => {
|
||||
cy.findByTestId('sessionLengthMobileInHoursinput').
|
||||
should('have.value', '720').
|
||||
clear().type('744');
|
||||
saveConfig();
|
||||
cy.findByTestId('sessionLengthMobileInHoursinput').should('have.value', '744');
|
||||
});
|
||||
it('Setting "Session Length Mobile (hours)" should be saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.SessionLengthMobileInHours;
|
||||
expect(setting).to.equal(744);
|
||||
});
|
||||
});
|
||||
it('Setting "Session Length SSO (hours)" should save in UI', () => {
|
||||
cy.findByTestId('sessionLengthSSOInHoursinput').
|
||||
should('have.value', '720').
|
||||
clear().type('744');
|
||||
saveConfig();
|
||||
cy.findByTestId('sessionLengthSSOInHoursinput').should('have.value', '744');
|
||||
});
|
||||
it('Setting "Session Length SSO (hours)" should be saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.SessionLengthSSOInHours;
|
||||
expect(setting).to.equal(744);
|
||||
});
|
||||
});
|
||||
it('Setting "Session Cache (minutes)" should save in UI', () => {
|
||||
cy.get('#sessionCacheInMinutes').
|
||||
should('have.value', '10').
|
||||
clear().type('11');
|
||||
saveConfig();
|
||||
cy.get('#sessionCacheInMinutes').should('have.value', '11');
|
||||
});
|
||||
it('Setting "Session Cache (minutes)" should be saved in the server configuration', () => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const setting = config.ServiceSettings.SessionCacheInMinutes;
|
||||
expect(setting).to.equal(11);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @te_only @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {adminConsoleNavigation} from '../../../utils/admin_console';
|
||||
|
||||
describe('System Console - Team', () => {
|
||||
before(() => {
|
||||
cy.shouldRunOnTeamEdition();
|
||||
|
||||
// # Go to system admin then verify admin console URL and header
|
||||
cy.visit('/admin_console/about/license');
|
||||
cy.url().should('include', '/admin_console/about/license');
|
||||
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).
|
||||
should('be.visible').
|
||||
and('have.text', 'Edition and License');
|
||||
});
|
||||
|
||||
const serverType = 'team';
|
||||
adminConsoleNavigation.forEach((testCase, index) => {
|
||||
const canNavigate = testCase.type.includes(serverType);
|
||||
const testTitle = `MM-T4263_${index + 1} ${canNavigate ? 'can' : 'cannot'} navigate to ${testCase.team_header || testCase.header}`;
|
||||
const testFn = canNavigate ? verifyCanNavigate : verifyCannotNavigate;
|
||||
|
||||
it(testTitle, () => {
|
||||
testFn(testCase);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verifyCanNavigate(testCase) {
|
||||
// # Click the link on the sidebar
|
||||
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).
|
||||
should('be.visible').
|
||||
findByText(testCase.sidebar).
|
||||
scrollIntoView().
|
||||
should('be.visible').
|
||||
click();
|
||||
|
||||
// * Verify that it redirects to the URL and matches with the header
|
||||
cy.url().should('include', testCase.url);
|
||||
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).
|
||||
should('be.visible').
|
||||
and(testCase.headerContains ? 'contain' : 'have.text', testCase.team_header || testCase.header);
|
||||
}
|
||||
|
||||
function verifyCannotNavigate(testCase) {
|
||||
// # Header should not exist in sidebar
|
||||
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).
|
||||
should('be.visible').
|
||||
findByText(testCase.sidebar).
|
||||
should('not.exist');
|
||||
|
||||
// # Visit the URL directly
|
||||
cy.visit(testCase.url);
|
||||
|
||||
// * Verify that it redirects to Edition and License page
|
||||
cy.url().should('include', '/admin_console/about/license');
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// 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 @enterprise @system_console @announcement_banner
|
||||
|
||||
import {hexToRgbArray, rgbArrayToString} from '../../../../utils';
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Announcement Banner', () => {
|
||||
before(() => {
|
||||
cy.apiRequireLicense();
|
||||
});
|
||||
|
||||
it('MM-T1128 Announcement Banner - Dismissible banner shows long text truncated', () => {
|
||||
const bannerEmbedLink = 'http://example.com';
|
||||
const bannerEndLink = 'http://example.com/the_end';
|
||||
const bannerText = `Here's an announcement! It has a link: ${bannerEmbedLink}. It's a really long announcement, because we have a lot to say. Be sure to read it all, click the link, then dismiss the banner, and then you can go on to the next test, which will have a shorter announcement. Thank you for reading [to the end](${bannerEndLink}) and have a nice day!`;
|
||||
const bannerBgColor = '#4378da';
|
||||
const bannerBgColorRGBArray = hexToRgbArray(bannerBgColor);
|
||||
const bannerTextColor = '#ffffff';
|
||||
const bannerTextColorRGBArray = hexToRgbArray(bannerTextColor);
|
||||
|
||||
// # Go to announcement banner config page of system console
|
||||
cy.visit('/admin_console/site_config/announcement_banner');
|
||||
|
||||
// # Enable banner if not already enabled
|
||||
cy.findByTestId('AnnouncementSettings.EnableBanner').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
cy.findByText('true').
|
||||
should('be.visible').
|
||||
click({force: true});
|
||||
});
|
||||
|
||||
// # Enter the long banner text
|
||||
cy.findByTestId('AnnouncementSettings.BannerText').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
cy.get('input').
|
||||
should('be.visible').
|
||||
clear().
|
||||
invoke('val', bannerText).
|
||||
wait(TIMEOUTS.HALF_SEC).
|
||||
type(' {backspace}{enter}');
|
||||
});
|
||||
|
||||
// # Change the banner background color
|
||||
cy.findByTestId('AnnouncementSettings.BannerColor').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
cy.get('input').
|
||||
should('be.visible').
|
||||
clear().
|
||||
type(bannerBgColor);
|
||||
});
|
||||
|
||||
// # Change the banner text color
|
||||
cy.findByTestId('AnnouncementSettings.BannerTextColor').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
cy.get('input').
|
||||
should('be.visible').
|
||||
clear().
|
||||
type(bannerTextColor);
|
||||
});
|
||||
|
||||
// # Allow for banner dismissal to true
|
||||
cy.findByTestId('AnnouncementSettings.AllowBannerDismissal').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
cy.findByText('true').
|
||||
should('be.visible').
|
||||
click({force: true});
|
||||
});
|
||||
|
||||
// # Click on the save button
|
||||
cy.get('.admin-console').
|
||||
should('exist').
|
||||
within(() => {
|
||||
cy.findByText('Save').should('be.visible').click();
|
||||
});
|
||||
|
||||
// * Verify banner overflow is hidden from viewport
|
||||
// also verify its background color and text color matches to configuration entered
|
||||
// and check if the url in the text rendered as anchor tag
|
||||
cy.get('.announcement-bar').
|
||||
as('announcementBanner').
|
||||
should('exist').
|
||||
and('is.visible').
|
||||
and('have.css', 'overflow', 'hidden').
|
||||
and(
|
||||
'have.css',
|
||||
'background-color',
|
||||
rgbArrayToString(bannerBgColorRGBArray),
|
||||
).
|
||||
and('have.css', 'color', rgbArrayToString(bannerTextColorRGBArray)).
|
||||
contains('a', bannerEmbedLink).
|
||||
should('have.attr', 'href', bannerEmbedLink);
|
||||
|
||||
// * Verify only the banner text's first part is visible by ensuring the first link
|
||||
// is visible but the second link is not
|
||||
cy.findByText(/Here's an announcement! It has a link: /).
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
cy.get(`a[href="${bannerEmbedLink}"]`).should('be.visible');
|
||||
cy.get(`a[href="${bannerEndLink}"]`).should('not.be.visible');
|
||||
});
|
||||
|
||||
// # Hover over the banner
|
||||
cy.get('@announcementBanner').trigger('mouseover');
|
||||
|
||||
// * Verify popover is visible
|
||||
cy.get('#announcement-bar__tooltip').
|
||||
as('announcementBannerTooltip').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
// * Verify complete banner is present in the popover
|
||||
cy.findByText(/Here's an announcement! It has a link: /).should(
|
||||
'be.visible',
|
||||
);
|
||||
cy.findByText(
|
||||
/. It's a really long announcement, because we have a lot to say. Be sure to read it all, click the link, then dismiss the banner, and then you can go on to the next test, which will have a shorter announcement. Thank you for reading and have a nice day!/,
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
// # Move mouse out of banner area
|
||||
cy.get('@announcementBanner').trigger('mouseout');
|
||||
|
||||
// * Verify the popover is no more visible
|
||||
cy.get('@announcementBannerTooltip').should('not.exist');
|
||||
|
||||
// # Close the banner
|
||||
cy.get('.announcement-bar__close').should('be.visible').click();
|
||||
|
||||
// * Verify the banner is closed
|
||||
cy.get('@announcementBanner').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,368 @@
|
||||
// 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 @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Customization', () => {
|
||||
beforeEach(() => {
|
||||
// # as many of the tests logout the user, ensure it's logged
|
||||
// in as an admin before each test
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Customization');
|
||||
});
|
||||
|
||||
it('MM-T1024 - Can change name and desc with Custom Branding set to false', () => {
|
||||
// # Make sure necessary field is false
|
||||
cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: false}});
|
||||
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.findByTestId('TeamSettings.SiteNamelabel').scrollIntoView().should('be.visible').and('have.text', 'Site Name:');
|
||||
|
||||
// # Update both Site Name and Description to store test values
|
||||
const siteName = 'Mattermost_Text';
|
||||
const siteDescription = 'This is a testing Mattermost site';
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName);
|
||||
cy.findByTestId('TeamSettings.CustomDescriptionTextinput').clear().type(siteDescription);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Ensure Site Name and Description are shown the updated values in the login screen
|
||||
cy.findByRole('link', {name: siteName}).should('be.visible');
|
||||
cy.get('.login-body-card-title').should('have.text', siteDescription);
|
||||
});
|
||||
|
||||
it('MM-T1025 - Site Name - Product Menu ➜ About and About Modal show custom name', () => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.findByTestId('TeamSettings.SiteNamelabel').scrollIntoView().should('be.visible').and('have.text', 'Site Name:');
|
||||
|
||||
// # Update Site Name test value
|
||||
const siteName = "A team's instance";
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Exit settings
|
||||
cy.visit('/');
|
||||
|
||||
// # Open About Mattermost menu option
|
||||
cy.uiOpenProductMenu(`About ${siteName}`);
|
||||
|
||||
// * Verify in the about modal that the new site name is being shown
|
||||
cy.get('#aboutModalLabel').should('be.visible').and('have.text', `About ${siteName}`);
|
||||
});
|
||||
|
||||
it('MM-T1026 - Custom Branding - Name character limit', () => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.findByTestId('TeamSettings.SiteNamelabel').scrollIntoView().should('be.visible').and('have.text', 'Site Name:');
|
||||
|
||||
// Character limit is 30, and Mattermost is exactly 10 characters long
|
||||
const siteName = 'Mattermost'.repeat(3);
|
||||
|
||||
// # Type the maximum amount of characters and then some more
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName + 'something else');
|
||||
|
||||
// * Verify that the input field didn't accept more characters than the limit
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').should('have.value', siteName);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the value was saved correctly, without the extra characters
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.TeamSettings.SiteName).to.equal(siteName);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1027 - Custom branding is enabled but no image has been uploaded', () => {
|
||||
// # Ensure that the brand image is deleted
|
||||
cy.apiDeleteBrandImage();
|
||||
cy.reload();
|
||||
|
||||
// # Set Enable Custom Branding to true
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrandtrue').check();
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout from the current user
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Ensure that the signup is loaded and the img doesn't exist
|
||||
cy.get('.login-body-custom-branding-image').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1028 - Custom brand image and text - true, and uploaded / updated', () => {
|
||||
// # Make sure necessary field is false
|
||||
cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: false}});
|
||||
|
||||
// # Ensure that the brand image is deleted
|
||||
cy.apiDeleteBrandImage();
|
||||
cy.reload();
|
||||
|
||||
// # Enable custom branding
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrandtrue').check();
|
||||
|
||||
// # Upload the image
|
||||
cy.findByTestId('CustomBrandImage').should('be.visible').within(() => {
|
||||
cy.get('input').attachFile('mattermost-icon.png');
|
||||
});
|
||||
|
||||
// * Verify that custom brand image setting is visible and matches text content
|
||||
cy.findByTestId('TeamSettings.CustomBrandTextlabel').scrollIntoView().should('be.visible').and('have.text', 'Custom Brand Text:');
|
||||
|
||||
// # Update custom brand text
|
||||
const customBrandText = 'This is a custom brand text';
|
||||
cy.findByTestId('TeamSettings.CustomBrandTextinput').clear().type(customBrandText);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout from the current user
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Verify that the image is visible
|
||||
cy.get('.login-body-custom-branding-image').should('exist').and('be.visible');
|
||||
|
||||
cy.get('.login-body-custom-branding-markdown').first().within(() => {
|
||||
// * Ensure that the custom brand text has been updated
|
||||
cy.get('p').should('have.text', customBrandText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1029 - Custom branding text can render markdown text', () => {
|
||||
// # Visit emoji system console page
|
||||
cy.visit('/admin_console/site_config/emoji');
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Emoji');
|
||||
|
||||
// # Set Enable Custom Emoji to true
|
||||
cy.findByTestId('ServiceSettings.EnableCustomEmojitrue').check();
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Visit the add custom emoji page for ad-1
|
||||
cy.visit('/ad-1/emoji/add');
|
||||
cy.get('.backstage-header').should('be.visible');
|
||||
|
||||
// * Ensure the form is visible
|
||||
cy.get('.backstage-form').should('be.visible').within(() => {
|
||||
// # Fill the emoji data
|
||||
cy.get('input#name').clear().type('yay');
|
||||
cy.get('input#select-emoji').attachFile('mattermost-icon.png');
|
||||
|
||||
// # Save emoji
|
||||
cy.get('.backstage-form__footer button').click();
|
||||
});
|
||||
|
||||
// # Make sure necessary field is true
|
||||
cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: true}});
|
||||
cy.reload();
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Customization');
|
||||
|
||||
// eslint-disable-next-line no-irregular-whitespace
|
||||
const customBrandText = `:yay:
|
||||
:smile:
|
||||
|
||||
- This is a bullet point
|
||||
- This is another bullet point
|
||||
|
||||
**This has been bolded**
|
||||
~~This has been strikethrough~~
|
||||
*This has been italicized*
|
||||
[This is a link to mattermost.com](https://mattermost.com)
|
||||
` + '`This is inline code`'; // eslint-disable-line no-useless-concat
|
||||
|
||||
// # Update custom brand text
|
||||
cy.findByTestId('TeamSettings.CustomBrandTextinput').clear().type(customBrandText);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('.login-body-custom-branding-markdown').first().scrollIntoView().should('be.visible').within(() => {
|
||||
// * Ensure custom emoji has been rendered
|
||||
// ToDo: uncomment after fixing MM-12657
|
||||
//cy.get('span.emoticon').should('have.attr', 'title', ':yay:');
|
||||
|
||||
// * Ensure default emoji has been rendered
|
||||
cy.get('span.emoticon').should('have.attr', 'title', ':smile:');
|
||||
|
||||
// * Ensure the list and two bullets have been rendered
|
||||
cy.get('ul.markdown__list').should('be.visible').within(() => {
|
||||
cy.contains('This is a bullet point');
|
||||
cy.contains('This is another bullet point');
|
||||
});
|
||||
|
||||
// * Find within the paragraph after the list
|
||||
cy.get('ul+p').should('be.visible').within(() => {
|
||||
// * Ensure the bold text has been rendered
|
||||
cy.get('strong').should('be.visible').and('have.text', 'This has been bolded');
|
||||
|
||||
// * Ensure the strikethrough text has been rendered
|
||||
cy.get('del').should('be.visible').and('have.text', 'This has been strikethrough');
|
||||
|
||||
// * Ensure the italic text has been rendered
|
||||
cy.get('em').should('be.visible').and('have.text', 'This has been italicized');
|
||||
|
||||
// * Ensure the link has been rendered
|
||||
cy.get('a.markdown__link').should('be.visible').and('have.text', 'This is a link to mattermost.com').and('have.attr', 'href', 'https://mattermost.com');
|
||||
|
||||
// * Ensure the inline code has been rendered
|
||||
cy.get('.codespan__pre-wrap').should('be.visible').and('have.text', 'This is inline code');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1030 - Custom branding removed - Default site name and description, and brand image and text - false', () => {
|
||||
// # Make sure necessary field is true
|
||||
cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: true}});
|
||||
cy.reload();
|
||||
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.findByTestId('TeamSettings.SiteNamelabel').scrollIntoView().should('be.visible').and('have.text', 'Site Name:');
|
||||
|
||||
// # Update both Site Name and Description to store default or empty values
|
||||
const siteName = 'Mattermost';
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName);
|
||||
cy.findByTestId('TeamSettings.CustomDescriptionTextinput').clear();
|
||||
|
||||
// # Remove the brand image
|
||||
cy.get('button.remove-image__btn').should('be.visible').click();
|
||||
|
||||
// # Set Enable Custom Branding to false
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrandfalse').check();
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Ensure that the default Site Name is shown in the login screen
|
||||
cy.get('.header-logo-link svg').should('be.visible');
|
||||
|
||||
// * Ensure Description have the default values
|
||||
cy.findByText('Collaborate with your team in real-time').should('exist').and('be.visible');
|
||||
|
||||
// * Ensure that the custom branding img is not visible
|
||||
cy.get('.login-body-custom-branding-image').should('not.exist');
|
||||
|
||||
// * Ensure that the custom branding text is not visible
|
||||
cy.get('.login-body-custom-branding-markdown').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1282 - Site Name help text matches text field behavior', () => {
|
||||
// * Verify that the existing Site Name is empty
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').should('be.empty');
|
||||
|
||||
// # Configure a custom Site Name
|
||||
const siteName = 'MM-T1282';
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Ensure that the custom Site Name is shown
|
||||
cy.findByRole('link', {name: siteName}).should('be.visible');
|
||||
|
||||
// # Log back in as an administrator
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
|
||||
// * Ensure that the 'about' link and modal render the custom Site Name
|
||||
verifySiteNameInAboutModal(siteName);
|
||||
|
||||
// # Empty the Site Name configuration
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear();
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Ensure that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Ensure that the default Site Name is shown in the login screen
|
||||
cy.get('.header-logo-link svg').should('be.visible');
|
||||
|
||||
// # Log back in as an administrator
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
|
||||
// * Ensure that the 'about' link and modal render the default Site Name
|
||||
verifySiteNameInAboutModal('Mattermost');
|
||||
});
|
||||
});
|
||||
|
||||
function saveSetting() {
|
||||
// # Click save button, and verify text and visibility
|
||||
cy.get('#saveSetting').
|
||||
should('have.text', 'Save').
|
||||
and('be.enabled').
|
||||
click().
|
||||
should('be.disabled').
|
||||
wait(TIMEOUTS.HALF_SEC);
|
||||
}
|
||||
|
||||
function verifySiteNameInAboutModal(siteName) {
|
||||
// # Open the hamburger menu
|
||||
cy.get('button > span[class="menu-icon"]').click();
|
||||
|
||||
// # Click to open about modal
|
||||
cy.findByText(`About ${siteName}`).click();
|
||||
|
||||
// * Verify about text is visible
|
||||
cy.findByText(`About ${siteName}`).should('be.visible');
|
||||
|
||||
// # Close the modal
|
||||
cy.get('div.modal-header button.close').should('exist').click();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
export function saveSetting() {
|
||||
// # Click save button, and verify text and visibility
|
||||
cy.get('#saveSetting').
|
||||
should('have.text', 'Save').
|
||||
and('be.enabled').
|
||||
click().
|
||||
should('be.disabled').
|
||||
wait(TIMEOUTS.HALF_SEC);
|
||||
}
|
||||
|
||||
export function backToTeam() {
|
||||
cy.get('.backstage-navbar__back').click();
|
||||
}
|
||||
@@ -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 @system_console @enterprise @cloud_only
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import {SupportSettings} from '../../../../utils/constants';
|
||||
|
||||
describe('SupportSettings', () => {
|
||||
before(() => {
|
||||
// * Check if server has license for Cloud
|
||||
cy.apiRequireLicenseForFeature('Cloud');
|
||||
|
||||
// # As admin, visit default team/channel
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
it('MM-T1031 - Customization Change all links', () => {
|
||||
// # Open about modal
|
||||
cy.uiOpenHelpMenu().within(() => {
|
||||
// * Verify links changed
|
||||
[
|
||||
{text: 'Ask the community', link: SupportSettings.ASK_COMMUNITY_LINK},
|
||||
{text: 'Help resources', link: SupportSettings.HELP_LINK},
|
||||
{text: 'Report a problem', link: SupportSettings.REPORT_A_PROBLEM_LINK},
|
||||
{text: 'Keyboard shortcuts'},
|
||||
].forEach(({text, link}) => {
|
||||
if (link) {
|
||||
cy.findByText(text).
|
||||
parent().
|
||||
should('have.attr', 'href', link);
|
||||
} else {
|
||||
cy.findByText(text);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// # Logout
|
||||
cy.uiLogout();
|
||||
|
||||
// * Verify that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
const guides = [
|
||||
{text: 'About', link: SupportSettings.ABOUT_LINK},
|
||||
{text: 'Privacy Policy', link: SupportSettings.PRIVACY_POLICY_LINK},
|
||||
{text: 'Terms', link: SupportSettings.TERMS_OF_SERVICE_LINK},
|
||||
{text: 'Help', link: SupportSettings.HELP_LINK},
|
||||
];
|
||||
|
||||
// * Verify that links are correct at login page
|
||||
guides.forEach((guide) => {
|
||||
cy.findByText(guide.text).
|
||||
should('have.attr', 'href', guide.link);
|
||||
});
|
||||
|
||||
// # Visit signup page
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').click();
|
||||
cy.url().should('include', '/signup_user_complete');
|
||||
|
||||
// * Verify that links are correct at signup page
|
||||
guides.forEach((guide) => {
|
||||
cy.findByText(guide.text).
|
||||
should('have.attr', 'href', guide.link);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,217 @@
|
||||
// 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 @system_console @enterprise @e20_only @not_cloud
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import {TERMS_OF_SERVICE_LINK} from '../../../../utils/constants';
|
||||
|
||||
import {backToTeam, saveSetting} from './helper';
|
||||
|
||||
describe('SupportSettings', () => {
|
||||
const tosLink = 'https://github.com/mattermost/platform/blob/master/README.md';
|
||||
const privacyLink = 'https://github.com/mattermost/platform/blob/master/README.md';
|
||||
const aboutLink = 'https://mattermost.com/default-about/';
|
||||
const helpLink = 'https://github.com/mattermost/platform/blob/master/doc/help/README.md';
|
||||
const problemLink = 'https://forum.mattermost.com/c/trouble-shoot';
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as admin and reset config
|
||||
cy.apiAdminLogin();
|
||||
cy.apiUpdateConfig();
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
});
|
||||
|
||||
it('MM-T1031 - Customization Change all links', () => {
|
||||
// # Edit links in the TOS, Privacy, About, Help, Report fields
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').clear().type(tosLink);
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').clear().type(privacyLink);
|
||||
cy.findByTestId('SupportSettings.AboutLinkinput').clear().type(aboutLink);
|
||||
cy.findByTestId('SupportSettings.HelpLinkinput').clear().type(helpLink);
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinkinput').clear().type(problemLink);
|
||||
|
||||
// # Save setting then back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// # Open about modal
|
||||
cy.uiOpenHelpMenu().within(() => {
|
||||
// * Verify links changed
|
||||
[
|
||||
{text: 'Report a problem', link: problemLink},
|
||||
{text: 'Help resources', link: helpLink},
|
||||
].forEach((guide) => {
|
||||
cy.findByText(guide.text).
|
||||
parent().
|
||||
should('have.attr', 'href', guide.link);
|
||||
});
|
||||
});
|
||||
|
||||
// # Logout
|
||||
cy.uiLogout();
|
||||
|
||||
// * Verify that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
const guides = [
|
||||
{text: 'About', link: aboutLink},
|
||||
{text: 'Privacy Policy', link: privacyLink},
|
||||
{text: 'Terms', link: tosLink},
|
||||
{text: 'Help', link: helpLink},
|
||||
];
|
||||
|
||||
// * Verify that links are correct at login page
|
||||
guides.forEach((guide) => {
|
||||
cy.findByText(guide.text).
|
||||
should('have.attr', 'href', guide.link);
|
||||
});
|
||||
|
||||
// # Visit signup page
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').click();
|
||||
cy.url().should('include', '/signup_user_complete');
|
||||
|
||||
// * Verify that links are correct at signup page
|
||||
cy.get('.hfroute-footer').scrollIntoView().should('be.visible').within(() => {
|
||||
guides.forEach((guide) => {
|
||||
cy.findByText(guide.text).
|
||||
should('have.attr', 'href', guide.link);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1033 - Customization: Blank TOS link field (login page)', () => {
|
||||
// # Empty the "terms of services" field
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').type('any').clear();
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Verify that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Verify that terms of services link is set to default
|
||||
cy.findByText('Terms').
|
||||
should('have.attr', 'href', TERMS_OF_SERVICE_LINK);
|
||||
});
|
||||
|
||||
it('MM-T1036 - Customization: Blank Help and Report a Problem hides options from help menu', () => {
|
||||
// # Change help and report links to blanks
|
||||
cy.findByTestId('SupportSettings.HelpLinkinput').type('any').clear();
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinkinput').type('any').clear();
|
||||
|
||||
// # Save setting and back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// * Verify that report link does not exist
|
||||
cy.uiOpenHelpMenu().within(() => {
|
||||
cy.get('Report a problem').should('not.exist');
|
||||
cy.get('Help resources').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1038 - Customization App download link - Change to different', () => {
|
||||
// # Edit links in the support email field
|
||||
const link = 'some_link';
|
||||
cy.findByTestId('NativeAppSettings.AppDownloadLinkinput').clear().type(link);
|
||||
|
||||
// # Save setting then back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// # Open about modal
|
||||
cy.uiOpenProductMenu().within(() => {
|
||||
// * Verify that 'Download Apps' has expected link
|
||||
cy.findByText('Download Apps').
|
||||
parent().
|
||||
should('have.attr', 'href', link);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3289_1 - Help (Ask community link setting)', () => {
|
||||
// * Verify enable ask community link to be true by default
|
||||
cy.findByTestId('SupportSettings.EnableAskCommunityLinktrue').should('be.checked');
|
||||
|
||||
// * Verify the help text
|
||||
cy.findByTestId('SupportSettings.EnableAskCommunityLinkhelp-text').should('contain', 'When true, "Ask the community" link appears on the Mattermost user interface and Help Menu, which allows users to join the Mattermost Community to ask questions and help others troubleshoot issues. When false, the link is hidden from users.');
|
||||
|
||||
// # Back to team view
|
||||
backToTeam();
|
||||
|
||||
// * Verify that hover shows "Help" text
|
||||
cy.uiGetHelpButton().
|
||||
trigger('mouseover', {force: true}).
|
||||
should('have.attr', 'aria-describedby').
|
||||
and('equal', 'userGuideHelpTooltip');
|
||||
cy.uiGetHelpButton().
|
||||
trigger('mouseout', {force: true}).
|
||||
should('not.have.attr', 'aria-describedby');
|
||||
|
||||
// # Open help menu
|
||||
cy.uiOpenHelpMenu().within(() => {
|
||||
// * Verify 4 options shown
|
||||
cy.findByText('Ask the community');
|
||||
cy.findByText('Help resources');
|
||||
cy.findByText('Report a problem');
|
||||
cy.findByText('Keyboard shortcuts');
|
||||
|
||||
// * Verify default link of Ask the community
|
||||
cy.findByText('Ask the community').
|
||||
parent().
|
||||
should('have.attr', 'href', 'https://mattermost.com/pl/default-ask-mattermost-community/');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T3289_2 - Help (Ask community link setting)', () => {
|
||||
// Disable setting for ask community
|
||||
cy.findByTestId('SupportSettings.EnableAskCommunityLinkfalse').click();
|
||||
|
||||
// Edit help link and report a problem link
|
||||
cy.findByTestId('SupportSettings.HelpLinkinput').clear().type(helpLink);
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinkinput').clear().type(problemLink);
|
||||
|
||||
// # Save setting and back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// # Open help menu
|
||||
cy.uiOpenHelpMenu().within(() => {
|
||||
// * Verify 3 options shown
|
||||
cy.findByText('Help resources');
|
||||
cy.findByText('Report a problem');
|
||||
cy.findByText('Keyboard shortcuts');
|
||||
|
||||
// * Verify help link has changed
|
||||
cy.findByText('Help resources').
|
||||
parent().
|
||||
should('have.attr', 'href', helpLink);
|
||||
|
||||
// * Verify report a problem link has changed
|
||||
cy.findByText('Report a problem').
|
||||
parent().
|
||||
should('have.attr', 'href', problemLink);
|
||||
|
||||
// # Click on keyboard shortcuts
|
||||
cy.findByText('Keyboard shortcuts').click();
|
||||
});
|
||||
|
||||
// * Verify link opens keyboard shortcuts modal
|
||||
cy.findAllByRole('dialog', 'Keyboard shortcuts');
|
||||
});
|
||||
});
|
||||
@@ -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 @not_cloud @system_console
|
||||
|
||||
import {
|
||||
FixedPublicLinks,
|
||||
} from '../../../../utils';
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
import {backToTeam, saveSetting} from './helper';
|
||||
|
||||
describe('SupportSettings', () => {
|
||||
const tosLink = 'https://github.com/mattermost/platform/blob/master/README.md';
|
||||
const privacyLink = 'https://github.com/mattermost/platform/blob/master/README.md';
|
||||
|
||||
let siteName;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
siteName = config.TeamSettings.SiteName;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiUpdateConfig();
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
});
|
||||
|
||||
it('MM-T1032 - Customization: Custom Terms and Privacy links in the About modal', () => {
|
||||
// # Edit links in the TOS and Privacy fields
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').clear().type(tosLink);
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').clear().type(privacyLink);
|
||||
|
||||
// # Save setting then back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// # Open about modal
|
||||
cy.uiOpenProductMenu(`About ${siteName}`);
|
||||
|
||||
// * Verify that links do not change and they open to default pages
|
||||
cy.get('#tosLink').should('contain', 'Terms of Use').and('have.attr', 'href').and('equal', FixedPublicLinks.TermsOfService);
|
||||
cy.get('#privacyLink').should('contain', 'Privacy Policy').and('have.attr', 'href').and('equal', FixedPublicLinks.PrivacyPolicy);
|
||||
});
|
||||
|
||||
it('MM-T1034 - Customization: Blank TOS link field (About modal)', () => {
|
||||
// # Empty the "terms of services" field
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').type('any').clear();
|
||||
|
||||
// # Save setting then back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// # Open about modal
|
||||
cy.uiOpenProductMenu(`About ${siteName}`);
|
||||
|
||||
// * Verify that tos link is set to default
|
||||
cy.get('#tosLink').should('contain', 'Terms of Use').and('have.attr', 'href').and('equal', FixedPublicLinks.TermsOfService);
|
||||
});
|
||||
|
||||
it('MM-T1035 - Customization Blank Privacy hides the link', () => {
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').clear();
|
||||
|
||||
// # Save setting then back to team view
|
||||
saveSetting();
|
||||
backToTeam();
|
||||
|
||||
// # Open about modal
|
||||
cy.uiOpenProductMenu(`About ${siteName}`);
|
||||
|
||||
// * Verify that tos link is there
|
||||
cy.get('#tosLink').should('be.visible').and('contain', 'Terms of Use');
|
||||
|
||||
// * Verify that privacy link is there
|
||||
cy.get('#privacyLink').should('contain', 'Privacy Policy').and('have.attr', 'href').and('equal', FixedPublicLinks.PrivacyPolicy);
|
||||
|
||||
// # Logout
|
||||
cy.apiLogout();
|
||||
|
||||
// * Verify that the user was redirected to the login page after the logout
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
// * Verify no privacy link
|
||||
cy.findByText('Privacy Policy').should('not.exist');
|
||||
|
||||
// # Visit signup page
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').click();
|
||||
|
||||
// * Verify no privacy link
|
||||
cy.get('.hfroute-footer').scrollIntoView().should('be.visible').within(() => {
|
||||
cy.findByText('Privacy Policy').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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 @not_cloud @system_console
|
||||
|
||||
describe('Site URL', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
});
|
||||
|
||||
it('MM-T3279 - Don\'t allow clearing site URL in System Console', () => {
|
||||
// # Navigate to System Console -> Environment -> Web Server
|
||||
cy.visit('/admin_console/environment/web_server');
|
||||
|
||||
// # Note the site URL value
|
||||
cy.findByTestId('ServiceSettings.SiteURLinput').invoke('val').then((originalSiteURLValue) => {
|
||||
// # Clear the Site URL
|
||||
cy.findByTestId('ServiceSettings.SiteURLinput').clear();
|
||||
|
||||
// # Save
|
||||
cy.findAllByTestId('saveSetting').click();
|
||||
cy.waitUntil(() => cy.findAllByTestId('saveSetting').then((el) => {
|
||||
return el[0].innerText === 'Save';
|
||||
}));
|
||||
|
||||
// * Check that the error message is present
|
||||
cy.findByTestId('errorMessage').contains('Site URL cannot be cleared.');
|
||||
|
||||
// # Reload the page
|
||||
cy.visit('/admin_console/environment/web_server');
|
||||
|
||||
// * Check that the setting is the original value
|
||||
cy.findByTestId('ServiceSettings.SiteURLinput').should('have.value', originalSiteURLValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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 @system_console @te_only
|
||||
|
||||
describe('Support Packet Generation', () => {
|
||||
it('MM-T3817 - Commercial Support Dialog UI - No License', () => {
|
||||
// # Remove license
|
||||
cy.apiAdminLogin();
|
||||
cy.apiDeleteLicense();
|
||||
|
||||
// # Go to System Console
|
||||
cy.visit('/admin_console');
|
||||
|
||||
cy.findByRole('button', {name: 'Menu Icon'}).should('exist').click();
|
||||
|
||||
// * Make sure the commercial support button takes you to external link
|
||||
cy.findByRole('link', {name: 'Commercial Support'}).and('have.attr', 'href').and('include', '/commercial-support/');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,222 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
describe('System Console > Site Statistics > True Up Review', () => {
|
||||
before(() => {
|
||||
cy.apiInitSetup();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const originalConfig = config;
|
||||
const newConfig = {
|
||||
...originalConfig,
|
||||
LogSettings: {
|
||||
...originalConfig.LogSettings,
|
||||
EnableDiagnostics: false,
|
||||
},
|
||||
};
|
||||
|
||||
cy.apiUpdateConfig(newConfig);
|
||||
});
|
||||
});
|
||||
|
||||
it('cloud instances should not see true up review sections', () => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense('cloud');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
|
||||
it('starter instances should not see true up review sections', () => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense('starter');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
|
||||
it('non-admin users do no see the true up review sections', () => {
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
|
||||
it('true up review exists in each statistics section', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
const dueDate = moment().add(1, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: false, due_date: dueDate}}).as('reviewStatus');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('exist');
|
||||
});
|
||||
|
||||
it('non air-gapped instances can submit a true up review request', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
const dueDate = moment().add(1, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: false, due_date: dueDate}}).as('reviewStatus');
|
||||
cy.intercept('POST', '**/api/v4/license/review', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('exist');
|
||||
|
||||
cy.findByText('Share to Mattermost').should('exist').click();
|
||||
|
||||
cy.wait('@reviewRequest');
|
||||
|
||||
cy.findByText('Success!').should('exist');
|
||||
});
|
||||
|
||||
it('air-gapped instances can submit a true up review request (for bundle download)', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
const dueDate = moment().add(1, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('POST', '**/api/v4/license/review', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: false, due_date: dueDate}}).as('reviewStatus');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('exist');
|
||||
|
||||
cy.findByText('Share to Mattermost').should('exist').click();
|
||||
|
||||
cy.wait('@reviewRequest');
|
||||
|
||||
cy.findByText('Success!').should('exist');
|
||||
});
|
||||
|
||||
it('error state visible when review request fails', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
const dueDate = moment().add(1, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: false, due_date: dueDate}}).as('reviewStatus');
|
||||
cy.intercept('POST', '**/api/v4/license/review', {statusCode: 500}).as('reviewRequest');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('exist');
|
||||
|
||||
cy.findByText('Share to Mattermost').should('exist').click();
|
||||
|
||||
cy.wait('@reviewRequest');
|
||||
|
||||
cy.findByText('There was an issue sending your True Up Review. Please try again.').should('exist');
|
||||
});
|
||||
|
||||
it('panel should not be present if true up review is already complete', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
const dueDate = moment().add(1, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: true, due_date: dueDate}}).as('reviewStatus');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
|
||||
it('panel should not be present if current date is not within the due date window', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
const dueDate = moment().add(20, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: true, due_date: dueDate}}).as('reviewStatus');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
|
||||
it('panel should not be present if current date is not within the due date window', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
const dueDate = moment().add(20, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: true, due_date: dueDate}}).as('reviewStatus');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
|
||||
it('panel should not be present if telemetry is enabled', () => {
|
||||
// # Log in as admin
|
||||
cy.apiAdminLogin();
|
||||
cy.apiRequireLicense();
|
||||
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const originalConfig = config;
|
||||
const newConfig = {
|
||||
...originalConfig,
|
||||
LogSettings: {
|
||||
...originalConfig.LogSettings,
|
||||
EnableDiagnostics: true,
|
||||
},
|
||||
};
|
||||
|
||||
cy.apiUpdateConfig(newConfig);
|
||||
});
|
||||
|
||||
const dueDate = moment().add(1, 'day').unix();
|
||||
cy.intercept('GET', '**/api/v4/hosted_customer/signup_available', {statusCode: 200, body: {status: 'OK'}}).as('reviewRequest');
|
||||
cy.intercept('GET', '**/api/v4/license/review/status', {statusCode: 200, body: {complete: true, due_date: dueDate}}).as('reviewStatus');
|
||||
|
||||
// # Go to team statistics
|
||||
cy.visit('/admin_console/reporting/team_statistics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
|
||||
// # Go to site statistics
|
||||
cy.visit('/admin_console/reporting/system_analytics');
|
||||
cy.findByText('True Up Review').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
// 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 @customization
|
||||
|
||||
describe('Customization', () => {
|
||||
it('MM-T5379 - Should match title and custom description in root html', () => {
|
||||
const defaultTitle = 'Mattermost';
|
||||
const defaultDescription = 'Log in';
|
||||
const customTitle = 'Custom site name';
|
||||
const customDescription = 'Custom description';
|
||||
|
||||
// # Log out and visit login page
|
||||
cy.apiLogout();
|
||||
cy.visit('/login');
|
||||
|
||||
// * Verify that the head tag contains default title and without og:description
|
||||
cy.get('head').find('title').should('have.text', defaultTitle);
|
||||
cy.get('head').get('meta[property="og:description"]').should('not.exist');
|
||||
|
||||
// * Verify that the header contains default logo/image
|
||||
cy.get('.header-logo-link').should('have.text', '').and('have.attr', 'href', '/').find('svg').should('be.visible');
|
||||
|
||||
// * Verify that login card contains default description
|
||||
cy.get('.login-body-card-title').should('be.visible').and('have.text', defaultDescription);
|
||||
|
||||
// # Update the site name and custom description
|
||||
cy.apiAdminLogin();
|
||||
cy.apiUpdateConfig({TeamSettings: {SiteName: customTitle, CustomDescriptionText: customDescription}});
|
||||
|
||||
// # Log out and visit login page
|
||||
cy.apiLogout();
|
||||
cy.visit('');
|
||||
|
||||
// * Verify that the head tag contains custom title and description
|
||||
cy.get('head').find('title').should('have.text', customTitle);
|
||||
cy.get('head').get('meta[property="og:description"]').should('have.attr', 'content', customDescription);
|
||||
|
||||
// * Verify that the header contains custom title
|
||||
cy.get('.header-logo-link').should('have.text', customTitle).and('have.attr', 'href', '/');
|
||||
|
||||
// * Verify that login card contains custom description
|
||||
cy.get('.login-body-card-title').should('be.visible').and('have.text', customDescription);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,242 @@
|
||||
// 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 @not_cloud @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Customization', () => {
|
||||
let origConfig;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// Get config
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
origConfig = config;
|
||||
});
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Customization');
|
||||
});
|
||||
|
||||
it('MM-T1214 - Can change Report a Problem Link setting', () => {
|
||||
// * Verify Report a Problem link label is visible and matches the text
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Report a Problem Link:');
|
||||
|
||||
// * Verify Report a Problem link input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinkinput').should('have.value', origConfig.SupportSettings.ReportAProblemLink);
|
||||
|
||||
// * Verify Report a Problem link help text is visible and matches the text
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinkhelp-text').find('span').should('be.visible').and('have.text', 'The URL for the Report a Problem link in the Help Menu. If this field is empty, the link is removed from the Help Menu.');
|
||||
|
||||
// # Enter a problem link
|
||||
const reportAProblemLink = 'https://mattermost.com/default-report-a-problem/';
|
||||
cy.findByTestId('SupportSettings.ReportAProblemLinkinput').clear().type(reportAProblemLink);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the Report a Problem link is saved, directly via REST API
|
||||
expect(config.SupportSettings.ReportAProblemLink).to.eq(reportAProblemLink);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1212 - Can change Privacy Policy Link setting', () => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Privacy Policy Link:');
|
||||
|
||||
// * Verify that help setting is visible and matches text content
|
||||
const content = 'The URL for the Privacy link on the login and sign-up pages. If this field is empty, the Privacy link is hidden from users.';
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinkhelp-text').scrollIntoView().find('span').should('be.visible').and('have.text', content);
|
||||
|
||||
// * Verify the input box visible and has default value
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').scrollIntoView().should('have.value', origConfig.SupportSettings.PrivacyPolicyLink).and('be.visible');
|
||||
|
||||
// # Fill input field with value
|
||||
const stringToSave = 'https://some.com';
|
||||
cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').clear().type(stringToSave);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the value is save, directly via REST API
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.SupportSettings.PrivacyPolicyLink).to.equal(stringToSave);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1216 Can change Android App Download Link setting', () => {
|
||||
// # Scroll Android App Download Link section into view and verify that it's visible
|
||||
cy.findByTestId('NativeAppSettings.AndroidAppDownloadLink').scrollIntoView().should('be.visible');
|
||||
|
||||
// * Verify that Android App Download Link label is visible and matches text content
|
||||
cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinklabel').should('be.visible').and('have.text', 'Android App Download Link:');
|
||||
|
||||
// * Verify the Android App Download Link input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinkinput').should('have.value', origConfig.NativeAppSettings.AndroidAppDownloadLink);
|
||||
|
||||
// * Verify that the help text is visible and matches text content
|
||||
cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinkhelp-text').find('span').should('be.visible').and('have.text', 'Add a link to download the Android app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.');
|
||||
|
||||
const newAndroidAppDownloadLink = 'https://example.com/android-app/';
|
||||
|
||||
// * Verify that set value is visible and matches text
|
||||
cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinkinput').clear().type(newAndroidAppDownloadLink).should('have.value', newAndroidAppDownloadLink);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the config is correctly saved in the server
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.NativeAppSettings.AndroidAppDownloadLink).to.equal(newAndroidAppDownloadLink);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1217 Can change iOS App Download Link setting', () => {
|
||||
// # Scroll iOS App Download Link section into view and verify that it's visible
|
||||
cy.findByTestId('NativeAppSettings.IosAppDownloadLink').scrollIntoView().should('be.visible');
|
||||
|
||||
// * Verify that iOS App Download Link label is visible and matches text content
|
||||
cy.findByTestId('NativeAppSettings.IosAppDownloadLinklabel').should('be.visible').and('have.text', 'iOS App Download Link:');
|
||||
|
||||
// * Verify the iOS App Download Link input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('NativeAppSettings.IosAppDownloadLinkinput').should('have.value', origConfig.NativeAppSettings.IosAppDownloadLink);
|
||||
|
||||
// * Verify that the help text is visible and matches text content
|
||||
cy.findByTestId('NativeAppSettings.IosAppDownloadLinkhelp-text').find('span').should('be.visible').and('have.text', 'Add a link to download the iOS app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.');
|
||||
|
||||
const newIosAppDownloadLink = 'https://example.com/iOS-app/';
|
||||
|
||||
// * Verify that set value is visible and matches text
|
||||
cy.findByTestId('NativeAppSettings.IosAppDownloadLinkinput').clear().type(newIosAppDownloadLink).should('have.value', newIosAppDownloadLink);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the config is correctly saved in the server
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.NativeAppSettings.IosAppDownloadLink).to.equal(newIosAppDownloadLink);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1215 - Can change Mattermost Apps Download Page Link setting', () => {
|
||||
// * Verify Mattermost Apps Download Page Link's setting name is visible and matches the text
|
||||
cy.findByTestId('NativeAppSettings.AppDownloadLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Mattermost Apps Download Page Link:');
|
||||
|
||||
// * Verify the Mattermost Apps Download Page Link input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('NativeAppSettings.AppDownloadLinkinput').should('have.value', origConfig.NativeAppSettings.AppDownloadLink);
|
||||
|
||||
// * Verify the site name's help text is visible and matches the text
|
||||
cy.findByTestId('NativeAppSettings.AppDownloadLinkhelp-text').find('span').should('be.visible').and('have.text', 'Add a link to a download page for the Mattermost apps. When a link is present, an option to "Download Mattermost Apps" will be added in the Product Menu so users can find the download page. Leave this field blank to hide the option from the Product Menu.');
|
||||
|
||||
// # Enter new App download link
|
||||
const newAppDownloadLink = 'https://example.com/app-download-link/';
|
||||
cy.findByTestId('NativeAppSettings.AppDownloadLinkinput').clear().type(newAppDownloadLink);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the App download link is saved, directly via REST API
|
||||
expect(config.NativeAppSettings.AppDownloadLink).to.eq(newAppDownloadLink);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1209 - Can change Help Link setting', () => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
const contents = ['The URL for the Help link on the Mattermost login page, sign-up pages, and Help Menu. If this field is empty, the Help link is hidden from users.'];
|
||||
cy.findByTestId('SupportSettings.HelpLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Help Link:');
|
||||
|
||||
// * Verify that help setting is visible and matches text content
|
||||
cy.findByTestId('SupportSettings.HelpLinkhelp-text').scrollIntoView().find('span').should('be.visible').and('have.text', contents[0]);
|
||||
|
||||
// * Verify the input box visible and has default value
|
||||
cy.findByTestId('SupportSettings.HelpLinkinput').scrollIntoView().should('have.value', origConfig.SupportSettings.HelpLink).and('be.visible');
|
||||
|
||||
// # Fill input field with value
|
||||
const stringToSave = 'https://some.com';
|
||||
cy.findByTestId('SupportSettings.HelpLinkinput').clear().type(stringToSave);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the value is save, directly via REST API
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.SupportSettings.HelpLink).to.equal(stringToSave);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1213 Can change About Link setting', () => {
|
||||
const newAboutLink = 'https://mattermost.com/';
|
||||
|
||||
// * Verify that setting is visible and has the correct label text
|
||||
cy.findByTestId('SupportSettings.AboutLinklabel').scrollIntoView().should('be.visible').and('have.text', 'About Link:');
|
||||
|
||||
// * Verify that the help text is visible and matches text content
|
||||
cy.findByTestId('SupportSettings.AboutLinkhelp-text').should('be.visible').and('have.text', 'The URL for the About link on the Mattermost login and sign-up pages. If this field is empty, the About link is hidden from users.');
|
||||
|
||||
// * Verify that the existing is visible and has default value
|
||||
cy.findByTestId('SupportSettings.AboutLinkinput').should('be.visible').and('have.value', origConfig.SupportSettings.AboutLink);
|
||||
|
||||
// # Clear existing about link and type the new about link
|
||||
cy.findByTestId('SupportSettings.AboutLinkinput').clear().type(newAboutLink);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.SupportSettings.AboutLink).to.equal(newAboutLink);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1211 - Can change Terms of Use Link setting', () => {
|
||||
// * Verify site name's setting name for is visible and matches the text
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Terms of Use Link:');
|
||||
|
||||
// * Verify the site name input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').should('have.value', origConfig.SupportSettings.TermsOfServiceLink);
|
||||
|
||||
// * Verify the site name's help text is visible and matches the text
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkhelp-text').find('span').should('be.visible').and('have.text',
|
||||
'Link to the terms under which users may use your online service. By default, this includes the ' +
|
||||
'"Mattermost Acceptable Use Policy" explaining the terms under which Mattermost software is ' +
|
||||
'provided to end users. If you change the default link to add your own terms for using the service you ' +
|
||||
'provide, your new terms must include a link to the default terms so end users are aware of the Mattermost ' +
|
||||
'Acceptable Use Policy for Mattermost software.');
|
||||
|
||||
// # Enter a new help link
|
||||
const newValue = 'https://test.com';
|
||||
cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').clear().type(newValue);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the site name is saved, directly via REST API
|
||||
expect(config.SupportSettings.TermsOfServiceLink).to.eq(newValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function saveSetting() {
|
||||
// # Click save button, and verify text and visibility
|
||||
cy.get('#saveSetting').
|
||||
should('have.text', 'Save').
|
||||
and('be.enabled').
|
||||
click().
|
||||
should('be.disabled').
|
||||
wait(TIMEOUTS.HALF_SEC);
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
// 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 @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('Customization', () => {
|
||||
let origConfig;
|
||||
|
||||
before(() => {
|
||||
// Get config
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
origConfig = config;
|
||||
});
|
||||
|
||||
// # Visit customization system console page
|
||||
cy.visit('/admin_console/site_config/customization');
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Customization');
|
||||
});
|
||||
|
||||
it('MM-T1207 - Can change Custom Brand Image setting', () => {
|
||||
// # Make sure necessary field is false
|
||||
cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: false}});
|
||||
cy.reload();
|
||||
|
||||
// # Set Enable Custom Branding to true to be able to upload custom brand image
|
||||
cy.get('[id="TeamSettings.EnableCustomBrandtrue"]').check();
|
||||
|
||||
cy.findByTestId('CustomBrandImage').should('be.visible').within(() => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.get('label').should('be.visible').and('have.text', 'Custom Brand Image:');
|
||||
|
||||
// * Verify that help setting is visible and matches text content
|
||||
const contents = 'Customize your user experience by adding a custom image to your login screen. Recommended maximum image size is less than 2 MB.';
|
||||
cy.get('.help-text').should('be.visible').and('have.text', contents);
|
||||
|
||||
// # upload the image
|
||||
cy.get('input').attachFile('mattermost-icon.png');
|
||||
});
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// # Verify that after page reload image exist
|
||||
cy.reload();
|
||||
cy.findByTestId('CustomBrandImage').should('be.visible').within(() => {
|
||||
cy.get('img').should('have.attr', 'src').and('include', '/api/v4/brand/image?t=');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1204 - Can change Site Name setting', () => {
|
||||
// * Verify site name's setting name for is visible and matches the text
|
||||
cy.findByTestId('TeamSettings.SiteNamelabel').scrollIntoView().should('be.visible').and('have.text', 'Site Name:');
|
||||
|
||||
// * Verify the site name input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').should('have.value', origConfig.TeamSettings.SiteName);
|
||||
|
||||
// * Verify the site name's help text is visible and matches the text
|
||||
cy.findByTestId('TeamSettings.SiteNamehelp-text').should('be.visible').and('have.text', 'Name of service shown in login screens and UI. When not specified, it defaults to "Mattermost".');
|
||||
|
||||
// # Generate and enter a random site name
|
||||
const siteName = 'New site name';
|
||||
cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the site name is saved, directly via REST API
|
||||
expect(config.TeamSettings.SiteName).to.eq(siteName);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1205 - Can change Site Description setting', () => {
|
||||
// * Verify site description label is visible and matches the text
|
||||
cy.findByTestId('TeamSettings.CustomDescriptionTextlabel').should('be.visible').and('have.text', 'Site Description: ');
|
||||
|
||||
// * Verify the site description input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('TeamSettings.CustomDescriptionTextinput').should('have.value', origConfig.TeamSettings.CustomDescriptionText);
|
||||
|
||||
// * Verify the site description help text is visible and matches the text
|
||||
cy.findByTestId('TeamSettings.CustomDescriptionTexthelp-text').find('span').should('be.visible').and('have.text', 'Displays as a title above the login form. When not specified, the phrase "Log in" is displayed.');
|
||||
|
||||
// # Generate and enter a random site description
|
||||
const siteDescription = 'New site description';
|
||||
cy.findByTestId('TeamSettings.CustomDescriptionTextinput').clear().type(siteDescription);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the site description is saved, directly via REST API
|
||||
expect(config.TeamSettings.CustomDescriptionText).to.eq(siteDescription);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1208 - Can change Custom Brand Text setting', () => {
|
||||
// * Verify custom brand text label is visible and matches the text
|
||||
cy.findByTestId('TeamSettings.CustomBrandTextlabel').scrollIntoView().should('be.visible').and('have.text', 'Custom Brand Text:');
|
||||
|
||||
// * Verify the custom brand input box has default value. The default value depends on the setup before running the test.
|
||||
cy.findByTestId('TeamSettings.CustomBrandTextinput').should('have.value', origConfig.TeamSettings.CustomBrandText);
|
||||
|
||||
// * Verify the custom brand help text is visible and matches the text
|
||||
cy.findByTestId('TeamSettings.CustomBrandTexthelp-text').find('span').should('be.visible').and('have.text', 'Text that will appear below your custom brand image on your login screen. Supports Markdown-formatted text. Maximum 500 characters allowed.');
|
||||
|
||||
//Enable custom branding
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrandtrue').check({force: true});
|
||||
|
||||
// # Enter a custom brand text
|
||||
const customBrandText = 'Random brand text';
|
||||
cy.findByTestId('TeamSettings.CustomBrandTextinput').clear().type(customBrandText);
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// Get config again
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
// * Verify the custom brand text is saved, directly via REST API
|
||||
expect(config.TeamSettings.CustomBrandText).to.eq(customBrandText);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1206 - Can change Enable Custom Branding setting', () => {
|
||||
// # Make sure necessary field is false
|
||||
cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: false}});
|
||||
cy.reload();
|
||||
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrand').should('be.visible').within(() => {
|
||||
// * Verify that setting is visible and matches text content
|
||||
cy.get('label:first').should('be.visible').and('have.text', 'Enable Custom Branding: ');
|
||||
|
||||
// * Verify that help setting is visible and matches text content
|
||||
const content = 'Enable custom branding to show an image of your choice, uploaded below, and some help text, written below, on the login page.';
|
||||
cy.get('.help-text').should('be.visible').and('have.text', content);
|
||||
|
||||
// # Set Enable Custom Branding to true
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrandtrue').check();
|
||||
});
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the value is save, directly via REST API
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.TeamSettings.EnableCustomBrand).to.equal(true);
|
||||
});
|
||||
|
||||
// # Set Enable Custom Branding to false
|
||||
cy.findByTestId('TeamSettings.EnableCustomBrandfalse').check();
|
||||
|
||||
// # Save setting
|
||||
saveSetting();
|
||||
|
||||
// * Verify that the value is save, directly via REST API
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.TeamSettings.EnableCustomBrand).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function saveSetting() {
|
||||
// # Click save button, and verify text and visibility
|
||||
cy.get('#saveSetting').
|
||||
should('have.text', 'Save').
|
||||
and('be.enabled').
|
||||
click().
|
||||
should('be.disabled').
|
||||
wait(TIMEOUTS.HALF_SEC);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @not_cloud @system_console
|
||||
|
||||
import {fileSizeToString} from '../../../utils';
|
||||
|
||||
describe('Unsaved Changes', () => {
|
||||
let defaultMaxFileSize;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
cy.apiGetConfig(true).then(({config}) => {
|
||||
defaultMaxFileSize = config.MaxFileSize;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T955 Warning leaving changed page without saving: Leave page, discard changes', () => {
|
||||
// # Make a change on any page.
|
||||
cy.visit('/admin_console/environment/file_storage');
|
||||
cy.findByTestId('FileSettings.MaxFileSizenumber').clear().type('150');
|
||||
|
||||
// # Click a navigation item in left nav.
|
||||
cy.findByText('Database').click();
|
||||
|
||||
// # When prompted: Yes, discard changes.
|
||||
cy.get('#confirmModal').should('be.visible');
|
||||
cy.get('#confirmModalButton').click();
|
||||
|
||||
// * Opens other page, changes discarded.
|
||||
cy.url().should('include', '/environment/database');
|
||||
cy.visit('/admin_console/environment/file_storage');
|
||||
cy.findByTestId('FileSettings.MaxFileSizenumber').should('have.value', fileSizeToString(defaultMaxFileSize).replace('MB', ''));
|
||||
});
|
||||
|
||||
it('MM-T956 Warning leaving changed page without saving: Cancel leaving page', () => {
|
||||
const draftValue = '150';
|
||||
|
||||
// # Make a change on any page.
|
||||
cy.visit('/admin_console/environment/file_storage');
|
||||
cy.findByTestId('FileSettings.MaxFileSizenumber').clear().type(draftValue);
|
||||
|
||||
// # Click a navigation item in left nav.
|
||||
cy.findByText('Database').click();
|
||||
|
||||
// # When prompted: No, cancel.
|
||||
cy.get('#confirmModal').should('be.visible');
|
||||
cy.get('#cancelModalButton').click();
|
||||
|
||||
// * Stays on current page, changes kept.
|
||||
cy.url().should('include', '/environment/file_storage');
|
||||
cy.findByTestId('FileSettings.MaxFileSizenumber').should('have.value', draftValue);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @system_console
|
||||
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
describe('System Console > User Management > Deactivation', () => {
|
||||
let team1;
|
||||
let otherAdmin;
|
||||
|
||||
before(() => {
|
||||
// # Do initial setup
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
team1 = team;
|
||||
});
|
||||
|
||||
// # Create other sysadmin
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
otherAdmin = sysadmin;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as other admin.
|
||||
cy.apiLogin(otherAdmin);
|
||||
|
||||
// # Visit town-square
|
||||
cy.visit(`/${team1.name}`);
|
||||
});
|
||||
|
||||
it('MM-T951 Reopened DM shows archived icon in LHS No status indicator in channel header Message box replaced with "You are viewing an archived channel with a deactivated user." in center and RHS - KNOWN ISSUE: MM-42529', () => {
|
||||
// # Create other user
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user}) => {
|
||||
// # Send a DM to the other user
|
||||
cy.sendDirectMessageToUser(user, MESSAGES.SMALL);
|
||||
|
||||
// # Open RHS
|
||||
cy.clickPostCommentIcon();
|
||||
|
||||
// * Verify status indicator is shown in channel header
|
||||
cy.get('#channelHeaderDescription .status').should('be.visible');
|
||||
|
||||
// # Deactivate other user
|
||||
cy.apiDeactivateUser(user.id);
|
||||
|
||||
// * Verify center channel message box is replace with warning
|
||||
cy.get('.channel-archived__message').contains('You are viewing an archived channel with a deactivated user. New messages cannot be posted.');
|
||||
|
||||
// * Verify RHS message box is replace with warning
|
||||
cy.get('#rhsContainer .post-create-message').contains('You are viewing an archived channel with a deactivated user. New messages cannot be posted.');
|
||||
|
||||
// * Verify status indicator is not shown in channel header
|
||||
cy.get('#channelHeaderDescription .status').should('not.exist');
|
||||
|
||||
// * Verify archived icon is shown in LHS
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').
|
||||
find('.active').should('be.visible').
|
||||
find('.icon-archive-outline').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
// 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 @system_console @not_cloud
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('System Console > User Management > Deactivation', () => {
|
||||
let testUser;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// # Do initial setup
|
||||
cy.apiInitSetup().then(({user}) => {
|
||||
testUser = user;
|
||||
});
|
||||
|
||||
// # Visit the system console.
|
||||
cy.visit('/admin_console');
|
||||
});
|
||||
|
||||
it('MM-T947 When deactivating users in the System Console, email address should not disappear', () => {
|
||||
// # Go to User management / Users tab
|
||||
cy.findByTestId('user_management.system_users').should('be.visible').click();
|
||||
|
||||
// # Search the newly created user in the search box
|
||||
cy.findByPlaceholderText('Search users').should('be.visible').clear().type(testUser.email).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify that user is listed
|
||||
cy.findByText(`@${testUser.username}`).should('be.visible');
|
||||
|
||||
// # Scan on the first item's row in the list
|
||||
cy.findByTestId('userListRow').should('be.visible').within(() => {
|
||||
// * Verify before deactivation email is visible
|
||||
cy.findByText(testUser.email).should('be.visible');
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.findByText('Member').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click on deactivate menu button
|
||||
cy.findByLabelText('User Actions Menu').findByText('Deactivate').click();
|
||||
});
|
||||
|
||||
// # Click confirm deactivate in the modal
|
||||
cy.get('.a11y__modal').should('exist').and('be.visible').within(() => {
|
||||
cy.findByText('Deactivate').should('be.visible').click();
|
||||
});
|
||||
|
||||
cy.findByTestId('userListRow').should('be.visible').within(() => {
|
||||
// * Verify that the user is now inactive
|
||||
cy.findByText('Inactive').should('be.visible');
|
||||
|
||||
// * Verify once again if email is visible
|
||||
cy.findByText(testUser.email).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,145 @@
|
||||
// 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 @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
describe('System Console > User Management > Deactivation', () => {
|
||||
let team1;
|
||||
let otherAdmin;
|
||||
|
||||
before(() => {
|
||||
// # Do initial setup
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
team1 = team;
|
||||
});
|
||||
|
||||
// # Create other sysadmin
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
otherAdmin = sysadmin;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as other admin.
|
||||
cy.apiLogin(otherAdmin);
|
||||
|
||||
// # Visit town-square
|
||||
cy.visit(`/${team1.name}`);
|
||||
});
|
||||
|
||||
// # Create two users
|
||||
it('MM-T946 GM: User deactivated in System Console still displays', () => {
|
||||
cy.apiCreateUser({prefix: 'first'}).then(({user: user1}) => {
|
||||
cy.apiCreateUser({prefix: 'second'}).then(({user: user2}) => {
|
||||
const message = MESSAGES.SMALL;
|
||||
|
||||
// # Send a GM to them
|
||||
cy.sendDirectMessageToUsers([user1, user2], message);
|
||||
|
||||
// * Verify names on the LHS are still ordered alphabetically
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').find('.active').should('contain', user1.username + ', ' + user2.username);
|
||||
|
||||
// # Deactivate user 1
|
||||
cy.apiDeactivateUser(user1.id);
|
||||
|
||||
// * Verify names on the LHS are still ordered alphabetically
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').find('.active').should('contain', user1.username + ', ' + user2.username);
|
||||
|
||||
// # Search for the message send in the GM
|
||||
cy.uiSearchPosts(message);
|
||||
|
||||
// * Verify GM message is returned in RHS
|
||||
cy.findAllByTestId('search-item-container').
|
||||
should('be.visible').and('have.length', 1).
|
||||
eq(0).should('contain', message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T948 DM posts searchable in DM More... and channel switcher DM channel re-openable', () => {
|
||||
cy.apiCreateUser({prefix: 'other'}).then(({user: other}) => {
|
||||
// # Open DM
|
||||
cy.sendDirectMessageToUser(other, MESSAGES.SMALL);
|
||||
|
||||
// # Close DM
|
||||
cy.get('#channelHeaderDropdownIcon').click();
|
||||
cy.findByText('Close Direct Message').click();
|
||||
|
||||
// # Deactivate the user
|
||||
cy.apiDeactivateUser(other.id);
|
||||
|
||||
// # Open Find Channels
|
||||
cy.uiOpenFindChannels();
|
||||
|
||||
// # Type the user name on Channel switcher input
|
||||
cy.get('#quickSwitchInput').type(other.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify user is marked as deactivated
|
||||
cy.get('[data-testid="' + other.username + '"]').contains('Deactivated');
|
||||
|
||||
// # Close Channel Switcher
|
||||
cy.uiClose();
|
||||
|
||||
// # Open DM Modal
|
||||
cy.uiAddDirectMessage().click().wait(TIMEOUTS.ONE_SEC);
|
||||
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Start typing part of a username that matches previously created users
|
||||
cy.findByRole('textbox', {name: 'Search for people'}).
|
||||
typeWithForce(other.username).
|
||||
wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// * Verify user is marked as deactivated
|
||||
cy.get('#displayedUserName' + other.username).parent().contains('Deactivated');
|
||||
|
||||
// # Click on the user
|
||||
cy.get('#displayedUserName' + other.username).click();
|
||||
|
||||
// * Confirm DM More... Modal is closed
|
||||
cy.get('#moreDmModal').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T949 If an active user is selected in DM More... or channel switcher, deactivated users should be shown in the DM more or channel switcher', () => {
|
||||
// # Create two users
|
||||
cy.apiCreateUser({prefix: 'first'}).then(({user: user1}) => {
|
||||
cy.apiCreateUser({prefix: 'second_'}).then(({user: user2}) => {
|
||||
// # Send a DM to user1 so they show up in the DM modal
|
||||
cy.sendDirectMessageToUser(user1, MESSAGES.SMALL);
|
||||
|
||||
// # Send a DM to user2 so they show up in the DM modal
|
||||
cy.sendDirectMessageToUser(user2, MESSAGES.SMALL);
|
||||
|
||||
// # Deactivate user 2
|
||||
cy.apiDeactivateUser(user2.id);
|
||||
|
||||
// # Open DM Modal
|
||||
cy.uiAddDirectMessage().click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type the user name of user1 on Channel switcher input
|
||||
cy.findByRole('textbox', {name: 'Search for people'}).
|
||||
typeWithForce(user1.username).
|
||||
wait(TIMEOUTS.ONE_SEC);
|
||||
|
||||
// # Click on the user
|
||||
cy.get('#displayedUserName' + user1.username).click();
|
||||
|
||||
// # Type the user name of user2 on Channel switcher input
|
||||
cy.get('.more-direct-channels #selectItems input').typeWithForce(user2.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Confirm user2 can't be added to the DM
|
||||
cy.get('#displayedUserName' + user2.username).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
// 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 @not_cloud @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
import * as MESSAGES from '../../../../fixtures/messages';
|
||||
|
||||
import {getRandomId} from '../../../../utils';
|
||||
|
||||
describe('System Console > User Management > Reactivation', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// # Do initial setup
|
||||
cy.apiInitSetup().then(({team}) => {
|
||||
// # Visit town-square
|
||||
cy.visit(`/${team.name}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T952 Reactivating a user results in them showing up in the normal spot in the list, without the `Deactivated` label.', () => {
|
||||
// # Create two users with same random prefix
|
||||
const id = getRandomId();
|
||||
|
||||
cy.apiCreateUser({prefix: id + '_a_'}).then(({user: user1}) => {
|
||||
cy.apiCreateUser({prefix: id + '_b_'}).then(({user: user2}) => {
|
||||
// # Send a DM to user1 so they show up in the DM modal
|
||||
cy.sendDirectMessageToUser(user1, MESSAGES.SMALL);
|
||||
|
||||
// # Send a DM to user2 so they show up in the DM modal
|
||||
cy.sendDirectMessageToUser(user2, MESSAGES.SMALL);
|
||||
|
||||
// # Open DM More... Modal
|
||||
cy.uiAddDirectMessage().click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type the user name of the other user on Channel switcher input
|
||||
cy.get('.more-direct-channels #selectItems input').typeWithForce(id).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify user 1 is shown first and doesn't have deactivated text
|
||||
cy.get('#moreDmModal .more-modal__row').siblings().its(0).get('#displayedUserName' + user1.username).parent().should('not.contain', 'Deactivated');
|
||||
|
||||
// * Verify user 2 is shown second
|
||||
cy.get('#moreDmModal .more-modal__row').siblings().its(1).get('#displayedUserName' + user2.username);
|
||||
|
||||
// # Deactivate user1
|
||||
cy.apiDeactivateUser(user1.id).then(() => {
|
||||
// * Verify user 1 is shown second and does have deactivated text
|
||||
cy.get('#moreDmModal .more-modal__row').siblings().its(1).get('#displayedUserName' + user1.username).parent().should('contain', 'Deactivated');
|
||||
|
||||
// * Verify user 2 is shown first
|
||||
cy.get('#moreDmModal .more-modal__row').siblings().its(0).get('#displayedUserName' + user2.username);
|
||||
|
||||
// # Reactivate user1
|
||||
cy.apiActivateUser(user1.id).then(() => {
|
||||
// * Verify user 1 is shown first and doesn't have deactivated text
|
||||
cy.get('#moreDmModal .more-modal__row').siblings().its(0).get('#displayedUserName' + user1.username).parent().should('not.contain', 'Deactivated');
|
||||
|
||||
// * Verify user 2 is shown second
|
||||
cy.get('#moreDmModal .more-modal__row').siblings().its(1).get('#displayedUserName' + user2.username);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,248 @@
|
||||
// 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 @system_console
|
||||
|
||||
import * as TIMEOUTS from '../../../../fixtures/timeouts';
|
||||
|
||||
describe('System Console > User Management > Users', () => {
|
||||
let testUser;
|
||||
let otherAdmin;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({user}) => {
|
||||
testUser = user;
|
||||
});
|
||||
|
||||
// # Create other sysadmin
|
||||
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
|
||||
otherAdmin = sysadmin;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Login as other admin.
|
||||
cy.apiLogin(otherAdmin);
|
||||
|
||||
// # Visit the system console.
|
||||
cy.visit('/admin_console');
|
||||
|
||||
// # Go to the User management/Users section.
|
||||
cy.findByTestId('user_management.system_users').
|
||||
click().
|
||||
wait(TIMEOUTS.ONE_SEC);
|
||||
});
|
||||
|
||||
it('MM-T925 Users - Profile image on User Configuration page is round', () => {
|
||||
// # Find the created user by entering in the search
|
||||
cy.findByPlaceholderText('Search users').
|
||||
should('be.visible').
|
||||
clear().
|
||||
type(testUser.email).
|
||||
wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click on the searched user name
|
||||
cy.findByText(`@${testUser.username}`).
|
||||
should('be.visible').
|
||||
click({force: true});
|
||||
|
||||
// * Verify we landed on the user configuration page
|
||||
cy.location('pathname').should(
|
||||
'equal',
|
||||
`/admin_console/user_management/user/${testUser.id}`,
|
||||
);
|
||||
|
||||
// * Verify that user profile image is round
|
||||
cy.findByAltText('user profile image').
|
||||
should('be.visible').
|
||||
and('have.css', 'border-radius', '50%');
|
||||
});
|
||||
|
||||
it('MM-T932 Users - Change a user\'s password', () => {
|
||||
// # Search for the user.
|
||||
cy.get('#searchUsers').type(testUser.email).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .text-right a').
|
||||
click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Reset Password menu option.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .MenuWrapperAnimation-enter-done').
|
||||
find('li').eq(3).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type new password and submit.
|
||||
cy.get('input[type=password]').type('new' + testUser.password);
|
||||
cy.get('button[type=submit]').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Log out.
|
||||
cy.apiLogout();
|
||||
|
||||
// * Verify that logging in with old password returns an error.
|
||||
apiLogin(testUser.username, testUser.password).then((response) => {
|
||||
expect(response.status).to.equal(401);
|
||||
|
||||
// * Verify that logging in with the updated password works.
|
||||
testUser.password = 'new' + testUser.password;
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Log out.
|
||||
cy.apiLogout();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T933 Users - System admin changes own password - Cancel out of changes', () => {
|
||||
// # Search for the admin.
|
||||
cy.get('#searchUsers').type(otherAdmin.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .text-right a').
|
||||
click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Reset Password menu option.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .MenuWrapperAnimation-enter-done').
|
||||
find('li').eq(2).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type current password and a new password.
|
||||
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
|
||||
cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password);
|
||||
|
||||
// # Click the 'Cancel' button.
|
||||
cy.get('button[type=button].btn.btn-link').should('contain', 'Cancel').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Log out.
|
||||
cy.apiLogout();
|
||||
|
||||
// * Verify that logging in with the old password works.
|
||||
cy.apiLogin(otherAdmin);
|
||||
});
|
||||
|
||||
it('MM-T934 Users - System admin changes own password - Incorrect old password', () => {
|
||||
// # Search for the admin.
|
||||
cy.get('#searchUsers').type(otherAdmin.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .text-right a').
|
||||
click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Reset Password menu option.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .MenuWrapperAnimation-enter-done').
|
||||
find('li').eq(2).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type wrong current password and a new password.
|
||||
cy.get('input[type=password]').eq(0).type('wrong' + otherAdmin.password);
|
||||
cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password);
|
||||
|
||||
// # Click the 'Reset' button.
|
||||
cy.get('button[type=submit] span').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify the appropriate error is returned.
|
||||
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').
|
||||
and('contain', 'The "Current Password" you entered is incorrect. Please check that Caps Lock is off and try again.');
|
||||
});
|
||||
|
||||
it('MM-T935 Users - System admin changes own password - Invalid new password', () => {
|
||||
// # Search for the admin.
|
||||
cy.get('#searchUsers').type(otherAdmin.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .text-right a').
|
||||
click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Reset Password menu option.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .MenuWrapperAnimation-enter-done').
|
||||
find('li').eq(2).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type current password and a new too short password.
|
||||
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
|
||||
cy.get('input[type=password]').eq(1).type('new');
|
||||
|
||||
// # Click the 'Reset' button.
|
||||
cy.get('button[type=submit] span').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify the appropriate error is returned.
|
||||
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').
|
||||
and('contain', 'Must be 5-64 characters long.');
|
||||
});
|
||||
|
||||
it('MM-T936 Users - System admin changes own password - Blank fields', () => {
|
||||
// # Search for the admin.
|
||||
cy.get('#searchUsers').type(otherAdmin.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .text-right a').
|
||||
click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Reset Password menu option.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .MenuWrapperAnimation-enter-done').
|
||||
find('li').eq(2).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the 'Reset' button.
|
||||
cy.get('button[type=submit] span').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify the appropriate error is returned.
|
||||
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').
|
||||
and('contain', 'Please enter your current password.');
|
||||
|
||||
// # Type current password, leave new password blank.
|
||||
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
|
||||
|
||||
// # Click the 'Reset' button.
|
||||
cy.get('button[type=submit] span').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify the appropriate error is returned.
|
||||
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').
|
||||
and('contain', 'Must be 5-64 characters long.');
|
||||
});
|
||||
|
||||
it('MM-T937 Users - System admin changes own password - Successfully changed', () => {
|
||||
// # Search for the admin.
|
||||
cy.get('#searchUsers').type(otherAdmin.username).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Open the actions menu.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .text-right a').
|
||||
click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Reset Password menu option.
|
||||
cy.get('[data-testid="userListRow"] .more-modal__right .more-modal__actions .MenuWrapper .MenuWrapperAnimation-enter-done').
|
||||
find('li').eq(2).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Type current and new passwords..
|
||||
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
|
||||
cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password);
|
||||
|
||||
// # Click the 'Reset' button.
|
||||
cy.get('button[type=submit] span').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Log out.
|
||||
cy.apiLogout();
|
||||
|
||||
// * Verify that logging in with old password returns an error.
|
||||
apiLogin(otherAdmin.username, otherAdmin.password).then((response) => {
|
||||
expect(response.status).to.equal(401);
|
||||
|
||||
// * Verify that logging in with new password works.
|
||||
otherAdmin.password = 'new' + otherAdmin.password;
|
||||
cy.apiLogin(otherAdmin);
|
||||
|
||||
// # Reset admin's password to the original.
|
||||
cy.apiResetPassword('me', otherAdmin.password, otherAdmin.password.substr(3));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function apiLogin(username, password) {
|
||||
return cy.request({
|
||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||
url: '/api/v4/users/login',
|
||||
method: 'POST',
|
||||
body: {login_id: username, password},
|
||||
failOnStatusCode: false,
|
||||
});
|
||||
}
|
||||
@@ -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 @system_console @not_cloud
|
||||
|
||||
const TIMEOUTS = require('../../../fixtures/timeouts');
|
||||
|
||||
describe('User Management', () => {
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let sysadmin;
|
||||
let testUser;
|
||||
let otherUser;
|
||||
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testChannel = channel;
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
return cy.apiCreateUser();
|
||||
}).then(({user: user2}) => {
|
||||
otherUser = user2;
|
||||
});
|
||||
|
||||
cy.apiAdminLogin().then((res) => {
|
||||
sysadmin = res.user;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T942 Users - Deactivated user not in drop-down, auto-logged out', () => {
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Create a direct channel between two users
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(() => {
|
||||
// # Visit the channel using the channel name
|
||||
cy.visit(`/${testTeam.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
|
||||
cy.apiLogout().apiAdminLogin();
|
||||
activateUser(otherUser, false);
|
||||
cy.apiLogout().wait(TIMEOUTS.FIVE_SEC);
|
||||
|
||||
cy.visit('/login');
|
||||
|
||||
// # Login as otherUser
|
||||
cy.get('#input_loginId').should('be.visible').type(otherUser.username);
|
||||
cy.get('#input_password-input').should('be.visible').type(otherUser.password);
|
||||
cy.get('#saveSetting').should('be.visible').click();
|
||||
|
||||
// * Verify appropriate error message is displayed for deactivated user
|
||||
cy.findByText('Login failed because your account has been deactivated. Please contact an administrator.').should('exist').and('be.visible');
|
||||
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// visit test channel
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Open team menu and click View Members
|
||||
cy.uiOpenTeamMenu('View Members');
|
||||
|
||||
// * Check View Members modal dialog
|
||||
cy.get('#teamMembersModal').should('be.visible').within(() => {
|
||||
cy.get('#searchUsersInput').
|
||||
should('be.visible').
|
||||
click().
|
||||
type(otherUser.email, {force: true});
|
||||
|
||||
// * Deactivated user does not show up in View Members for teams
|
||||
cy.findByTestId('noUsersFound');
|
||||
cy.uiClose();
|
||||
});
|
||||
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Click Channel Members
|
||||
cy.get('.member-rhs__trigger').should('be.visible').click();
|
||||
|
||||
// * Deactivated user does not show up in View Members for channels
|
||||
cy.uiGetRHS().findByText(otherUser.username).should('not.exist');
|
||||
|
||||
// * User does show up in DM More menu so that DM channels can be viewed.
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').findByText(otherUser.username).should('not.exist');
|
||||
cy.uiAddDirectMessage().click();
|
||||
|
||||
// * Verify that new messages cannot be posted.
|
||||
cy.get('#moreDmModal').should('be.visible').within(() => {
|
||||
cy.get('#selectItems input').typeWithForce(otherUser.email + '{enter}').wait(TIMEOUTS.HALF_SEC);
|
||||
cy.uiGetPostTextBox({exist: false});
|
||||
});
|
||||
|
||||
// # Restore the user.
|
||||
cy.apiLogout().apiAdminLogin();
|
||||
activateUser(otherUser, true);
|
||||
});
|
||||
|
||||
it('MM-T943 Users - Deactivate a user - DM, GM in LHS (not actively viewing DM in another window)', () => {
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// # Open a DM with a user you want to deactivate, post a message
|
||||
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(() => {
|
||||
cy.visit(`/${testTeam.name}/channels/${testUser.id}__${otherUser.id}`);
|
||||
cy.postMessage(':)');
|
||||
});
|
||||
|
||||
// # Also open a GM with that user and a third user, post a message.
|
||||
cy.apiCreateGroupChannel([sysadmin.id, otherUser.id, testUser.id]).then(({channel}) => {
|
||||
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
|
||||
cy.postMessage('hello');
|
||||
});
|
||||
|
||||
const displayName = [sysadmin, otherUser].
|
||||
map((member) => member.username).
|
||||
sort((a, b) => a.localeCompare(b, 'en', {numeric: true})).
|
||||
join(', ');
|
||||
|
||||
// # Observe DM and GM in LHS.
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').findByText(displayName).should('be.visible');
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').findByText(otherUser.username).should('be.visible');
|
||||
|
||||
// # System Console > Users Deactivate the user.
|
||||
cy.apiLogout().apiAdminLogin();
|
||||
activateUser(otherUser, false);
|
||||
|
||||
// # Go back to view team.
|
||||
cy.apiLogin(testUser).visit(`/${testTeam.name}/channels/${testChannel.name}`).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * On returning to the team the DM has been removed from LHS.
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').findByText(otherUser.username).should('not.exist');
|
||||
|
||||
// * GM stays in LHS channel list.
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').findByText(displayName).should('be.visible');
|
||||
|
||||
// # Open GM channel.
|
||||
cy.uiGetLhsSection('DIRECT MESSAGES').findByText(displayName).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * GM still has message box (is not archived)
|
||||
cy.findByTestId('post_textbox').should('be.visible');
|
||||
|
||||
// # Restore the user.
|
||||
cy.apiLogout().apiAdminLogin();
|
||||
activateUser(otherUser, true);
|
||||
});
|
||||
|
||||
function activateUser(user, activate) {
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// # Search for the user.
|
||||
cy.get('#searchUsers').clear().type(user.email, {delay: TIMEOUTS.ONE_HUNDRED_MILLIS}).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
cy.findByTestId('userListRow').within(() => {
|
||||
if (activate) {
|
||||
cy.findByText('Inactive').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click on the "Activate" button.
|
||||
cy.findByLabelText('User Actions Menu').findByText('Activate').click();
|
||||
} else {
|
||||
cy.findByText('Member').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click on the "Deactivate" button.
|
||||
cy.findByLabelText('User Actions Menu').findByText('Deactivate').click();
|
||||
}
|
||||
});
|
||||
|
||||
if (!activate) {
|
||||
// # Verify the modal opened and then confirm.
|
||||
cy.get('#confirmModal').should('exist').within(() => {
|
||||
cy.get('#confirmModalButton').click().wait(TIMEOUTS.HALF_SEC);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,302 @@
|
||||
// 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 @system_console
|
||||
|
||||
import {
|
||||
getEmailResetEmailTemplate,
|
||||
getEmailVerifyEmailTemplate,
|
||||
getRandomId,
|
||||
verifyEmailBody,
|
||||
} from '../../../utils';
|
||||
|
||||
const TIMEOUTS = require('../../../fixtures/timeouts');
|
||||
|
||||
describe('User Management', () => {
|
||||
const newUsername = 'u' + getRandomId();
|
||||
const newEmailAddr = newUsername + '@sample.mattermost.com';
|
||||
let testTeam;
|
||||
let testChannel;
|
||||
let sysadmin;
|
||||
let testUser;
|
||||
|
||||
before(() => {
|
||||
cy.apiInitSetup().then(({team, channel, user}) => {
|
||||
testChannel = channel;
|
||||
testTeam = team;
|
||||
testUser = user;
|
||||
});
|
||||
|
||||
cy.apiAdminLogin().then((res) => {
|
||||
sysadmin = res.user;
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T924 Users - Page through users list', () => {
|
||||
cy.apiGetUsers().then(({users}) => {
|
||||
const minimumNumberOfUsers = 60;
|
||||
|
||||
if (users.length < minimumNumberOfUsers) {
|
||||
Cypress._.times(minimumNumberOfUsers - users.length, () => {
|
||||
cy.apiCreateUser();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
cy.get('#searchableUserListTotal').then((el) => {
|
||||
const count1 = el[0].innerText.replace(/\n/g, '').replace(/\s/g, ' ');
|
||||
|
||||
// * Can page through several pages of users.
|
||||
cy.get('#searchableUserListNextBtn').should('be.visible').click();
|
||||
|
||||
// * Count at top changes appropriately.
|
||||
cy.get('#searchableUserListTotal').then((el2) => {
|
||||
const count2 = el2[0].innerText.replace(/\n/g, '').replace(/\s/g, ' ');
|
||||
expect(count1).not.equal(count2);
|
||||
});
|
||||
|
||||
// * Can page backward as well.
|
||||
cy.get('#searchableUserListPrevBtn').should('be.visible').click();
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T928 Users - Change a user\'s email address', () => {
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// # Update config.
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: true,
|
||||
},
|
||||
});
|
||||
|
||||
// * Blank email address: "Please enter a valid email address"
|
||||
resetUserEmail(testUser.email, '', 'Please enter a valid email address');
|
||||
|
||||
// * Invalid email address: "Please enter a valid email address"
|
||||
resetUserEmail(testUser.email, 'user-1(at)sample.mattermost.com', 'Please enter a valid email address');
|
||||
|
||||
// * Email address already in use: "An account with that email already exists."
|
||||
resetUserEmail(testUser.email, 'sysadmin@sample.mattermost.com', 'An account with that email already exists.');
|
||||
});
|
||||
|
||||
it('MM-T929 Users - Change a user\'s email address, with verification off', () => {
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// # Update config.
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
});
|
||||
|
||||
// # System admin changes new user's email address.
|
||||
resetUserEmail(testUser.email, newEmailAddr, '');
|
||||
|
||||
// # Updates immediately in Profile for the user.
|
||||
cy.get('#searchUsers').clear().type(newEmailAddr).wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('.more-modal__details').should('be.visible').within(() => {
|
||||
cy.findByText(newEmailAddr).should('exist');
|
||||
});
|
||||
|
||||
// * User also receives email confirmation that email address has been changed.
|
||||
checkResetEmail(testUser, newEmailAddr);
|
||||
|
||||
// # Logout, so that test user can login.
|
||||
cy.apiLogout();
|
||||
|
||||
// * User cannot log in with old email address.
|
||||
apiLogin(testUser.email, testUser.password).then((response) => {
|
||||
expect(response.status).to.equal(401);
|
||||
|
||||
// # User logs in with username /password (no verification needed), then logs out again
|
||||
cy.apiLogin({username: testUser.username, password: testUser.password}).apiLogout();
|
||||
|
||||
// # User logs in with new email address /password (no verification needed)
|
||||
cy.apiLogin({username: newEmailAddr, password: testUser.password}).apiLogout();
|
||||
});
|
||||
|
||||
// # Revert the changes.
|
||||
cy.apiAdminLogin();
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
resetUserEmail(newEmailAddr, testUser.email, '');
|
||||
});
|
||||
|
||||
it('MM-T930 Users - Change a user\'s email address, with verification on', () => {
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// # Update Configs.
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: true,
|
||||
},
|
||||
});
|
||||
|
||||
resetUserEmail(testUser.email, newEmailAddr, '');
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Type email and password.
|
||||
cy.get('#input_loginId').type(testUser.email);
|
||||
cy.get('#input_password-input').type(testUser.password);
|
||||
cy.get('#saveSetting').should('not.be.disabled').click();
|
||||
|
||||
// * Verify that logging in with the old e-mail works but requires e-mail verification.
|
||||
cy.url().should('include', 'should_verify_email');
|
||||
|
||||
// # Log out.
|
||||
cy.apiLogout();
|
||||
|
||||
// Verify e-mail.
|
||||
verifyEmail({username: newUsername, email: newEmailAddr});
|
||||
cy.wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Verify that logging in with the old e-mail works.
|
||||
cy.apiLogin({username: newEmailAddr, password: testUser.password}).apiLogout();
|
||||
|
||||
// # Revert the config.
|
||||
cy.apiAdminLogin().apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
});
|
||||
|
||||
resetUserEmail(newEmailAddr, testUser.email, '');
|
||||
});
|
||||
|
||||
it('MM-T931 Users - Can\'t update a user\'s email address if user has other signin method', () => {
|
||||
// # Update config.
|
||||
cy.apiUpdateConfig({
|
||||
GitLabSettings: {
|
||||
Enable: true,
|
||||
},
|
||||
});
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
cy.apiCreateUser().then(({user: gitlabUser}) => {
|
||||
cy.apiUpdateUserAuth(gitlabUser.id, gitlabUser.email, '', 'gitlab');
|
||||
|
||||
// # Search for the user.
|
||||
cy.get('#searchUsers').clear().type(gitlabUser.email).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
cy.findByTestId('userListRow').within(() => {
|
||||
// # Open the actions menu.
|
||||
cy.findByText('Member').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Update email menu option.
|
||||
cy.findByLabelText('User Actions Menu').findByText('Update Email').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T941 Users - Revoke all sessions for unreachable users', () => {
|
||||
// # Login as a system user - User
|
||||
cy.apiLogin(testUser);
|
||||
|
||||
// Visit the test channel
|
||||
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
|
||||
|
||||
// # Revoke all sessions for the user
|
||||
cy.externalRequest({user: sysadmin, method: 'post', path: `users/${testUser.id}/sessions/revoke/all`});
|
||||
|
||||
// # Visit default page and wait until it's redirected to login page
|
||||
cy.visit('/');
|
||||
cy.waitUntil(() => cy.url().then((url) => {
|
||||
return url.includes('/login');
|
||||
}), {timeout: TIMEOUTS.HALF_MIN});
|
||||
|
||||
// # Check if user's session is automatically logged out and the user is redirected to the login page
|
||||
cy.url().should('contain', '/login');
|
||||
});
|
||||
|
||||
function resetUserEmail(oldEmail, newEmail, errorMsg) {
|
||||
cy.visit('/admin_console/user_management/users');
|
||||
|
||||
// # Search for the user.
|
||||
cy.get('#searchUsers').clear().type(oldEmail).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
cy.findByTestId('userListRow').within(() => {
|
||||
// # Open the actions menu.
|
||||
cy.findByText('Member').click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click the Update email menu option.
|
||||
cy.findByLabelText('User Actions Menu').findByText('Update Email').click().wait(TIMEOUTS.HALF_SEC);
|
||||
});
|
||||
|
||||
// # Verify the modal opened.
|
||||
cy.findByTestId('resetEmailModal').should('exist');
|
||||
|
||||
// # Type the new e-mail address.
|
||||
if (newEmail.length > 0) {
|
||||
cy.get('input[type=email]').eq(0).clear().type(newEmail);
|
||||
}
|
||||
|
||||
// # Click the "Reset" button.
|
||||
cy.findByTestId('resetEmailButton').click();
|
||||
|
||||
// * Check for the error messages, if any.
|
||||
if (errorMsg.length > 0) {
|
||||
cy.get('form.form-horizontal').find('.has-error p.error').should('be.visible').and('contain', errorMsg);
|
||||
|
||||
// # Close the modal.
|
||||
cy.findByLabelText('Close').click();
|
||||
}
|
||||
}
|
||||
|
||||
function checkResetEmail(user, newEmail) {
|
||||
cy.getRecentEmail(user).then((data) => {
|
||||
const {body: actualEmailBody, subject} = data;
|
||||
|
||||
// # Verify that the email subject is as expected.
|
||||
expect(subject).to.contain('Your email address has changed');
|
||||
|
||||
// # Verify email body
|
||||
const expectedEmailBody = getEmailResetEmailTemplate(newEmail);
|
||||
verifyEmailBody(expectedEmailBody, actualEmailBody);
|
||||
});
|
||||
}
|
||||
|
||||
function verifyEmail(user) {
|
||||
const baseUrl = Cypress.config('baseUrl');
|
||||
|
||||
// # Verify e-mail through verification link.
|
||||
cy.getRecentEmail(user).then((data) => {
|
||||
const {body: actualEmailBody, subject} = data;
|
||||
|
||||
// # Verify that the email subject is as expected.
|
||||
expect(subject).to.contain('Email Verification');
|
||||
|
||||
// # Verify email body
|
||||
const expectedEmailBody = getEmailVerifyEmailTemplate(user.email);
|
||||
verifyEmailBody(expectedEmailBody, actualEmailBody);
|
||||
|
||||
// # Extract verification the link from the e-mail.
|
||||
const line = actualEmailBody[4].split(' ');
|
||||
const verificationLink = line[3].replace(baseUrl, '');
|
||||
|
||||
// # Complete verification.
|
||||
cy.visit(verificationLink);
|
||||
cy.findByText('Email Verified').should('be.visible');
|
||||
cy.get('#input_loginId').should('be.visible').and('have.value', user.email);
|
||||
});
|
||||
}
|
||||
|
||||
function apiLogin(username, password) {
|
||||
return cy.request({
|
||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||
url: '/api/v4/users/login',
|
||||
method: 'POST',
|
||||
body: {login_id: username, password},
|
||||
failOnStatusCode: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,327 @@
|
||||
// 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 @system_console
|
||||
|
||||
describe('Workspace deletion', () => {
|
||||
const host = window.location.host;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiLogout();
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
it('Workspace deletion cta is visible for free trials', () => {
|
||||
// Professional Yearly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_3',
|
||||
is_free_trial: 'true',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete your workspace').should('exist');
|
||||
cy.findByText(`${host}`).should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion cta is not visible for cloud professional with a yearly plan', () => {
|
||||
// Professional Yearly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_4',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
// Text is separated by an html <a> tag, just get the last half.
|
||||
cy.findByText('Delete your workspace').should('not.exist');
|
||||
cy.findByText(`${host}`).should('not.exist');
|
||||
|
||||
cy.findByText('Cancel your subscription').should('exist');
|
||||
cy.findByText('At this time, deleting a workspace can only be done with the help of a customer support representative.').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion cta is not visible for cloud enterprise with a yearly plan', () => {
|
||||
// Enterprise Yearly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_5',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
// Text is separated by an html <a> tag, just get the last half.
|
||||
cy.findByText('Delete your workspace').should('not.exist');
|
||||
cy.findByText(`${host}`).should('not.exist');
|
||||
|
||||
cy.findByText('Cancel your subscription').should('exist');
|
||||
cy.findByText('At this time, deleting a workspace can only be done with the help of a customer support representative.').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion cta is visible for cloud free', () => {
|
||||
// Free.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_1',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete your workspace').should('exist');
|
||||
cy.findByText(`${host}`).should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion cta is visible for cloud professional with a monthly plan', () => {
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete your workspace').should('exist');
|
||||
cy.findByText(`${host}`).should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion cta is not visible for cloud enterprise with a monthly plan', () => {
|
||||
// Professional Yearly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_3',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
// Text is separated by an html <a> tag, just get the last half.
|
||||
cy.findByText('Delete your workspace').should('not.exist');
|
||||
cy.findByText(`${host}`).should('not.exist');
|
||||
|
||||
cy.findByText('Cancel your subscription').should('exist');
|
||||
cy.findByText('At this time, deleting a workspace can only be done with the help of a customer support representative.').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade button is not visible for cloud free', () => {
|
||||
// Free.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_1',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('not.exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade button is visible for cloud professional', () => {
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade button is not visible for free trials', () => {
|
||||
// Free.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_3',
|
||||
is_free_trial: 'true',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('not.exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > delete workspace button click > feedback modal shown before submitting deletion request', () => {
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.get('.DeleteWorkspaceModal__Buttons-Delete').contains('Delete Workspace').should('exist').click();
|
||||
cy.findByText('Please share your reason for deleting').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > delete workspace button click > feedback modal requires option selected to enable submit', () => {
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.get('.DeleteWorkspaceModal__Buttons-Delete').contains('Delete Workspace').should('exist').click();
|
||||
cy.findByText('Please share your reason for deleting').should('exist');
|
||||
cy.findByText('No longer found value').click();
|
||||
cy.get('.GenericModal__button.confirm').contains('Delete Workspace').should('be.enabled');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade workspace button click > feedback modal shown before submitting downgrade request', () => {
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('exist').click();
|
||||
cy.findByText('Please share your reason for downgrading').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade workspace button click > feedback modal requires option selected to enable submit', () => {
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('exist').click();
|
||||
cy.findByText('Please share your reason for downgrading').should('exist');
|
||||
cy.findByText('Experienced technical issues').click();
|
||||
cy.findByText('Downgrade').should('be.enabled');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > delete workspace > after survey, a success modal is displayed when the deletion succeeds', () => {
|
||||
cy.intercept('DELETE', '/api/v4/cloud/delete-workspace', {statusCode: 200, body: {message: 'Status OK'}}).as('deleteWorkspace');
|
||||
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.get('.DeleteWorkspaceModal__Buttons-Delete').contains('Delete Workspace').should('exist').click();
|
||||
cy.findByText('Please share your reason for deleting').should('exist');
|
||||
cy.findByText('No longer found value').click();
|
||||
cy.get('.GenericModal__button.confirm').contains('Delete Workspace').should('be.enabled').click();
|
||||
cy.wait('@deleteWorkspace');
|
||||
|
||||
cy.get('.result_modal').should('exist');
|
||||
cy.findByText('Your workspace has been deleted').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > delete workspace > after survey, a failure modal is displayed when the deletion fails', () => {
|
||||
cy.intercept('DELETE', '/api/v4/cloud/delete-workspace', {statusCode: 500}).as('deleteWorkspace');
|
||||
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.get('.DeleteWorkspaceModal__Buttons-Delete').contains('Delete Workspace').should('exist').click();
|
||||
cy.findByText('Please share your reason for deleting').should('exist');
|
||||
cy.findByText('No longer found value').click();
|
||||
cy.get('.GenericModal__button.confirm').contains('Delete Workspace').should('be.enabled').click();
|
||||
|
||||
cy.wait('@deleteWorkspace');
|
||||
|
||||
cy.get('.result_modal').should('exist');
|
||||
cy.findByText('Workspace deletion failed').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade workspace > after survey, a success modal is displayed when the downgrade succeeds', () => {
|
||||
cy.intercept('PUT', '/api/v4/cloud/subscription', {statusCode: 200, body: {message: 'Status OK'}}).as('downgradeWorkspace');
|
||||
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('exist').click();
|
||||
cy.findByText('Please share your reason for downgrading').should('exist');
|
||||
cy.findByText('Experienced technical issues').click();
|
||||
cy.findByText('Downgrade').should('be.enabled').click();
|
||||
|
||||
cy.wait('@downgradeWorkspace');
|
||||
|
||||
cy.get('.cloud_subscribe_result_modal').should('exist');
|
||||
cy.findByText('You are now subscribed to Cloud Free').should('exist');
|
||||
});
|
||||
|
||||
it('Workspace deletion modal > downgrade workspace > after survey, a failure modal is displayed when the downgrade fails', () => {
|
||||
cy.intercept('PUT', '/api/v4/cloud/subscription', {statusCode: 500}).as('downgradeWorkspace');
|
||||
|
||||
// Professional Monthly.
|
||||
const subscription = {
|
||||
id: 'sub_test1',
|
||||
product_id: 'prod_2',
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
cy.simulateSubscription(subscription);
|
||||
cy.visit('/admin_console/billing/subscription');
|
||||
|
||||
cy.findByText('Delete Workspace').click();
|
||||
cy.findByText('Are you sure you want to delete?').should('exist');
|
||||
cy.findByText('Downgrade To Free').should('exist').click();
|
||||
cy.findByText('Please share your reason for downgrading').should('exist');
|
||||
cy.findByText('Experienced technical issues').click();
|
||||
cy.findByText('Downgrade').should('be.enabled').click();
|
||||
|
||||
cy.wait('@downgradeWorkspace');
|
||||
|
||||
cy.get('.cloud_subscribe_result_modal').should('exist');
|
||||
cy.findByText('We were unable to change your plan').should('exist');
|
||||
});
|
||||
});
|
||||
Ссылка в новой задаче
Block a user