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 Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
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
This commit is contained in:
325
e2e-tests/cypress/tests/support/ui/post.ts
Normal file
325
e2e-tests/cypress/tests/support/ui/post.ts
Normal file
@@ -0,0 +1,325 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user