MM-63820 chore(e2e): update dependencies and docs (#30807)

* chore(e2e): update dependencies and docs

* update the use of postMessage, expose 8065 on test server and fix flakiness on profile popover
Этот коммит содержится в:
Saturn Abril
2025-04-22 02:02:55 +08:00
коммит произвёл GitHub
родитель de46d798e4
Коммит d631974e88
21 изменённых файлов: 587 добавлений и 485 удалений

Просмотреть файл

@@ -65,6 +65,8 @@ services:
MM_LOGSETTINGS_ENABLEDIAGNOSTICS: "false"
MM_LOGSETTINGS_CONSOLELEVEL: "DEBUG"
network_mode: host
ports:
- "8065:8065"
depends_on:
$(for service in $ENABLED_DOCKER_SERVICES; do
# The server container will start only if all other dependent services are healthy
@@ -277,7 +279,7 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
echo '
playwright:
image: mcr.microsoft.com/playwright:v1.51.1-noble
image: mcr.microsoft.com/playwright:v1.52.0-noble
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:

Просмотреть файл

@@ -2,20 +2,47 @@
#### 1. Start local server in a separate terminal.
```
There are two ways to run the local server:
**Option 1: Run from source**
```bash
# Typically run the local server with:
cd server && make run
# Or build and distribute webapp including channels and playbooks
# so that their product URLs do not rely on Webpack dev server.
# Especially important when running tests inside the Playwright's docker container.
cd webapp && make dist
# Or run webapp and server on separate terminals for better performance
# First terminal: Build and run the webapp
cd webapp && make run
# Second terminal: Run the server
cd server && make run-server
```
**Option 2: Run using Docker (recommended for testing)**
```bash
# 1. Configure environment variables in e2e-tests/.ci/env
# Create this file if it doesn't exist
# 2. Set the server image (optional)
# To use the latest master image:
SERVER_IMAGE="mattermostdevelopment/mattermost-enterprise-edition:master"
# If not set, it will use the current commit: mattermostdevelopment/mattermost-enterprise-edition:$(git rev-parse --short=7 HEAD)
# Note: The image must exist in Docker Hub at https://hub.docker.com/r/mattermostdevelopment/mattermost-enterprise-edition/tags
# 3. Add your license if needed
MM_LICENSE=<your-license-key>
# 4. For additional configuration options, see e2e-tests/README.md
# 5. Run the server and Playwright's smoke tests from the e2e-tests directory
cd e2e-tests && TEST=playwright make
```
This approach uses the server's Docker image to create a consistent testing environment. It automatically configures the server with the necessary settings for Playwright tests and handles dependencies.
#### 2. Install dependencies and run the test.
```
```bash
# Install npm packages
npm i
@@ -36,19 +63,36 @@ npm run test
#### 3. Inspect test results at `/results/output` folder when something fails unexpectedly.
## Run tests in UI mode
Check out https://playwright.dev/docs/test-ui-mode for detailed guide on UI Mode to learn more about its features.
```bash
npm run playwright-ui
```
> **Note:** If no tests appear in the UI, check your filter settings:
>
> - Test name filters
> - Project filters (setup, ipad, chrome, firefox)
> - Tag filters (@tag)
> - Execution status filters
>
> The "setup" project runs the initial configuration tests in `specs/test_setup.ts` (ensuring plugins are loaded and server deployment is correct). These setup tests are typically run only once before other tests and may be unchecked for subsequent runs, though they can remain checked if needed.
## Updating screenshots is done strictly via Playwright's docker container for consistency
#### 1. Run docker container using latest focal version
#### 1. Run Playwright's docker container
Change to the `e2e-tests/playwright` directory, then run the docker container. (See https://playwright.dev/docs/docker for reference.)
```
docker run -it --rm -v "$(pwd):/mattermost/" --ipc=host mcr.microsoft.com/playwright:v1.51.1-noble /bin/bash
```bash
docker run -it --rm -v "$(pwd):/mattermost/" --ipc=host mcr.microsoft.com/playwright:v1.52.0-noble /bin/bash
```
#### 2. Inside the docker container
```
```bash
export PW_BASE_URL=http://host.docker.internal:8065
export PW_HEADLESS=true
cd mattermost/e2e-tests/playwright

Просмотреть файл

@@ -45,24 +45,24 @@
"@axe-core/playwright": "4.10.1",
"@mattermost/client": "file:../../../webapp/platform/client",
"@mattermost/types": "file:../../../webapp/platform/types",
"@percy/cli": "1.30.9",
"@percy/playwright": "1.0.7",
"@percy/cli": "1.30.10",
"@percy/playwright": "1.0.8",
"async-wait-until": "2.0.27",
"axe-core": "4.10.3",
"deepmerge": "4.3.1",
"dotenv": "16.4.7",
"dotenv": "16.5.0",
"mime-types": "3.0.1",
"uuid": "11.1.0"
},
"devDependencies": {
"@rollup/plugin-typescript": "12.1.2",
"@types/mime-types": "2.1.4",
"@types/node": "22.14.0",
"@types/react": "19.1.0",
"rollup": "4.39.0",
"@types/node": "22.14.1",
"@types/react": "19.1.2",
"rollup": "4.40.0",
"rollup-plugin-copy": "3.5.0"
},
"peerDependencies": {
"@playwright/test": "1.51.1"
"@playwright/test": "1.52.0"
}
}

