snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-16 00:29:55 +05:00
commit 240db4e2a7
15309 changed files with 2173406 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
// 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 @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.findByTestId('AnnouncementSettings.EnableBannertrue').
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.findByTestId('AnnouncementSettings.AllowBannerDismissaltrue').
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');
});
// Go back to Channels
cy.get('a.backstage-navbar__back').click();
// # 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');
});
});

View File

@@ -0,0 +1,366 @@
// 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 TIMEOUTS from '@/fixtures/timeouts';
import {getRandomId} from '@/utils';
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.get('div.header-main a').should('be.visible').should('have.text', siteName);
cy.get('p.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', () => {
const emojiText = getRandomId(3);
// # 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(emojiText);
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 = `​​​​:${emojiText}:
: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\``;
// # 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 default emoji has been rendered
cy.get('span.emoticon').should('have.attr', 'alt', ':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.get('div.header-main a').should('be.visible').should('have.text', siteName);
// # 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();
}

View File

@@ -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();
}

View File

@@ -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 @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: 'Mattermost user guide', link: SupportSettings.MATTERMOST_USER_GUIDE},
{text: 'Report a problem', link: 'mailto:reportaproblem@mattermost.com'},
{text: 'Keyboard shortcuts'},
].forEach(({text, link}) => {
if (link) {
cy.findByText(text).
parent().
should('have.attr', 'href').
and('contain', 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').
and('contain', 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').
and('contain', guide.link);
});
});
});

View File

@@ -0,0 +1,212 @@
// 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 {backToTeam, saveSetting} from './helper';
import * as TIMEOUTS from '@/fixtures/timeouts';
import {TERMS_OF_SERVICE_LINK} from '@/utils/constants';
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';
const askCommunityLink = 'https://mattermost.com/pl/default-ask-mattermost-community';
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.ReportAProblemTypedropdown').select('Custom link');
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: 'Ask the community', link: askCommunityLink},
].forEach((guide) => {
cy.findByText(guide.text).
parent().
should('have.attr', 'href').and('match', new RegExp(`${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').and('match', new RegExp(`${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').and('match', new RegExp(`${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').and('match', new RegExp(`${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.ReportAProblemTypedropdown').select('Hide link');
// # 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 = 'https://github.com/mattermost/desktop/releases';
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').
parents('a').
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('mouseenter').
should('have.attr', 'aria-describedby');
cy.uiGetHelpButton().
trigger('mouseleave').
should('not.have.attr', 'aria-describedby');
// # Open help menu
cy.uiOpenHelpMenu().within(() => {
// * Verify 4 options shown
cy.findByText('Ask the community');
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').and('match', new RegExp(`${askCommunityLink}/*`));
});
});
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.ReportAProblemTypedropdown').select('Custom link');
cy.findByTestId('SupportSettings.ReportAProblemLinkinput').clear().type(problemLink);
// # Save setting and back to team view
saveSetting();
backToTeam();
// # Open help menu
cy.uiOpenHelpMenu().within(() => {
// * Verify 2 options shown
cy.findByText('Report a problem');
cy.findByText('Keyboard shortcuts');
// * Verify report a problem link has changed
cy.findByText('Report a problem').
parent().
should('have.attr', 'href').and('match', new RegExp(`${problemLink}/*`));
// # Click on keyboard shortcuts
cy.findByText('Keyboard shortcuts').click();
});
// * Verify link opens keyboard shortcuts modal
cy.findAllByRole('dialog', 'Keyboard shortcuts');
});
});

View File

@@ -0,0 +1,107 @@
// 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 {backToTeam, saveSetting} from './helper';
import {
FixedPublicLinks,
} from '@/utils';
import * as TIMEOUTS from '@/fixtures/timeouts';
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('match', new RegExp(`${FixedPublicLinks.TermsOfService}/*`));
cy.get('#privacyLink').should('contain', 'Privacy Policy').and('have.attr', 'href').and('match', new RegExp(`${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('match', new RegExp(`${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('match', new RegExp(`${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');
});
});
});