MM-64282 E2E/Playwright: Test documentation format (#31050)

* initial implementation of test documentation in spec file with AI-assisted prompt from Claude and linter script

* update snapshots

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
sabril
2025-05-20 01:07:47 +08:00
коммит произвёл GitHub
родитель a358401772
Коммит 2116a6d94a
18 изменённых файлов: 1721 добавлений и 487 удалений

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

@@ -3,91 +3,106 @@
import {expect, test} from '@mattermost/playwright-lib';
/**
* @objective Verify that users can search for GIFs, select them, and post them correctly when using the center textbox.
*/
test.fixme(
'MM-T5445 Should search, select and post correct Gif when Gif picker is opened from center textbox',
'MM-T5445 searches for GIF from center textbox and posts selected GIF correctly',
{tag: '@gif_picker'},
async ({pw}) => {
// # Initialize a test user
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
// # Navigate to default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open emoji/gif picker
// # Open emoji/gif picker from center textbox
await channelsPage.centerView.postCreate.openEmojiPicker();
// * Verify emoji/gif picker popup appears
await channelsPage.emojiGifPickerPopup.toBeVisible();
// # Open gif tab
// # Switch to GIF tab in the picker
await channelsPage.emojiGifPickerPopup.openGifTab();
// # Search for gif
// # Search for GIFs using the term "hello"
await channelsPage.emojiGifPickerPopup.searchGif('hello');
// # Select the first gif
// # Select the first GIF from search results
const {img: firstSearchGifResult, alt: altOfFirstSearchGifResult} =
await channelsPage.emojiGifPickerPopup.getNthGif(0);
await firstSearchGifResult.click();
// # Send the selected gif as a message
// # Send the selected GIF as a message
await channelsPage.centerView.postCreate.sendMessage();
// * Verify that last message has the gif
// * Verify the posted message contains the selected GIF
const lastPost = await channelsPage.getLastPost();
await lastPost.toBeVisible();
await expect(lastPost.body.getByLabel('file thumbnail')).toHaveAttribute('alt', altOfFirstSearchGifResult);
},
);
/**
* @objective Verify that users can search for GIFs, select them, and post them correctly when using the right-hand sidebar.
*/
test.fixme(
'MM-T5446 Should search, select and post correct Gif when Gif picker is opened from RHS textbox',
'MM-T5446 searches for GIF from RHS textbox and posts selected GIF correctly in thread',
{tag: '@gif_picker'},
async ({pw}) => {
// # Initialize a test user
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
// # Navigate to default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Send a message
// # Post a message to create a thread
await channelsPage.postMessage('Message to open RHS');
// # Open the last post sent in RHS
// # Open the message in right-hand sidebar to start a thread
const lastPost = await channelsPage.getLastPost();
await lastPost.hover();
await lastPost.postMenu.toBeVisible();
await lastPost.postMenu.reply();
// * Verify right sidebar opens and is visible
const sidebarRight = channelsPage.sidebarRight;
await sidebarRight.toBeVisible();
// # Send a message in the thread
// # Post an initial reply in the thread
await sidebarRight.postCreate.toBeVisible();
await sidebarRight.postCreate.writeMessage('Replying to a thread');
await sidebarRight.postCreate.sendMessage();
// # Open emoji/gif picker
// # Open emoji/gif picker from the RHS textbox
await sidebarRight.postCreate.openEmojiPicker();
// * Verify emoji/gif picker popup appears
await channelsPage.emojiGifPickerPopup.toBeVisible();
// # Open gif tab
// # Switch to GIF tab in the picker
await channelsPage.emojiGifPickerPopup.openGifTab();
// # Search for gif
// # Search for GIFs using the term "hello"
await channelsPage.emojiGifPickerPopup.searchGif('hello');
// # Select the first gif
// # Select the first GIF from search results
const {img: firstSearchGifResult, alt: altOfFirstSearchGifResult} =
await channelsPage.emojiGifPickerPopup.getNthGif(0);
await firstSearchGifResult.click();
// # Send the selected gif as a message in the thread
// # Send the selected GIF as a message in the thread
await sidebarRight.postCreate.sendMessage();
// * Verify that last message has the gif
// * Verify the posted message in the thread contains the selected GIF
const lastPostInRHS = await sidebarRight.getLastPost();
await lastPostInRHS.toBeVisible();
await expect(lastPostInRHS.body.getByLabel('file thumbnail')).toHaveAttribute('alt', altOfFirstSearchGifResult);

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

@@ -3,9 +3,17 @@
import {expect, test} from '@mattermost/playwright-lib';
test('Multiple user mentions test', async ({pw}) => {
/**
* @objective Verify that multiple user mentions are displayed properly in the Recent Mentions section.
*
* @precondition
* Two users must be members of the same team
*/
test('displays multiple mentions correctly in Recent Mentions panel', {tag: '@mentions'}, async ({pw}) => {
// # Define the number of mentions to create
const MENTION_COUNT = 20;
// # Initialize the first user who will create the mentions
const {
team,
user: mentioningUser,
@@ -19,9 +27,10 @@ test('Multiple user mentions test', async ({pw}) => {
const mentionedUser = pw.random.user('mentioned');
const {id: mentionedUserID} = await adminClient.createUser(mentionedUser, '', '');
// # Add the mentioned user to the team
await adminClient.addToTeam(team.id, mentionedUserID);
// Get the town-square channel data
// # Get the town-square channel data
const channels = await userClient.getMyChannels(team.id);
const townSquare = channels.find((channel) => channel.name === 'town-square');
@@ -29,7 +38,7 @@ test('Multiple user mentions test', async ({pw}) => {
throw new Error('Town Square channel not found');
}
// Use API to create all the mention posts
// # Create multiple posts that mention the second user
for (let i = 0; i < MENTION_COUNT; i++) {
const message = `Hey @${mentionedUser.username}, this is mention #${i + 1}`;
await userClient.createPost({
@@ -39,26 +48,24 @@ test('Multiple user mentions test', async ({pw}) => {
});
}
// Login as the mentioned user to check mentions in the UI
// # Login as the mentioned user to check mentions in the UI
const {page: mentionedPage, channelsPage: mentionedChannelsPage} = await pw.testBrowser.login(mentionedUser);
await mentionedChannelsPage.goto(team.name, 'town-square');
await mentionedChannelsPage.toBeVisible();
// Click on the Recent Mentions button in the channel header
// # Click on the Recent Mentions button in the channel header
await mentionedPage.getByRole('button', {name: 'Recent mentions'}).click();
// Wait for the RHS panel to be visible first
// * Verify the right sidebar opens and is visible
await mentionedChannelsPage.sidebarRight.toBeVisible();
// Get all the mention posts in the RHS
// # Get all the mention posts in the right sidebar
const mentionPosts = mentionedChannelsPage.sidebarRight.container.locator('.post');
// Verify we have the expected number of mention posts
// Note: RHS might not load all 100 at once due to pagination, so we'll check
// a sufficient number is loaded (at least the first page)
// * Verify the correct number of mention posts are displayed
await expect(mentionPosts).toHaveCount(MENTION_COUNT);
// Verify the content of the first few mentions (most recent first)
// * Verify the content of each mention displays correctly with the right mention text
for (let i = 0; i < MENTION_COUNT; i++) {
const mentionNumber = MENTION_COUNT - i;
const expectedText = `Hey @${mentionedUser.username}, this is mention #${mentionNumber}`;

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

@@ -3,46 +3,58 @@
import {expect, test} from '@mattermost/playwright-lib';
test('MM-T5139: Message Priority - Standard message priority and system setting', async ({pw}) => {
// # Setup test environment
const {user} = await pw.initSetup();
/**
* @objective Verify that standard message priority posts correctly without priority labels and functions as expected.
*/
test(
'MM-T5139 posts message with standard priority and verifies no priority labels appear',
{tag: '@message_priority'},
async ({pw}) => {
// # Setup test environment
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {channelsPage} = await pw.testBrowser.login(user);
// # Log in as a user in new browser context
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Visit default channel page
await channelsPage.goto();
await channelsPage.toBeVisible();
// Open menu
await channelsPage.centerView.postCreate.openPriorityMenu();
// # Open priority menu
await channelsPage.centerView.postCreate.openPriorityMenu();
// Use messagePriority for dialog interactions
await channelsPage.messagePriority.verifyPriorityDialog();
await channelsPage.messagePriority.verifyStandardOptionSelected();
// * Verify priority dialog appears with standard option selected
await channelsPage.messagePriority.verifyPriorityDialog();
await channelsPage.messagePriority.verifyStandardOptionSelected();
// # Close menu and post message
await channelsPage.messagePriority.closePriorityMenu();
// # Close priority menu
await channelsPage.messagePriority.closePriorityMenu();
const testMessage = 'This is just a test message';
await channelsPage.postMessage(testMessage);
// # Post a message with standard priority
const testMessage = 'This is just a test message';
await channelsPage.postMessage(testMessage);
// # Verify message posts without priority label
const lastPost = await channelsPage.getLastPost();
await lastPost.toBeVisible();
await lastPost.toContainText(testMessage);
await expect(lastPost.container.locator('.post-priority')).not.toBeVisible();
// * Verify message posts correctly with the expected text
const lastPost = await channelsPage.getLastPost();
await lastPost.toBeVisible();
await lastPost.toContainText(testMessage);
// # Open post in RHS and verify
await lastPost.container.click();
await channelsPage.sidebarRight.toBeVisible();
// * Verify no priority label appears on the post
await expect(lastPost.container.locator('.post-priority')).not.toBeVisible();
// # Get RHS post and verify content
const rhsPost = await channelsPage.sidebarRight.getLastPost();
await rhsPost.toBeVisible();
await rhsPost.toContainText(testMessage);
await expect(rhsPost.container.locator('.post-priority')).not.toBeVisible();
// # Open post in right-hand sidebar
await lastPost.container.click();
await channelsPage.sidebarRight.toBeVisible();
// # Verify RHS formatting bar doesn't have priority button
await expect(channelsPage.sidebarRight.postCreate.priorityButton).not.toBeVisible();
});
// * Verify post content appears correctly in RHS
const rhsPost = await channelsPage.sidebarRight.getLastPost();
await rhsPost.toBeVisible();
await rhsPost.toContainText(testMessage);
// * Verify no priority label appears in RHS
await expect(rhsPost.container.locator('.post-priority')).not.toBeVisible();
// * Verify RHS formatting bar doesn't include priority button
await expect(channelsPage.sidebarRight.postCreate.priorityButton).not.toBeVisible();
},
);

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

@@ -3,54 +3,67 @@
import {expect, test} from '@mattermost/playwright-lib';
test('MM-T483 Channel-wide mentions with uppercase letters', async ({pw, headless, browserName}) => {
test.skip(
headless && browserName !== 'firefox',
'Works across browsers and devices, except in headless mode, where stubbing the Notification API is supported only in Firefox and WebKit.',
);
/**
* @objective Verify that channel-wide mentions with uppercase letters trigger notifications and are properly highlighted.
*
* @precondition
* - Two users are members of the same team
* - Notification permissions are granted in the browser
*/
test(
'MM-T483 triggers notification with uppercase channel-wide mention and highlights message for all users',
{tag: '@notifications'},
async ({pw, headless, browserName}) => {
test.skip(
headless && browserName !== 'firefox',
'Works across browsers and devices, except in headless mode, where stubbing the Notification API is supported only in Firefox and WebKit.',
);
// Initialize setup and get the required users and team
const {team, adminUser, user} = await pw.initSetup();
// # Initialize setup and get the required users and team
const {team, adminUser, user} = await pw.initSetup();
// Log in as the admin in one browser session and navigate to the "town-square" channel
const {page: adminPage, channelsPage: adminChannelsPage} = await pw.testBrowser.login(adminUser);
await adminChannelsPage.goto(team.name, 'town-square');
await adminChannelsPage.toBeVisible();
// # Log in as the admin in one browser session and navigate to the "town-square" channel
const {page: adminPage, channelsPage: adminChannelsPage} = await pw.testBrowser.login(adminUser);
await adminChannelsPage.goto(team.name, 'town-square');
await adminChannelsPage.toBeVisible();
// Stub the Notification in the admin's browser to capture notifications
await pw.stubNotification(adminPage, 'granted');
// # Stub the Notification in the admin's browser to capture notifications
await pw.stubNotification(adminPage, 'granted');
// Log in as the regular user in a separate browser and navigate to the "off-topic" channel
const {channelsPage: otherChannelsPage} = await pw.testBrowser.login(user);
await otherChannelsPage.goto(team.name, 'off-topic');
await otherChannelsPage.toBeVisible();
// # Log in as the regular user in a separate browser and navigate to the "off-topic" channel
const {channelsPage: otherChannelsPage} = await pw.testBrowser.login(user);
await otherChannelsPage.goto(team.name, 'off-topic');
await otherChannelsPage.toBeVisible();
// Post a channel-wide mention message "@ALL" in uppercase from the user's browser
const message = `@ALL good morning, ${team.name}!`;
await otherChannelsPage.postMessage(message);
// # Post a channel-wide mention message "@ALL" in uppercase from the user's browser
const message = `@ALL good morning, ${team.name}!`;
await otherChannelsPage.postMessage(message);
// Wait for a notification to be received in the admin's browser and verify its content
const notifications = await pw.waitForNotification(adminPage);
expect(notifications.length).toBe(1);
// * Verify notification is received in the admin's browser with correct content
const notifications = await pw.waitForNotification(adminPage);
expect(notifications.length).toBe(1);
const notification = notifications[0];
expect(notification.title).toBe('Off-Topic');
expect(notification.body).toBe(`@${user.username}: ${message}`);
expect(notification.tag).toBe(`@${user.username}: ${message}`);
expect(notification.icon).toContain('.png');
expect(notification.requireInteraction).toBe(false);
expect(notification.silent).toBe(false);
const notification = notifications[0];
expect(notification.title).toBe('Off-Topic');
expect(notification.body).toBe(`@${user.username}: ${message}`);
expect(notification.tag).toBe(`@${user.username}: ${message}`);
expect(notification.icon).toContain('.png');
expect(notification.requireInteraction).toBe(false);
expect(notification.silent).toBe(false);
// Verify the last post as viewed by the regular user in the "off-topic" channel contains the message and is highlighted
const otherLastPost = await otherChannelsPage.getLastPost();
await otherLastPost.toContainText(message);
await expect(otherLastPost.container.locator('.mention--highlight')).toBeVisible();
await expect(otherLastPost.container.locator('.mention--highlight').getByText('@ALL')).toBeVisible();
// * Verify the last post as viewed by the regular user in the "off-topic" channel contains the message and is highlighted
const otherLastPost = await otherChannelsPage.getLastPost();
await otherLastPost.toContainText(message);
await expect(otherLastPost.container.locator('.mention--highlight')).toBeVisible();
await expect(otherLastPost.container.locator('.mention--highlight').getByText('@ALL')).toBeVisible();
// Admin navigates to the "off-topic" channel and verifies the message is posted and highlighted correctly
await adminChannelsPage.goto(team.name, 'off-topic');
const adminLastPost = await adminChannelsPage.getLastPost();
await adminLastPost.toContainText(message);
await expect(adminLastPost.container.locator('.mention--highlight')).toBeVisible();
await expect(adminLastPost.container.locator('.mention--highlight').getByText('@ALL')).toBeVisible();
});
// # Navigate admin to the "off-topic" channel
await adminChannelsPage.goto(team.name, 'off-topic');
// * Verify the message is posted and highlighted correctly for the admin user
const adminLastPost = await adminChannelsPage.getLastPost();
await adminLastPost.toContainText(message);
await expect(adminLastPost.container.locator('.mention--highlight')).toBeVisible();
await expect(adminLastPost.container.locator('.mention--highlight').getByText('@ALL')).toBeVisible();
},
);

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

@@ -16,53 +16,59 @@ test.beforeEach(async ({pw}) => {
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5643_1 should create a scheduled message from a channel', {tag: '@scheduled_messages'}, async ({pw}) => {
// Set test timeout to 4 mins to wait for the scheduled message to be sent
// which is expected within 2 mins.
test.setTimeout(pw.duration.four_min);
test(
'MM-T5643_1 creates scheduled message from channel and posts at scheduled time',
{tag: '@scheduled_messages'},
async ({pw}) => {
// Set test timeout to 4 mins to wait for the scheduled message to be sent
// which is expected within 2 mins.
test.setTimeout(pw.duration.four_min);
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {page, channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {page, channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a scheduled message
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 0, 1);
// # Create a scheduled message with short delay
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 0, 1);
// * Verify scheduled post indicator with correct date/time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled post indicator shows correct date and time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled post badge in left sidebar shows correct count
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// * Verify scheduled post badge in left sidebar shows count of 1
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// 3. Click "See all link" to navigate to scheduled posts page
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page via "See all" link
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send ${selectedDate} at ${selectedTime}`;
await verifyScheduledPost(scheduledPostsPage, {draftMessage, sendOnMessage, badgeCountOnTab: 1});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send ${selectedDate} at ${selectedTime}`;
await verifyScheduledPost(scheduledPostsPage, {draftMessage, sendOnMessage, badgeCountOnTab: 1});
// 4. Go back to the channels page
await page.goBack();
// # Return to the channels page
await page.goBack();
// * Verify the message has been posted and there's no more scheduled messages
await pw.waitUntil(
async () => {
const post = await channelsPage.getLastPost();
const content = await post.container.textContent();
// * Verify scheduled message was posted successfully
await pw.waitUntil(
async () => {
const post = await channelsPage.getLastPost();
const content = await post.container.textContent();
return content?.includes(draftMessage);
},
{timeout: pw.duration.two_min},
);
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(scheduledPostsPage.badge).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
});
return content?.includes(draftMessage);
},
{timeout: pw.duration.two_min},
);
// * Verify scheduled indicators are removed after posting
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(scheduledPostsPage.badge).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
},
);
/**
* @objective Verify the ability to create a scheduled message in a thread.
@@ -70,54 +76,60 @@ test('MM-T5643_1 should create a scheduled message from a channel', {tag: '@sche
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5643_6 should create a scheduled message under a thread post', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Threaded Message ${pw.random.id()}`;
test(
'MM-T5643_6 creates scheduled message in thread and posts in thread conversation',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Threaded Message ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Post a message
await channelsPage.postMessage('Root Message');
// # Create a root message in the channel
await channelsPage.postMessage('Root Message');
// 3. Reply to a message
const {sidebarRight} = await channelsPage.replyToLastPost('Replying to a thread');
// # Start a thread by replying to the message
const {sidebarRight} = await channelsPage.replyToLastPost('Replying to a thread');
// 4. Create a scheduled message from the thread
const {selectedDate, selectedTime} = await channelsPage.scheduleMessageFromThread(draftMessage, 1);
// # Create a scheduled message within the thread
const {selectedDate, selectedTime} = await channelsPage.scheduleMessageFromThread(draftMessage, 1);
// * Verify scheduled post indicator with correct date/time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(sidebarRight.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled post indicator shows correct date and time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(sidebarRight.scheduledPostIndicator, indicatorMessage);
// 5. Navigate to scheduled posts page
await sidebarRight.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page using indicator link
await sidebarRight.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 6. Hover over the scheduled post and send now
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// # Send the scheduled message immediately
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// * Verify the message has been posted and there's no more scheduled messages
await sidebarRight.toBeVisible();
const lastPost = await sidebarRight.getLastPost();
await expect(lastPost.body).toContainText(draftMessage);
await sidebarRight.scheduledPostIndicator.toBeNotVisible();
await expect(scheduledPostsPage.noScheduledDrafts).toBeVisible();
await expect(scheduledPostsPage.badge).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
});
// * Verify message is posted in the thread
await sidebarRight.toBeVisible();
const lastPost = await sidebarRight.getLastPost();
await expect(lastPost.body).toContainText(draftMessage);
// * Verify all scheduled message indicators are removed
await sidebarRight.scheduledPostIndicator.toBeNotVisible();
await expect(scheduledPostsPage.noScheduledDrafts).toBeVisible();
await expect(scheduledPostsPage.badge).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
},
);
/**
* @objective Verify the ability to reschedule a scheduled message.
@@ -125,49 +137,51 @@ test('MM-T5643_6 should create a scheduled message under a thread post', {tag: '
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5644 should reschedule a scheduled message', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
test(
'MM-T5644_2 reschedules message to a future date from scheduled posts page',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a scheduled message with 1 day offset
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// # Create a scheduled message for tomorrow
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// * Verify scheduled message indicator appears with correct date/time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled message indicator shows correct date and time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled post badge in left sidebar shows correct count
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// * Verify scheduled post badge appears with count of 1
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// 3. Navigate to scheduled posts page
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page via indicator link
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 4. Reschedule message to 2 days from today
const {selectedDate: newSelectedDate, selectedTime: newSelectedTime} = await scheduledPostsPage.rescheduleMessage(
scheduledPost,
2,
);
// # Reschedule the message to a different date (2 days from now)
const {selectedDate: newSelectedDate, selectedTime: newSelectedTime} =
await scheduledPostsPage.rescheduleMessage(scheduledPost, 2);
// 5. Return to channel page
await channelsPage.goto();
// # Return to channel page
await channelsPage.goto();
// * Verify the message shows updated scheduled time
const newIndicatorMessage = `Message scheduled for ${newSelectedDate} at ${newSelectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, newIndicatorMessage);
});
// * Verify indicator shows the updated scheduled time
const newIndicatorMessage = `Message scheduled for ${newSelectedDate} at ${newSelectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, newIndicatorMessage);
},
);
/**
* @objective Verify the ability to delete a scheduled message.
@@ -175,45 +189,50 @@ test('MM-T5644 should reschedule a scheduled message', {tag: '@scheduled_message
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5645 should delete a scheduled message', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
test(
'MM-T5645 deletes scheduled message from scheduled posts page and removes all indicators',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a scheduled message with 1 day offset
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// # Create a scheduled message for tomorrow
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// * Verify scheduled message indicator appears with correct date/time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled message indicator shows correct date and time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// 3. Navigate to scheduled posts page
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page via indicator link
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 4. Delete the scheduled message
await scheduledPost.hover();
await scheduledPost.deleteButton.click();
// # Delete the scheduled message
await scheduledPost.hover();
await scheduledPost.deleteButton.click();
await scheduledPostsPage.deleteScheduledPostModal.toBeVisible();
await scheduledPostsPage.deleteScheduledPostModal.deleteButton.click();
// # Confirm deletion in the modal
await scheduledPostsPage.deleteScheduledPostModal.toBeVisible();
await scheduledPostsPage.deleteScheduledPostModal.deleteButton.click();
// * Verify the scheduled message is removed from the scheduled posts page
await expect(scheduledPostsPage.noScheduledDrafts).toBeVisible();
await expect(scheduledPostsPage.badge).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
});
// * Verify the scheduled message is removed and no longer appears
await expect(scheduledPostsPage.noScheduledDrafts).toBeVisible();
await expect(scheduledPostsPage.badge).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
},
);
/**
* @objective Verify the ability to send a scheduled message immediately.
@@ -221,46 +240,54 @@ test('MM-T5645 should delete a scheduled message', {tag: '@scheduled_messages'},
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5643_9 should send a scheduled message immediately', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
test(
'MM-T5643_9 sends scheduled message immediately from scheduled posts page',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user, townSquareUrl} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user, townSquareUrl} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a scheduled message with 1 day offset
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// # Create a scheduled message for tomorrow
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// * Verify scheduled message indicator appears with correct date/time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled message indicator shows correct date and time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// 3. Navigate to scheduled posts page
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page via indicator link
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 4. Send the scheduled message immediately
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// # Send the scheduled message immediately instead of waiting
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// * Verify it redirects to the channels page, the message has been posted and there's no more scheduled messages
await expect(channelsPage.page).toHaveURL(townSquareUrl);
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
const lastPost = await channelsPage.getLastPost();
await expect(lastPost.body).toContainText(draftMessage);
});
// * Verify page redirects to the channel
await expect(channelsPage.page).toHaveURL(townSquareUrl);
// * Verify scheduled indicators are removed
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
// * Verify message was posted in the channel
const lastPost = await channelsPage.getLastPost();
await expect(lastPost.body).toContainText(draftMessage);
},
);
/**
* @objective Verify the ability to create a scheduled message from a direct message (DM).
@@ -268,59 +295,67 @@ test('MM-T5643_9 should send a scheduled message immediately', {tag: '@scheduled
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5643_3 should create a scheduled message from a DM', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
test(
'MM-T5643_3 creates scheduled message from DM channel and posts at scheduled time',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user and another user
const {user, team, adminClient} = await pw.initSetup();
const otherUser = await adminClient.createUser(pw.random.user(), '', '');
// # Initialize test setup with main user and create a second user
const {user, team, adminClient} = await pw.initSetup();
const otherUser = await adminClient.createUser(pw.random.user(), '', '');
// 2. Login the first user and navigate to a DM channel with the other user
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto(team.name, `@${otherUser.username}`);
await channelsPage.toBeVisible();
// # Login as first user and navigate to DM channel with second user
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto(team.name, `@${otherUser.username}`);
await channelsPage.toBeVisible();
// 3. Create a scheduled message with 1 day offset
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// # Create a scheduled message for tomorrow in the DM
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// * Verify scheduled message indicator appears with correct date/time
let indicatorMessage;
if (pw.isOutsideRemoteUserHour(otherUser.timezone)) {
indicatorMessage = 'You have one scheduled message.';
} else {
indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
}
await channelsPage.centerView.scheduledPostIndicator.toBeVisible();
await expect(channelsPage.centerView.scheduledPostIndicator.messageText).toContainText(indicatorMessage);
// * Verify appropriate scheduled message indicator appears
let indicatorMessage;
if (pw.isOutsideRemoteUserHour(otherUser.timezone)) {
indicatorMessage = 'You have one scheduled message.';
} else {
indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
}
await channelsPage.centerView.scheduledPostIndicator.toBeVisible();
await expect(channelsPage.centerView.scheduledPostIndicator.messageText).toContainText(indicatorMessage);
// 4. Navigate to scheduled posts page
if (pw.isOutsideRemoteUserHour(otherUser.timezone)) {
await channelsPage.centerView.scheduledPostIndicator.scheduledMessageLink.click();
} else {
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
}
// # Navigate to scheduled posts page using appropriate link
if (pw.isOutsideRemoteUserHour(otherUser.timezone)) {
await channelsPage.centerView.scheduledPostIndicator.scheduledMessageLink.click();
} else {
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
}
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 5. Send the scheduled message immediately
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// # Send the scheduled message immediately instead of waiting
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// * Verify it redirects to the DM channel, message is posted and there's no more scheduled messages
await expect(channelsPage.page).toHaveURL(`/${team.name}/messages/@${otherUser.username}`);
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
const lastPost = await channelsPage.getLastPost();
await expect(lastPost.body).toContainText(draftMessage);
});
// * Verify page redirects to the DM channel
await expect(channelsPage.page).toHaveURL(`/${team.name}/messages/@${otherUser.username}`);
// * Verify scheduled indicators are removed
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
// * Verify message was posted in the DM channel
const lastPost = await channelsPage.getLastPost();
await expect(lastPost.body).toContainText(draftMessage);
},
);
/**
* @objective Verify the ability to convert a draft message to a scheduled message.
@@ -328,40 +363,46 @@ test('MM-T5643_3 should create a scheduled message from a DM', {tag: '@scheduled
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5648 should create a draft and then schedule it', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
test(
'MM-T5648 converts draft message to scheduled message from drafts page',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user, team} = await pw.initSetup();
const {channelsPage, draftsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user, team} = await pw.initSetup();
const {channelsPage, draftsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a draft message
await channelsPage.centerView.postCreate.input.fill(draftMessage);
// # Create a draft message without sending it
await channelsPage.centerView.postCreate.input.fill(draftMessage);
// 3. Go to drafts page
await draftsPage.goto(team.name);
await draftsPage.toBeVisible();
expect(await draftsPage.getBadgeCountOnTab()).toBe('1');
// # Navigate to the drafts page
await draftsPage.goto(team.name);
await draftsPage.toBeVisible();
// * Verify draft message exists
const draftedPost = await draftsPage.getLastPost();
await expect(draftedPost.panelBody).toContainText(draftMessage);
// * Verify draft count badge shows one draft
expect(await draftsPage.getBadgeCountOnTab()).toBe('1');
// 4. Open schedule modal from draft and schedule it to the next 2 days
await draftedPost.hover();
await draftedPost.scheduleButton.click();
await draftsPage.scheduleMessageModal.toBeVisible();
const {selectedDate, selectedTime} = await draftsPage.scheduleMessageModal.scheduleMessage(2);
// * Verify draft message content appears correctly
const draftedPost = await draftsPage.getLastPost();
await expect(draftedPost.panelBody).toContainText(draftMessage);
// 5. Navigate to scheduled posts page
await scheduledPostsPage.goto(team.name);
// # Schedule the draft for 2 days in the future
await draftedPost.hover();
await draftedPost.scheduleButton.click();
await draftsPage.scheduleMessageModal.toBeVisible();
const {selectedDate, selectedTime} = await draftsPage.scheduleMessageModal.scheduleMessage(2);
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
await verifyScheduledPost(scheduledPostsPage, {draftMessage, sendOnMessage, badgeCountOnTab: 1});
});
// # Navigate to scheduled posts page
await scheduledPostsPage.goto(team.name);
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
await verifyScheduledPost(scheduledPostsPage, {draftMessage, sendOnMessage, badgeCountOnTab: 1});
},
);
/**
* @objective Verify the ability to edit a scheduled message before it's sent.
@@ -369,62 +410,70 @@ test('MM-T5648 should create a draft and then schedule it', {tag: '@scheduled_me
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5644 should edit scheduled message', {tag: '@scheduled_messages'}, async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
test(
'MM-T5644_1 edits scheduled message content while preserving scheduled time',
{tag: '@scheduled_messages'},
async ({pw}) => {
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user, townSquareUrl} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user, townSquareUrl} = await pw.initSetup();
const {channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a scheduled message with 2 days offset
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 2);
// # Create a scheduled message for 2 days in the future
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 2);
// * Verify scheduled message indicator appears with correct date/time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled message indicator shows correct date and time
const indicatorMessage = `Message scheduled for ${selectedDate} at ${selectedTime}.`;
await verifyScheduledPostIndicator(channelsPage.centerView.scheduledPostIndicator, indicatorMessage);
// * Verify scheduled post badge in left sidebar shows correct count
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// * Verify scheduled post badge shows count of 1
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// 3. Navigate to scheduled posts page
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page via indicator link
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 4. Hover and click edit button
await scheduledPost.hover();
await scheduledPost.editButton.click();
// # Edit the scheduled message content
await scheduledPost.hover();
await scheduledPost.editButton.click();
const updatedText = 'updated text';
await scheduledPost.editTextBox.fill(updatedText);
await scheduledPost.saveButton.click();
// 5. Edit the scheduled message
const updatedText = 'updated text';
await scheduledPost.editTextBox.fill(updatedText);
await scheduledPost.saveButton.click();
// * Verify the edited message content is updated
await expect(scheduledPost.panelBody).toContainText(updatedText);
// 6. Verify the edited message appears in the channel
await expect(scheduledPost.panelBody).toContainText(updatedText);
await expect(scheduledPost.panelHeader).toContainText(`Send on ${selectedDate} at ${selectedTime}`);
// * Verify scheduled date/time remains unchanged
await expect(scheduledPost.panelHeader).toContainText(`Send on ${selectedDate} at ${selectedTime}`);
// 7. Send the message immediately
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// # Send the edited message immediately
await scheduledPost.hover();
await scheduledPost.sendNowButton.click();
await scheduledPostsPage.sendMessageNowModal.toBeVisible();
await scheduledPostsPage.sendMessageNowModal.sendNowButton.click();
// * Verify it redirects to the channels page, the message has been posted and there's no more scheduled messages
await expect(channelsPage.page).toHaveURL(townSquareUrl);
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
const lastPost = await channelsPage.getLastPost();
await expect(lastPost.body).toHaveText(updatedText);
});
// * Verify page redirects to the channel
await expect(channelsPage.page).toHaveURL(townSquareUrl);
// * Verify scheduled indicators are removed
await channelsPage.centerView.scheduledPostIndicator.toBeNotVisible();
await expect(channelsPage.sidebarLeft.scheduledPostBadge).not.toBeVisible();
// * Verify edited message was posted in the channel
const lastPost = await channelsPage.getLastPost();
await expect(lastPost.body).toHaveText(updatedText);
},
);
/**
* @objective Verify the ability to copy a scheduled message to clipboard.
@@ -432,51 +481,55 @@ test('MM-T5644 should edit scheduled message', {tag: '@scheduled_messages'}, asy
* @precondition
* A test server with valid license to support scheduled message features
*/
test('MM-T5650 should copy scheduled message', {tag: '@scheduled_messages'}, async ({pw, browserName}) => {
// Skip this test in Firefox clipboard permissions are not supported
test.skip(browserName === 'firefox', 'Test not supported in Firefox');
test(
'MM-T5650 copies scheduled message text to clipboard for reuse',
{tag: '@scheduled_messages'},
async ({pw, browserName}) => {
// # Skip this test in Firefox since clipboard permissions are not supported
test.skip(browserName === 'firefox', 'Test not supported in Firefox');
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
const draftMessage = `Scheduled Draft ${pw.random.id()}`;
// 1. Setup test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {page, channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Initialize test user, login and navigate to a channel
const {user} = await pw.initSetup();
const {page, channelsPage, scheduledPostsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// 2. Create a scheduled message with 1 day offset
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// # Create a scheduled message for tomorrow
const {selectedDate, selectedTime} = await channelsPage.scheduleMessage(draftMessage, 1);
// * Verify scheduled post badge in left sidebar shows correct count
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// * Verify scheduled post badge shows count of 1
await verifyScheduledPostBadgeOnLeftSidebar(channelsPage, 1);
// 3. Navigate to scheduled posts page
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// # Navigate to scheduled posts page via indicator link
await channelsPage.centerView.scheduledPostIndicator.seeAllLink.click();
// * Verify scheduled posts page displays correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// * Verify scheduled post appears with correct information
const sendOnMessage = `Send on ${selectedDate} at ${selectedTime}`;
const scheduledPost = await verifyScheduledPost(scheduledPostsPage, {
draftMessage,
sendOnMessage,
badgeCountOnTab: 1,
});
// 4. Copy the scheduled message
await scheduledPost.hover();
await scheduledPost.copyTextButton.click();
// # Copy the scheduled message text to clipboard
await scheduledPost.hover();
await scheduledPost.copyTextButton.click();
// 5. Return to channel page
await page.goBack();
// # Return to the channel page
await page.goBack();
// 6. Paste the copied message in post creator
await channelsPage.centerView.postCreate.input.focus();
await page.keyboard.down('ControlOrMeta');
await page.keyboard.press('V');
await page.keyboard.up('ControlOrMeta');
// # Paste the copied message into the post input box
await channelsPage.centerView.postCreate.input.focus();
await page.keyboard.down('ControlOrMeta');
await page.keyboard.press('V');
await page.keyboard.up('ControlOrMeta');
// * Verify the copied message is pasted in the post input box
await expect(channelsPage.centerView.postCreate.input).toHaveText(draftMessage);
});
// * Verify the clipboard content was pasted correctly
await expect(channelsPage.centerView.postCreate.input).toHaveText(draftMessage);
},
);
/**
* Verifies that the scheduled post indicator is visible and displays the correct date and time.

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

@@ -3,38 +3,49 @@
import {test} from '@mattermost/playwright-lib';
test('/signup_email', async ({pw, page, browserName, viewport}, testInfo) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
/**
* @objective Verify the appearance of the signup email page in normal and error states
*/
test(
'signup_email visual verification',
{tag: '@visual_signup'},
async ({pw, page, browserName, viewport}, testInfo) => {
// # Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// Go to login page
const {adminClient} = await pw.getAdminClient();
await pw.loginPage.goto();
await pw.loginPage.toBeVisible();
// # Navigate to login page
const {adminClient} = await pw.getAdminClient();
await pw.loginPage.goto();
await pw.loginPage.toBeVisible();
// Create an account
await pw.loginPage.createAccountLink.click();
// # Click on create account link
await pw.loginPage.createAccountLink.click();
// Should have redirected to signup page
await pw.signupPage.toBeVisible();
// * Verify redirection to signup page
await pw.signupPage.toBeVisible();
// Click to other element to remove focus from email input
await pw.signupPage.title.click();
// # Remove focus from email input by clicking elsewhere
await pw.signupPage.title.click();
// Match snapshot of signup_email page
const testArgs = {page, browserName, viewport};
const license = await adminClient.getClientLicenseOld();
const editionSuffix = license.IsLicensed === 'true' ? '' : 'free edition';
await pw.matchSnapshot({...testInfo, title: `${testInfo.title} ${editionSuffix}`}, testArgs);
// # Get license information to determine snapshot suffix
const license = await adminClient.getClientLicenseOld();
const editionSuffix = license.IsLicensed === 'true' ? '' : 'free edition';
const testArgs = {page, browserName, viewport};
// Click sign in button without entering user credential
const invalidUser = {email: 'invalid', username: 'a', password: 'b'};
await pw.signupPage.create(invalidUser, false);
await pw.signupPage.emailError.waitFor();
await pw.signupPage.usernameError.waitFor();
await pw.signupPage.passwordError.waitFor();
await pw.waitForAnimationEnd(pw.signupPage.bodyCard);
// * Verify visual appearance of signup page
await pw.matchSnapshot({...testInfo, title: `${testInfo.title} ${editionSuffix}`}, testArgs);
// Match snapshot of signup_email page
await pw.matchSnapshot({...testInfo, title: `${testInfo.title} error ${editionSuffix}`}, testArgs);
});
// # Attempt to create account with invalid credentials
const invalidUser = {email: 'invalid', username: 'a', password: 'b'};
await pw.signupPage.create(invalidUser, false);
// * Verify error messages appear for each field
await pw.signupPage.emailError.waitFor();
await pw.signupPage.usernameError.waitFor();
await pw.signupPage.passwordError.waitFor();
await pw.waitForAnimationEnd(pw.signupPage.bodyCard);
// * Verify visual appearance of signup page with errors
await pw.matchSnapshot({...testInfo, title: `${testInfo.title} error ${editionSuffix}`}, testArgs);
},
);

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 209 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 211 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 508 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 170 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 507 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 167 KiB