Просмотреть файл

@@ -94,11 +94,20 @@ async function printClientInfo(client: Client4) {
- TelemetryId = ${config.TelemetryId}
- ServiceEnvironment = ${config.ServiceEnvironment}`);
const {LogSettings, ServiceSettings} = await client.getConfig();
const {LogSettings, ServiceSettings, FeatureFlags} = await client.getConfig();
// eslint-disable-next-line no-console
console.log(`Notable Server Config:
- ServiceSettings.EnableSecurityFixAlert = ${ServiceSettings?.EnableSecurityFixAlert}
- LogSettings.EnableDiagnostics = ${LogSettings?.EnableDiagnostics}`);
// eslint-disable-next-line no-console
console.log('Feature Flags:');
// eslint-disable-next-line no-console
console.log(
Object.entries(FeatureFlags)
.map(([key, value]) => ` - ${key} = ${value}`)
.join('\n'),
);
}
async function printPluginDetails(client: Client4) {

Просмотреть файл

@@ -277,6 +277,7 @@ const defaultServerConfig: AdminConfig = {
FileCompress: false,
FileMaxQueueSize: 1000,
AdvancedLoggingJSON: {},
Certificate: '',
},
NotificationLogSettings: {
EnableConsole: true,
@@ -783,4 +784,8 @@ const defaultServerConfig: AdminConfig = {
DisableSharedChannelsStatusSync: false,
MaxPostsPerSync: 50,
},
AccessControlSettings: {
EnableAttributeBasedAccessControl: false,
EnableChannelScopeAccessControl: false,
},
};

Просмотреть файл

@@ -50,6 +50,10 @@ export default class ChannelsCenterView {
await this.postCreate.toBeVisible();
}
async postMessage(message: string, files?: string[]) {
await this.postCreate.postMessage(message, files);
}
/**
* Click on "See all scheduled messages"
*/

Просмотреть файл

@@ -45,6 +45,10 @@ export default class ChannelsSidebarRight {
await expect(this.container).toBeVisible();
}
async postMessage(message: string) {
await this.postCreate.postMessage(message);
}
/**
* Returns the RHS post by post id
* @param postId Just the ID without the prefix

Просмотреть файл

@@ -3,7 +3,7 @@
import {expect, Page} from '@playwright/test';
import {components} from '@/ui/components';
import {ChannelsPost, components} from '@/ui/components';
export default class ChannelsPage {
readonly channels = 'Channels';
@@ -89,9 +89,10 @@ export default class ChannelsPage {
/**
* `postMessage` posts a message in the current channel
* @param message Message to post
* @param files Files to attach to the message
*/
async postMessage(message: string) {
await this.centerView.postCreate.postMessage(message);
async postMessage(message: string, files?: string[]) {
await this.centerView.postMessage(message, files);
}
async openUserAccountMenu() {
@@ -106,4 +107,16 @@ export default class ChannelsPage {
await expect(this.profileModal.container).toBeVisible();
return this.profileModal;
}
async openProfilePopover(post: ChannelsPost) {
// Find and click the post's user avatar to open the profile popover
await post.hover();
await post.profileIcon.click();
// Wait for the profile popover to be visible
const popover = this.userProfilePopover;
await expect(popover.container).toBeVisible();
return popover;
}
}

756
e2e-tests/playwright/package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@@ -24,15 +24,15 @@
"@mattermost/client": "file:../../webapp/platform/client",
"@mattermost/playwright-lib": "*",
"@mattermost/types": "file:../../webapp/platform/types",
"@playwright/test": "1.51.1",
"@playwright/test": "1.52.0",
"cross-env": "7.0.3",
"dayjs": "1.11.13",
"zod": "3.24.2"
"zod": "3.24.3"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "8.29.0",
"eslint": "9.24.0",
"eslint-import-resolver-typescript": "4.3.2",
"@typescript-eslint/eslint-plugin": "8.30.1",
"eslint": "9.25.0",
"eslint-import-resolver-typescript": "4.3.3",
"eslint-plugin-header": "3.1.1",
"eslint-plugin-import": "2.31.0",
"prettier": "3.5.3",

Просмотреть файл

@@ -13,7 +13,7 @@ test.fixme('Base channel accessibility', async ({pw, axe}) => {
// # Visit a default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('hello');
await channelsPage.postMessage('hello');
// # Analyze the page
// Disable 'color-contrast' to be addressed by MM-53814
@@ -35,7 +35,7 @@ test('Post actions tab support', async ({pw, axe}) => {
// # Visit a default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('hello');
await channelsPage.postMessage('hello');
const post = await channelsPage.getLastPost();
await post.hover();

Просмотреть файл

@@ -3,10 +3,17 @@
import {expect, test} from '@mattermost/playwright-lib';
test('MM-T53377 Profile popover should show correct fields after at-mention autocomplete', async ({pw}) => {
// # Initialize with specific config and get admin client
/**
* Verify that profile popover shows correct user information based on privacy settings
* and continues to show correct information after at-mention autocomplete is used.
*
* Precondition:
* 1. A test server configured with privacy settings to hide email and full name
* 2. Two user accounts, with one user able to see their own information
*/
test('Profile popover should show correct fields after at-mention autocomplete @user_profile', async ({pw}) => {
// Initialize with user's privacy settings set to hide email and full name
const {user, adminClient, team} = await pw.initSetup();
await adminClient.patchConfig({
PrivacySettings: {
ShowEmailAddress: false,
@@ -14,59 +21,59 @@ test('MM-T53377 Profile popover should show correct fields after at-mention auto
},
});
// # Create and add another user using admin client
// Create and add another user using admin client
const testUser2 = await adminClient.createUser(pw.random.user(), '', '');
await adminClient.addToTeam(team.id, testUser2.id);
// # Log in as user in new browser context
// 1. Login as the first user
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Send mentions quickly
await channelsPage.centerView.postCreate.postMessage(`@${user.username} @${testUser2.username}`);
// 2. Post a message with mentions of both users
await channelsPage.postMessage(`@${user.username} @${testUser2.username}`);
// # Open profile popover for current user
const firstMention = channelsPage.centerView.container.getByText(`@${user.username}`, {exact: true});
// 3. Open profile popover for the current user on first
const lastPost = await channelsPage.getLastPost();
const firstMention = await lastPost.container.getByText(`@${user.username}`, {exact: true});
await firstMention.click();
const currentUserProfilePopover = channelsPage.userProfilePopover;
// * Verify all fields are visible for current user
const popover = channelsPage.userProfilePopover;
await expect(popover.container.getByText(`@${user.username}`)).toBeVisible();
await expect(popover.container.getByText(`${user.first_name} ${user.last_name}`)).toBeVisible();
await expect(popover.container.getByText(user.email)).toBeVisible();
// * Verify all fields are visible for current user in the profile popover
await expect(currentUserProfilePopover.container.getByText(`@${user.username}`)).toBeVisible(); // TODO: Fix this
await expect(currentUserProfilePopover.container.getByText(`${user.first_name} ${user.last_name}`)).toBeVisible();
await expect(currentUserProfilePopover.container.getByText(user.email)).toBeVisible();
// # Close profile popover
await popover.close();
// 4. Close the current user's profile popover
await currentUserProfilePopover.close();
// # Open profile popover for other user
const secondMention = channelsPage.centerView.container.getByText(`@${testUser2.username}`, {exact: true});
// 5. Open profile popover for the other user on second mention
const secondMention = await lastPost.container.getByText(`@${testUser2.username}`, {exact: true});
await secondMention.click();
const otherUserProfilePopover = channelsPage.userProfilePopover;
// * Verify only username is visible for other user
await expect(popover.container.getByText(`@${testUser2.username}`)).toBeVisible();
await expect(popover.container.getByText(testUser2.email)).not.toBeVisible();
// * Verify only username is visible for other user in the profile popover
await expect(otherUserProfilePopover.container.getByText(`@${testUser2.username}`)).toBeVisible();
await expect(otherUserProfilePopover.container.getByText(testUser2.email)).not.toBeVisible(); // TODO: Fix this
// # Close profile popover
await popover.close();
// 6. Close the other user's profile popover
await otherUserProfilePopover.close();
// # Trigger autocomplete
// 7. Start typing an at-mention to trigger autocomplete suggestion
await channelsPage.centerView.postCreate.writeMessage(`@${user.username}`);
// # Wait for autocomplete
// * Verify autocomplete suggestion appears
const suggestionList = channelsPage.centerView.postCreate.suggestionList;
await expect(suggestionList.getByText(`@${user.username}`)).toBeVisible();
// # Clear textbox
// 8. Clear the message box
await channelsPage.centerView.postCreate.writeMessage('');
// # Open profile popover for current user again
await firstMention.click();
// 9. Open profile popover for the current user again
const profilePopoverAgain = await channelsPage.openProfilePopover(lastPost);
// * Verify all fields are still visible
await expect(popover.container.getByText(`@${user.username}`)).toBeVisible();
await expect(popover.container.getByText(`${user.first_name} ${user.last_name}`)).toBeVisible();
await expect(popover.container.getByText(user.email)).toBeVisible();
await expect(profilePopoverAgain.container.getByText(`@${user.username}`)).toBeVisible();
await expect(profilePopoverAgain.container.getByText(`${user.first_name} ${user.last_name}`)).toBeVisible();
await expect(profilePopoverAgain.container.getByText(user.email)).toBeVisible();
});

Просмотреть файл

@@ -16,7 +16,6 @@ import {
deleteCustomProfileAttributes,
verifyAttributeInPopover,
verifyAttributeNotInPopover,
openProfilePopover,
updateCustomProfileAttributeVisibility,
TEST_PHONE,
TEST_URL,
@@ -129,7 +128,8 @@ test('MM-T5773 Display custom profile attributes in profile popover @custom_prof
await channelsPage.postMessage(TEST_MESSAGE);
// 3. Open the profile popover for the user's post
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify each custom attribute is displayed correctly
for (const attribute of customAttributes) {
@@ -158,7 +158,8 @@ test('MM-T5774 Do not display custom profile attributes if none exist @custom_pr
await channelsPage.postMessage(TEST_MESSAGE);
// 3. Open the profile popover for the user's post
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify custom attributes are not displayed
for (const attribute of customAttributes) {
@@ -185,7 +186,8 @@ test('MM-T5775 Update custom profile attributes when changed @custom_profile_att
await channelsPage.postMessage(TEST_MESSAGE);
// 3. Open the profile popover for the user's post
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify each custom attribute is displayed correctly
for (const attribute of customAttributes) {
@@ -213,7 +215,7 @@ test('MM-T5775 Update custom profile attributes when changed @custom_profile_att
await setupCustomProfileAttributeValues(userClient, updatedAttributes, attributeFieldsMap);
// 6. Open the profile popover again
await openProfilePopover(channelsPage);
await channelsPage.openProfilePopover(lastPost);
// * Verify updated attributes are displayed correctly
for (const attribute of updatedAttributes) {
@@ -250,7 +252,8 @@ test('MM-T5776 Hide custom profile attributes when visibility is set to hidden @
await channelsPage.postMessage(TEST_MESSAGE);
// 4. Open the profile popover for the user's post
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify the Department attribute is not displayed
await verifyAttributeNotInPopover(channelsPage, 'Department');
@@ -283,7 +286,8 @@ test('MM-T5777 Always display custom profile attributes with visibility set to a
await channelsPage.postMessage(TEST_MESSAGE);
// 4. Open the profile popover for the user's post
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify custom attributes are displayed correctly
for (const attribute of customAttributes) {
@@ -319,7 +323,8 @@ test('MM-T5778 Display phone and URL type custom profile attributes correctly @c
await channelsPage.postMessage(TEST_MESSAGE);
// 3. Open the profile popover for the other user
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify the Phone attribute is displayed correctly
await verifyAttributeInPopover(channelsPage, 'Phone', TEST_PHONE);
@@ -349,7 +354,8 @@ test('MM-T5779 Verify phone and URL attributes are clickable in profile popover
await channelsPage.postMessage(TEST_MESSAGE);
// 3. Open the profile popover for the other user
await openProfilePopover(channelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Verify the Phone attribute has a clickable link with tel: protocol
const popover = channelsPage.userProfilePopover.container;

Просмотреть файл

@@ -213,21 +213,6 @@ export async function editMultiselectAttribute(
await page.waitForTimeout(500); // Wait for save to complete
}
/**
* Helper function to open the profile popover for the test user
* @param {ChannelsPage} channelsPage - The Playwright channels page object
*/
export async function openProfilePopover(channelsPage: ChannelsPage): Promise<void> {
// Find and click the last post's user avatar to open the profile popover
const lastPost = await channelsPage.getLastPost();
await lastPost.hover();
await lastPost.profileIcon.click();
// Wait for the profile popover to be visible
const popover = channelsPage.userProfilePopover;
await expect(popover.container).toBeVisible();
}
/**
* Helper function to verify an attribute exists in the profile settings
* @param {Page} page - The Playwright page object

Просмотреть файл

@@ -17,7 +17,6 @@ import {
verifyAttributesExistInSettings,
verifyAttributeInPopover,
verifyAttributeNotInPopover,
openProfilePopover,
editTextAttribute,
editSelectAttribute,
editMultiselectAttribute,
@@ -171,7 +170,8 @@ test('MM-T5768 Editing Custom Profile Attributes @custom_profile_attributes', as
await otherChannelsPage.goto();
// 9. View the test user's profile popover
await openProfilePopover(otherChannelsPage);
const lastPost = await otherChannelsPage.getLastPost();
await otherChannelsPage.openProfilePopover(lastPost);
// * Profile popover shows updated custom attributes
await verifyAttributeInPopover(otherChannelsPage, 'Department', TEST_UPDATED_DEPARTMENT);
@@ -220,7 +220,8 @@ test('MM-T5769 Clearing Custom Profile Attributes @custom_profile_attributes', a
await otherChannelsPage.goto();
// 7. View the test user's profile popover
await openProfilePopover(otherChannelsPage);
const lastPost = await channelsPage.getLastPost();
await channelsPage.openProfilePopover(lastPost);
// * Department attribute is not displayed in the profile popover
await verifyAttributeNotInPopover(otherChannelsPage, 'Department');
@@ -311,7 +312,8 @@ test('MM-T5771 Editing Phone and URL Type Custom Profile Attributes @custom_prof
await otherChannelsPage.goto();
// 8. View the test user's profile popover
await openProfilePopover(otherChannelsPage);
const lastPost = await otherChannelsPage.getLastPost();
await otherChannelsPage.openProfilePopover(lastPost);
// * Profile popover shows updated attributes
await verifyAttributeInPopover(otherChannelsPage, 'Phone', TEST_UPDATED_PHONE);

Просмотреть файл

@@ -41,7 +41,7 @@ test('MM-T5435_1 Global Drafts link in sidebar should be hidden when another use
// # Post a message as a user
const sidebarRight = channelsPage.sidebarRight;
await sidebarRight.toBeVisible();
await sidebarRight.postCreate.postMessage('Replying to a thread');
await sidebarRight.postMessage('Replying to a thread');
// # Write a message in the reply thread but don't send it now so that it becomes a draft
const draftMessageByUser = 'I should be in drafts by User';
@@ -86,7 +86,7 @@ test('MM-T5435_2 Global Drafts link in sidebar should be hidden when user delete
await channelsPage.toBeVisible();
// # Post a message in the channel
await channelsPage.centerView.postCreate.postMessage('Message which will be deleted');
await channelsPage.postMessage('Message which will be deleted');
// # Start a thread by clicking on reply menuitem from post options menu
const post = await channelsPage.getLastPost();
@@ -98,7 +98,7 @@ test('MM-T5435_2 Global Drafts link in sidebar should be hidden when user delete
await sidebarRight.toBeVisible();
// # Post a message in the thread
await sidebarRight.postCreate.postMessage('Replying to a thread');
await sidebarRight.postMessage('Replying to a thread');
// # Write a message in the reply thread but don't send it
await sidebarRight.postCreate.writeMessage('I should be in drafts');

Просмотреть файл

@@ -13,7 +13,7 @@ test('MM-T5654_1 should be able to add attachments while editing a post', async
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage);
await channelsPage.postMessage(originalMessage);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -41,7 +41,7 @@ test('MM-T5654_2 should be able to add attachments while editing a threaded post
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage);
await channelsPage.postMessage(originalMessage);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -54,7 +54,7 @@ test('MM-T5654_2 should be able to add attachments while editing a threaded post
await channelsPage.postDotMenu.replyMenuItem.click();
await channelsPage.sidebarRight.toBeVisible();
await channelsPage.sidebarRight.postCreate.toBeVisible();
await channelsPage.sidebarRight.postCreate.postMessage('Replying to the post');
await channelsPage.sidebarRight.postMessage('Replying to the post');
await channelsPage.sidebarRight.toContainText('Replying to the post');
const replyPost = await channelsPage.sidebarRight.getLastPost();
@@ -119,7 +119,7 @@ test('MM-T5654_3 should be able to edit post message originally containing files
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage, ['sample_text_file.txt']);
await channelsPage.postMessage(originalMessage, ['sample_text_file.txt']);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -147,7 +147,7 @@ test('MM-T5654_4 should be able to add files when editing a post', async ({pw})
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage);
await channelsPage.postMessage(originalMessage);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -192,11 +192,7 @@ test('MM-5654_5 should be able to remove attachments while editing a post', asyn
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage, [
'sample_text_file.txt',
'mattermost.png',
'archive.zip',
]);
await channelsPage.postMessage(originalMessage, ['sample_text_file.txt', 'mattermost.png', 'archive.zip']);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -232,7 +228,7 @@ test('MM-T5655_1 removing message content and files should delete the post', asy
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage, ['sample_text_file.txt']);
await channelsPage.postMessage(originalMessage, ['sample_text_file.txt']);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -266,11 +262,7 @@ test('MM-T5655_2 should be able to remove all files when editing a post', async
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage, [
'sample_text_file.txt',
'mattermost.png',
'archive.zip',
]);
await channelsPage.postMessage(originalMessage, ['sample_text_file.txt', 'mattermost.png', 'archive.zip']);
const post = await channelsPage.getLastPost();
await post.toBeVisible();
@@ -309,7 +301,7 @@ test('MM-T5656_1 should be able to restore previously edited post version that c
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage(originalMessage, ['sample_text_file.txt']);
await channelsPage.postMessage(originalMessage, ['sample_text_file.txt']);
const post = await channelsPage.getLastPost();
await post.toBeVisible();

Просмотреть файл

@@ -53,7 +53,7 @@ test.fixme(
await channelsPage.toBeVisible();
// # Send a message
await channelsPage.centerView.postCreate.postMessage('Message to open RHS');
await channelsPage.postMessage('Message to open RHS');
// # Open the last post sent in RHS
const lastPost = await channelsPage.getLastPost();

Просмотреть файл

@@ -53,7 +53,7 @@ test('MM-T5643_6 should create a scheduled message under a thread post ', async
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('Root Message');
await channelsPage.postMessage('Root Message');
// # Start a thread by clicking on reply menuitem from post options menu
const post = await channelsPage.getLastPost();
@@ -63,7 +63,7 @@ test('MM-T5643_6 should create a scheduled message under a thread post ', async
await sidebarRight.toBeVisible();
// # Post a message in the thread
await sidebarRight.postCreate.postMessage('Replying to a thread');
await sidebarRight.postMessage('Replying to a thread');
// # Write a message in the reply thread but don't send it
await sidebarRight.postCreate.writeMessage(draftMessage);

Просмотреть файл

@@ -23,7 +23,7 @@ test('MM-T5465-1 Should add the keyword when enter, comma or tab is pressed on t
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('Hello World');
await channelsPage.postMessage('Hello World');
// # Open settings modal
const settingsModal = await channelsPage.globalHeader.openSettings();
@@ -97,7 +97,7 @@ test('MM-T5465-2 Should highlight the keywords when a message is sent with the k
// # Post a message without the keyword
const messageWithoutKeyword = 'This message does not contain the keyword';
await channelsPage.centerView.postCreate.postMessage(messageWithoutKeyword);
await channelsPage.postMessage(messageWithoutKeyword);
const lastPostWithoutHighlight = await channelsPage.getLastPost();
// * Verify that the keywords are not highlighted
@@ -108,7 +108,7 @@ test('MM-T5465-2 Should highlight the keywords when a message is sent with the k
// # Post a message with the keyword
const messageWithKeyword = `This message contains the keyword ${keywords[3]}`;
await channelsPage.centerView.postCreate.postMessage(messageWithKeyword);
await channelsPage.postMessage(messageWithKeyword);
const lastPostWithHighlight = await channelsPage.getLastPost();
// * Verify that the keywords are highlighted
@@ -151,7 +151,7 @@ test('MM-T5465-3 Should highlight the keywords when a message is sent with the k
// # Post a message without the keyword
const messageWithoutKeyword = 'This message does not contain the keyword';
await channelsPage.centerView.postCreate.postMessage(messageWithoutKeyword);
await channelsPage.postMessage(messageWithoutKeyword);
const lastPostWithoutHighlight = await channelsPage.getLastPost();
// # Open the message in the RHS
@@ -162,7 +162,7 @@ test('MM-T5465-3 Should highlight the keywords when a message is sent with the k
// # Post a message with the keyword in the RHS
const messageWithKeyword = `This message contains the keyword ${keywords[3]}`;
await channelsPage.sidebarRight.postCreate.postMessage(messageWithKeyword);
await channelsPage.sidebarRight.postMessage(messageWithKeyword);
// * Verify that the keywords are highlighted
const lastPostWithHighlightInRHS = await channelsPage.sidebarRight.getLastPost();

Просмотреть файл

@@ -484,6 +484,7 @@ export type ExperimentalAuditSettings = {
FileCompress: boolean;
FileMaxQueueSize: number;
AdvancedLoggingJSON: Record<string, any>;
Certificate: string;
};
export type NotificationLogSettings = {
@@ -966,6 +967,11 @@ export type ExportSettings = {
RetentionDays: number;
};
export type AccessControlSettings = {
EnableAttributeBasedAccessControl: boolean;
EnableChannelScopeAccessControl: boolean;
};
export type AdminConfig = {
ServiceSettings: ServiceSettings;
TeamSettings: TeamSettings;
@@ -1011,6 +1017,7 @@ export type AdminConfig = {
ExportSettings: ExportSettings;
WranglerSettings: WranglerSettings;
ConnectedWorkspacesSettings: ConnectedWorkspacesSettings;
AccessControlSettings: AccessControlSettings;
};
export type ReplicaLagSetting = {