Files
upstream-mirror 240db4e2a7
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 Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 00:29:55 +05:00

326 lines
11 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import type {ChainableT} from '../../types';
function uiGetPostTextBox(option = {exist: true}): ChainableT<JQuery> {
if (option.exist) {
return cy.get('#post_textbox').should('be.visible');
}
return cy.get('#post_textbox').should('not.exist');
}
Cypress.Commands.add('uiGetPostTextBox', uiGetPostTextBox);
function uiGetReplyTextBox(option = {exist: true}): ChainableT<JQuery> {
if (option.exist) {
return cy.get('#reply_textbox').should('be.visible');
}
return cy.get('#reply_textbox').should('not.exist');
}
Cypress.Commands.add('uiGetReplyTextBox', uiGetReplyTextBox);
function uiGetPostProfileImage(postId: string): ChainableT<JQuery> {
return getPost(postId).within(() => {
return cy.get('.post__img').should('be.visible');
});
}
Cypress.Commands.add('uiGetPostProfileImage', uiGetPostProfileImage);
function uiGetPostHeader(postId: string): ChainableT<JQuery> {
return getPost(postId).within(() => {
return cy.get('.post__header').should('be.visible');
});
}
Cypress.Commands.add('uiGetPostHeader', uiGetPostHeader);
function uiGetPostBody(postId: string): ChainableT<JQuery> {
return getPost(postId).within(() => {
return cy.get('.post__body').should('be.visible');
});
}
Cypress.Commands.add('uiGetPostBody', uiGetPostBody);
function uiGetPostThreadFooter(postId: string): ChainableT<JQuery> {
return getPost(postId).find('.ThreadFooter');
}
Cypress.Commands.add('uiGetPostThreadFooter', uiGetPostThreadFooter);
function uiGetPostEmbedContainer(postId: string): ChainableT<JQuery> {
return cy.uiGetPostBody(postId).
find('.file-preview__button').
should('be.visible');
}
Cypress.Commands.add('uiGetPostEmbedContainer', uiGetPostEmbedContainer);
function getCenterPostById(postId: string): ChainableT<JQuery> {
// Prefer postView rows: virtualized lists may detach #post_<id> from a bare cy.get() query.
return cy.findAllByTestId('postView', {timeout: 20000}).
filter(`#post_${postId}`).
should('have.length.at.least', 1).
first().
scrollIntoView().
should('be.visible');
}
function getPost(postId: string): ChainableT<JQuery> {
if (postId) {
return getCenterPostById(postId);
}
return cy.getLastPost();
}
Cypress.Commands.add('getPost', getPost);
function getPostMmBlocks(postId: string): ChainableT<JQuery> {
return getCenterPostById(postId).find('.mm-blocks').should('exist');
}
Cypress.Commands.add('getPostMmBlocks', getPostMmBlocks);
function getRhsPostMmBlocks(postId: string): ChainableT<JQuery> {
return cy.findAllByTestId('rhsPostView', {timeout: 20000}).
filter(`#rhsPost_${postId}`).
should('have.length.at.least', 1).
first().
find('.mm-blocks').
should('exist');
}
Cypress.Commands.add('getRhsPostMmBlocks', getRhsPostMmBlocks);
function editLastPostWithNewMessage(message: string) {
cy.uiGetPostTextBox().type('{uparrow}');
// * Edit Post Input should appear
cy.get('#edit_textbox').should('be.visible');
// # Update the post message and click Save
cy.get('#edit_textbox').clear().type(message);
cy.get('#create_post').findByText('Save').scrollIntoView().click();
}
Cypress.Commands.add('editLastPostWithNewMessage', editLastPostWithNewMessage);
export function verifySavedPost(postId: string, message: string) {
// * Check that the center save icon has been updated correctly
cy.get(`#post_${postId}`).trigger('mouseover', {force: true});
cy.get(`#CENTER_flagIcon_${postId}`).
should('have.class', 'post-menu__item').
and('have.attr', 'aria-label', 'remove from saved');
// # Open the post-dotmenu
cy.clickPostDotMenu(postId, 'CENTER');
// * Check that the dotmenu item is changed accordingly
cy.findAllByTestId(`post-menu-${postId}`).eq(0).should('be.visible');
cy.findByText('Remove from Saved').scrollIntoView().should('be.visible');
cy.get('body').type('{esc}');
cy.get('#postListContent').within(() => {
// * Check that the post is highlighted
cy.get(`#post_${postId}`).should('have.class', 'post--pinned-or-flagged');
// * Check that the post pre-header is visible
cy.get('div.post-pre-header').should('be.visible');
// * Check that the post pre-header has the saved icon
cy.get('span.icon--post-pre-header').
should('be.visible').
within(() => {
cy.get('svg').should('have.attr', 'aria-label', 'Saved Icon');
});
// * Check that the post pre-header has the saved post link
cy.get('div.post-pre-header__text-container').
should('be.visible').
and('have.text', 'Saved').
within(() => {
cy.get('a').as('savedLink').should('be.visible');
});
});
// * Check that the saved posts list is not open in RHS before clicking the link in the post pre-header
cy.get('#searchContainer').should('not.exist');
// # Click the link
cy.get('@savedLink').click();
// * Check that the saved posts list is open in RHS
cy.get('#searchContainer').should('be.visible').within(() => {
cy.get('.sidebar--right__title').
should('be.visible').
and('have.text', 'Saved messages');
// * Check that the post pre-header is not shown for the saved message in RHS
cy.get(`#searchResult_${postId}`).within(() => {
cy.get(`#rhsPostMessageText_${postId}`).contains(message);
cy.get('div.post-pre-header').should('not.exist');
});
});
// # Close the RHS
cy.get('#searchResultsCloseButton').should('be.visible').click();
}
export function verifyUnsavedPost(postId: string) {
// * Check that the center save icon has been updated correctly
cy.get(`#post_${postId}`).trigger('mouseover', {force: true});
cy.get(`#CENTER_flagIcon_${postId}`).
should('have.class', 'post-menu__item').
and('have.attr', 'aria-label', 'save message');
// # Open the post-dotmenu
cy.clickPostDotMenu(postId, 'CENTER');
// * Check that the dotmenu item is changed accordingly
cy.findAllByTestId(`post-menu-${postId}`).eq(0).should('be.visible');
cy.findByText('Save Message').scrollIntoView().should('be.visible');
cy.get('body').type('{esc}');
cy.get('#postListContent').within(() => {
// * Check that the post is not highlighted
cy.get(`#post_${postId}`).should('not.have.class', 'post--pinned-or-flagged');
// * Check that the post pre-header is not visible
cy.get('div.post-pre-header').should('not.exist');
// * Check that the post pre-header does not have the saved icon
cy.get('span.icon--post-pre-header').
should('not.exist');
// * Check that the post pre-header does not have the saved post link
cy.get('div.post-pre-header__text-container').
should('not.exist');
});
// * Check that the saved posts list is not open in RHS before clicking the link in the post pre-header
cy.get('#searchContainer').should('not.exist');
// # Click the link
cy.uiGetSavedPostButton().click();
// * Check that the saved posts list is open in RHS
cy.get('#searchContainer').should('be.visible').within(() => {
cy.get('.sidebar--right__title').
should('be.visible').
and('have.text', 'Saved messages');
// * Check that the post pre-header is not shown for the saved message in RHS
cy.get('#search-items-container').within(() => {
cy.get(`#rhsPostMessageText_${postId}`).should('not.exist');
});
});
// # Close the RHS
cy.get('#searchResultsCloseButton').should('be.visible').click();
}
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable {
/**
* Edit last post with a new message
*
* @param {string} - message
*
* @example
* cy.editLastPostWithNewMessage('new message');
*/
editLastPostWithNewMessage: typeof editLastPostWithNewMessage;
/**
* Get post profile image of a given post ID or the last post if post ID is not given
*
* @param {string} - postId (optional)
*
* @example
* cy.uiGetPostProfileImage();
*/
uiGetPostProfileImage: typeof uiGetPostProfileImage;
/**
* Get post header of a given post ID or the last post if post ID is not given
*
* @param {string} - postId (optional)
*
* @example
* cy.uiGetPostHeader();
*/
uiGetPostHeader: typeof uiGetPostHeader;
/**
* Get post body of a given post ID or the last post if post ID is not given
*
* @param {string} - postId (optional)
*
* @example
* cy.uiGetPostBody();
*/
uiGetPostBody: typeof uiGetPostBody;
/**
* Get post thread footer of a given post ID or the last post if post ID is not given
*
* @param {string} - postId (optional)
*
* @example
* cy.uiGetPostThreadFooter();
*/
uiGetPostThreadFooter: typeof uiGetPostThreadFooter;
/**
* Get post embed container of a given post ID or the last post if post ID is not given
*
* @param {string} - postId (optional)
*
* @example
* cy.uiGetPostEmbedContainer();
*/
uiGetPostEmbedContainer: typeof uiGetPostEmbedContainer;
/**
* Get post textbox
*
* @param {bool} option.exist - Set to false to check whether element should not exist. Otherwise, true (default) to check visibility.
*
* @example
* cy.uiGetPostTextBox();
*/
uiGetPostTextBox: typeof uiGetPostTextBox;
/**
* Get reply textbox
*
* @param {bool} option.exist - Set to false to check whether element should not exist. Otherwise, true (default) to check visibility.
*
* @example
* cy.uiGetReplyTextBox();
*/
uiGetReplyTextBox: typeof uiGetReplyTextBox;
getPost: typeof getPost;
/**
* Get mm_blocks root within a center-channel post.
*
* @param {string} postId
*
* @example
* cy.getPostMmBlocks(postId).within(() => { ... });
*/
getPostMmBlocks: typeof getPostMmBlocks;
/**
* Get mm_blocks root within an RHS/thread post row.
*
* @param {string} postId
*
* @example
* cy.getRhsPostMmBlocks(postId).within(() => { ... });
*/
getRhsPostMmBlocks: typeof getRhsPostMmBlocks;
}
}
}