Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
56baba3
[MM-62302] Edit message update "post too long" error message placemen…
M-ZubairAhmed Jan 6, 2025
1db330c
[MM-62403] Seperate MessageWithMentionsFooter into separate component…
M-ZubairAhmed Jan 6, 2025
7005a9e
[MM-61800] Email is cut off in profile popover (#29753)
M-ZubairAhmed Jan 7, 2025
697feda
[MA-27]: Remove tabIndex from non-interactive elements
SaurabhSharma-884 Dec 16, 2024
06ce7b4
Translations update from Mattermost Weblate (#29715)
weblate Jan 7, 2025
2bbd136
[MA-27]: Fix E2E tests
SaurabhSharma-884 Jan 7, 2025
e0e24aa
[MM-62390] Combine the floating and transition styles into one in Wit…
M-ZubairAhmed Jan 7, 2025
647c9b6
[MM-62293]: Remove Elasticsearch from translation strings (#29728)
agnivade Jan 8, 2025
55a7993
[MM-T5139] Add Standard message priority and system setting test (#2…
fume4mattermost Jan 8, 2025
b74c219
MM-61926 Channel Conversion Text and add test (#29498)
sbishel Jan 8, 2025
22856b4
Update latest minor version to 10.5.0 (#29779)
unified-ci-app[bot] Jan 8, 2025
e6b4764
Fix: Playwright e2e tests (#29768)
yasserfaraazkhan Jan 8, 2025
baf9bf8
Bugfix - Enforce URL length check in LinkMetadata before attempting t…
NadavTasher Jan 8, 2025
4265df8
MM-62079: Fix permissions being reset properly (#29574)
agnivade Jan 8, 2025
e7c583f
MM-62371 Add additional error handling to PerformanceReporter (#29774)
hmhealey Jan 8, 2025
3a13dc2
MM-61411 - fix incorrect linking case sensitive issue (#29683)
pvev Jan 8, 2025
a3b2ece
[MM-61571]: Add label to form field in channel header (#29553)
SaurabhSharma-884 Jan 8, 2025
db3b72e
[MM-62381] Move LinkTooltip from Popper to Floating-UI (#29727)
M-ZubairAhmed Jan 9, 2025
e8beefd
Remove duplicate SAML login error message (#29767)
hanzei Jan 9, 2025
882654d
MM-62226 - set focus back to search button (#29669)
pvev Jan 9, 2025
0c213ea
Reduce number of IDE warnings in permissions_migrations.go (#29605)
enzowritescode Jan 9, 2025
95b22f4
MM-62426: Remove form-data from @mattermost/client (#29792)
saturninoabril Jan 10, 2025
93a5f0a
Merge branch 'master' into MM-61599
mattermost-build Jan 10, 2025
1a46932
[MA-27]: Remove unnecessary test
SaurabhSharma-884 Jan 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ describe('Verify Accessibility Support in Post', () => {
postMessages(testChannel, otherUser, 1);

// # Shift focus to the last post
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).type('{uparrow}{downarrow}');
cy.focused().tab();
cy.get('#FormattingControl_bold').focus().tab({shift: true}).tab({shift: true}).tab({shift: true}).tab({shift: true});

cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).within(() => {
Expand Down Expand Up @@ -199,9 +198,6 @@ describe('Verify Accessibility Support in Post', () => {
// * Verify focus is on the more button
cy.get(`#CENTER_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'more');
cy.focused().tab();

// * Verify focus is on the post text
cy.get(`#postMessageText_${postId}`).should('be.focused');
});
});
});
Expand Down Expand Up @@ -230,36 +226,32 @@ describe('Verify Accessibility Support in Post', () => {
// * Verify reverse tab on RHS
cy.getLastPostId().then((postId) => {
cy.get(`#rhsPost_${postId}`).within(() => {
// * Verify focus is on the post text
cy.get(`#rhsPostMessageText_${postId}`).should('be.focused');
cy.focused().tab({shift: true});

// * Verify focus is on the more button
cy.get(`#RHS_COMMENT_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'more');
// * Verify focus is on the time
cy.get(`#RHS_COMMENT_time_${postId}`).should('be.focused');
cy.focused().tab({shift: true});

// * Verify focus is on the actions button
cy.get(`#RHS_COMMENT_actions_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'actions');
cy.focused().tab({shift: true});
// * Verify focus is on the username
cy.get('button.user-popover').should('be.focused');
cy.focused().tab().tab();

// * Verify focus is on the save icon
cy.get(`#RHS_COMMENT_flagIcon_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'save message');
cy.focused().tab({shift: true});
// * Verify focus is on most recent action
cy.get('#recent_reaction_0').should('have.class', 'emoticon--post-menu').and('have.attr', 'aria-label');
cy.focused().tab();

// * Verify focus is on the reactions button
cy.get(`#RHS_COMMENT_reaction_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'Add Reaction');
cy.focused().tab({shift: true});
cy.focused().tab();

// * Verify focus is on most recent action
cy.get('#recent_reaction_0').should('have.class', 'emoticon--post-menu').and('have.attr', 'aria-label');
cy.focused().tab({shift: true});
// * Verify focus is on the save icon
cy.get(`#RHS_COMMENT_flagIcon_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'save message');
cy.focused().tab();

// * Verify focus is on the time
cy.get(`#RHS_COMMENT_time_${postId}`).should('be.focused');
cy.focused().tab({shift: true});
// * Verify focus is on the actions button
cy.get(`#RHS_COMMENT_actions_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'actions');
cy.focused().tab();

// * Verify focus is on the username
cy.get('button.user-popover').should('be.focused');
// * Verify focus is on the more button
cy.get(`#RHS_COMMENT_button_${postId}`).should('be.focused').and('have.attr', 'aria-label', 'more');
cy.focused().tab({shift: true});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ describe('Channel Settings - Channel Header', () => {
cy.findByText('Edit Channel Header').click();

// # Type something in the header edit box
cy.get('[aria-label="edit the channel header..."]').clear().type('This is the new header content');
cy.get('textarea[placeholder="Edit the Channel Header..."]').clear().type('This is the new header content');

// * Verify the "Preview" button exists
cy.findByText('Preview').should('be.visible');

// * Verify that before hitting the preview button, the style on the textbox is `display: block`
cy.get('[aria-label="edit the channel header..."]').should('have.css', 'display', 'block');
cy.get('textarea[placeholder="Edit the Channel Header..."]').should('have.css', 'display', 'block');

// # Click the "Preview" button
cy.findByText('Preview').click();
Expand All @@ -51,7 +51,7 @@ describe('Channel Settings - Channel Header', () => {
cy.findByText('Edit').should('be.visible');

// * Verify that the display is now none on the textbox element
cy.get('[aria-label="edit the channel header..."]').should('have.css', 'display', 'none');
cy.get('textarea[placeholder="Edit the Channel Header..."]').should('have.css', 'display', 'none');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe('Verify Accessibility Support in different input fields', () => {
cy.apiAddUserToTeam(testTeam.id, user.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, user.id).then(() => {
// * Verify Accessibility support in post input field
cy.uiGetPostTextBox().should('have.attr', 'aria-label', `write to ${testChannel.display_name}`).clear().focus();
cy.uiGetPostTextBox().should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`).clear().focus();

// # Ensure User list is cached once in UI
cy.uiGetPostTextBox().type('@').wait(TIMEOUTS.FIVE_SEC);
Expand Down Expand Up @@ -168,7 +168,7 @@ describe('Verify Accessibility Support in different input fields', () => {
it('MM-T1458 Verify Accessibility Support in Main Post Input', () => {
cy.get('#advancedTextEditorCell').within(() => {
// * Verify Accessibility Support in Main Post input
cy.uiGetPostTextBox().should('have.attr', 'aria-label', `write to ${testChannel.display_name}`).and('have.attr', 'role', 'textbox').clear().focus().type('test');
cy.uiGetPostTextBox().should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`).and('have.attr', 'role', 'textbox').clear().focus().type('test');

// # Set a11y focus on the textbox
cy.get('#FormattingControl_bold').focus().tab({shift: true});
Expand Down Expand Up @@ -231,7 +231,7 @@ describe('Verify Accessibility Support in different input fields', () => {

cy.get('#rhsContainer').within(() => {
// * Verify Accessibility Support in RHS input
cy.uiGetReplyTextBox().should('have.attr', 'aria-label', 'reply to this thread...').and('have.attr', 'role', 'textbox').focus().type('test').tab({shift: true}).tab().tab();
cy.uiGetReplyTextBox().should('have.attr', 'placeholder', 'Reply to this thread...').and('have.attr', 'role', 'textbox').focus().type('test').tab({shift: true}).tab().tab();

// * Verify if the focus is on the preview button
cy.get('#PreviewInputTextButton').should('be.focused').and('have.attr', 'aria-label', 'preview').tab();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {

// # Check Guest user should not have the permission to create a post on a channel when the option is removed
// * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('have.attr', 'placeholder', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled');

// # As a system admin, check the option to allow Create Posts for Guests and save
Expand All @@ -75,7 +75,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {
// # Check Guest user should have the permission to create a post on a channel when the option is allowed
// * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox').clear();
cy.findByTestId('post_textbox_placeholder').should('have.text', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('not.be.disabled');
});

Expand All @@ -92,7 +92,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {

// # Check Member should not have the permission to create a post on a channel when the option is removed.
// * User should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('have.attr', 'placeholder', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled');

// # As a system admin, check the option to allow Create Posts for Members and save
Expand All @@ -106,7 +106,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {
// # Check Member should have the permission to create a post on a channel when the option is allowed
// * Member user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox').clear();
cy.findByTestId('post_textbox_placeholder').should('have.text', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('not.be.disabled');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('Keyboard Shortcuts', () => {
// * Verify modal is open
cy.findByRole('dialog', {name: 'Edit Header for Off-Topic'}).within(() => {
// # Enter new header and save
cy.findByRole('textbox', {name: 'edit the channel header...'}).type(newHeader);
cy.findByRole('textbox', {name: 'Edit the text appearing next to the channel name in the header.'}).type(newHeader);
cy.uiSave();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,6 @@ describe('Channels', () => {
// * Verify the "Mark as Unread" option is absent in post menu
markAsUnreadShouldBeAbsent(post1.id);

// * Hover on the post with holding alt should show cursor
cy.get(`#post_${post1.id}`).trigger('mouseover').type('{alt}', {release: false}).should(notShowCursor);

// # Mouse click on the post holding alt
cy.get(`#post_${post1.id}`).type('{alt}', {release: false}).click();

// * Verify the post is not marked as unread
cy.get('.NotificationSeparator').should('not.exist');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ describe('Mark as Unread', () => {
// * Hover on the post with holding alt should show cursor
cy.get(`#post_${post2.id}`).trigger('mouseover').type('{alt}', {release: false}).should(showCursor);

// # Mouse click on the post holding alt
cy.get(`#post_${post2.id}`).type('{alt}', {release: false}).click();
// # Mouse click on the post
cy.get(`#post_${post2.id}`).click();

// * Verify the post is marked as unread
verifyPostNextToNewMessageSeparator('post2');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,15 @@ describe('Emoji reactions to posts/messages in GM channels', () => {
cy.findByLabelText('Add a reaction').should('not.be.visible');

// # Focus on the post since we can't hover with Cypress
cy.get(`#post_${postId}`).focus().tab().tab();
// cy.get(`#post_${postId}`).focus().tab().tab();

// * Verify that the Add Reaction button is now visible
cy.findByLabelText('Add a reaction').should('be.visible');
cy.get(`#post_${postId}`).within(() => {
// * Verify focus is on profile image
cy.get('.status-wrapper button').focus().tab();

// * Verify that the Add Reaction button is now visible
cy.findByLabelText('Add a reaction').should('be.visible');
});

// # Click somewhere to clear the focus
cy.get('#channelIntro').click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,20 @@ describe('Link tooltips', () => {
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
cy.visit(`/${team.name}/channels/${channel.name}`);
});
cy.postMessage('www.test.com');
});

it('MM-T3422 fade in and out with an animation', () => {
cy.get('a[href*="www.test.com"] span').as('link');
cy.contains('This is a custom tooltip from the Demo Plugin').parents('.tooltip-container').as('tooltip-container');
const url = 'www.test.com';
cy.postMessage(url);
cy.uiWaitUntilMessagePostedIncludes(url);

// # Mouse over the link
cy.get('@link').trigger('mouseover');
// # Hover over the plugin link
cy.findByText(url).should('exist').focus();

// * Check tooltip has appeared
cy.get('@tooltip-container').should('have.class', 'visible');
cy.findByText('This is a custom tooltip from the Demo Plugin').should('be.visible');

// # Mouse out the link
cy.get('@link').trigger('mouseout');

// * Check tooltip has disappeared
cy.get('@tooltip-container').should('not.have.class', 'visible');
// # Close the tooltip
cy.get('body').type('{esc}');
});
});
17 changes: 16 additions & 1 deletion e2e-tests/playwright/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion e2e-tests/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"dotenv": "16.4.5",
"form-data-encoder": "4.0.2",
"formdata-node": "6.0.3",
"uuid": "11.0.3"
"uuid": "11.0.3",
"zod": "3.24.1"
},
"devDependencies": {
"@types/uuid": "10.0.0",
Expand Down
65 changes: 65 additions & 0 deletions e2e-tests/playwright/support/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import path from 'node:path';
import fs from 'node:fs';

const assetPath = path.resolve(__dirname, 'asset');

/**
* Reads file data and creates a File object.
* @param filePath - The path to the file.
* @param mimeType - The MIME type of the file.
* @returns A File object containing the file data.
* @throws If the file does not exist.
*/
export function getFileData(filePath: string, mimeType: string): File {
if (!fs.existsSync(filePath)) {
throw new Error(`File not found at path: ${filePath}`);
}

const fileName = path.basename(filePath);
const fileBuffer = fs.readFileSync(filePath);

return new File([fileBuffer], fileName, {type: mimeType});
}

/**
* Reads file data from the "asset" directory and creates a File object.
* @param filename - The name of the file in the "asset" directory.
* @param mimeType - The MIME type of the file.
* @returns An object containing a File object and the filename.
*/
export function getFileDataFromAsset(filename: string, mimeType: string) {
const filePath = path.join(assetPath, filename);

return {file: getFileData(filePath, mimeType), filename: path.basename(filePath)};
}

/**
* Reads file data and creates a Blob object.
* @param filePath - The path to the file.
* @param mimeType - The MIME type of the file.
* @returns A Blob object containing the file data.
* @throws If the file does not exist.
*/
export function getBlobData(filePath: string, mimeType: string): Blob {
if (!fs.existsSync(filePath)) {
throw new Error(`File not found at path: ${filePath}`);
}
const fileBuffer = fs.readFileSync(filePath);

return new Blob([fileBuffer], {type: mimeType});
}

/**
* Reads file data from the "asset" directory and creates a Blob object.
* @param filename - The name of the file in the "asset" directory.
* @param mimeType - The MIME type of the file.
* @returns An object containing a Blob object and the filename.
*/
export function getBlobDataFromAsset(filename: string, mimeType: string) {
const filePath = path.join(assetPath, filename);

return {blob: getBlobData(filePath, mimeType), filename: path.basename(filePath)};
}
7 changes: 3 additions & 4 deletions e2e-tests/playwright/support/server/init.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import path from 'node:path';
import {expect} from '@playwright/test';

import {PreferenceType} from '@mattermost/types/preferences';
import testConfig from '@e2e-test.config';
import {getFileDataFromAsset} from '@e2e-support/file';

import {makeClient} from '.';
import {getOnPremServerConfig} from './default_config';
Expand Down Expand Up @@ -42,9 +42,8 @@ export async function initSetup({
const {client: userClient} = await makeClient(user);

if (withDefaultProfileImage) {
// Set user profile image
const fullPath = path.join(path.resolve(__dirname), '../', 'asset/mattermost-icon_128x128.png');
await userClient.uploadProfileImageX(user.id, fullPath);
const {file} = getFileDataFromAsset('mattermost-icon_128x128.png', 'image/png');
await userClient.uploadProfileImage(user.id, file);
}

// Update user preference
Expand Down
Loading
Loading