E2E/Playwright: Instantiate page in pw (#29765)

* instantiate page in pw

* update spec

* fix storage key and require user when logging in via API

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Saturnino Abril 2025-01-14 12:30:42 +08:00 committed by GitHub
parent 20e9c6aa3e
commit 90e3d2833e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 554 additions and 591 deletions

View File

@ -41,15 +41,6 @@ export default defineConfig({
trace: 'off',
video: 'retain-on-failure',
actionTimeout: duration.half_min,
storageState: {
cookies: [],
origins: [
{
origin: testConfig.baseURL,
localStorage: [{name: '__landingPageSeen__', value: 'true'}],
},
],
},
},
projects: [
{
@ -57,14 +48,14 @@ export default defineConfig({
use: {
browserName: 'chromium',
...devices['iPad Pro 11'],
permissions: ['notifications'],
permissions: ['notifications', 'clipboard-read', 'clipboard-write'],
},
},
{
name: 'chrome',
use: {
browserName: 'chromium',
permissions: ['notifications'],
permissions: ['notifications', 'clipboard-read', 'clipboard-write'],
viewport: {width: 1280, height: 1024},
},
},

View File

@ -7,6 +7,7 @@ import {request, Browser, BrowserContext} from '@playwright/test';
import {UserProfile} from '@mattermost/types/users';
import testConfig from '@e2e-test.config';
import pages from '@e2e-support/ui/pages';
export class TestBrowser {
readonly browser: Browser;
@ -17,7 +18,7 @@ export class TestBrowser {
this.context = null;
}
async login(user: UserProfile | null) {
async login(user: UserProfile) {
const options = {storageState: ''};
if (user) {
// Log in via API request and save user storage
@ -29,9 +30,14 @@ export class TestBrowser {
const context = await this.browser.newContext(options);
const page = await context.newPage();
const channelsPage = new pages.ChannelsPage(page);
const systemConsolePage = new pages.SystemConsolePage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const draftPage = new pages.DraftPage(page);
this.context = context;
return {context, page};
return {context, page, channelsPage, systemConsolePage, scheduledDraftPage, draftPage};
}
async close() {

View File

@ -20,6 +20,9 @@ export async function initSetup({
try {
// Login the admin user via API
const {adminClient, adminUser} = await getAdminClient();
if (!adminUser) {
throw new Error('Failed to setup admin: Admin user not found.');
}
if (!adminClient) {
throw new Error(
"Failed to setup admin: Check that you're able to access the server using the same admin credential.",

View File

@ -6,16 +6,16 @@ import {TestBrowser} from './browser_context';
import {shouldHaveCallsEnabled, shouldHaveFeatureFlag, shouldRunInLinux, ensureLicense, skipIfNoLicense} from './flag';
import {initSetup, getAdminClient} from './server';
import {hideDynamicChannelsContent, waitForAnimationEnd, waitUntil} from './test_action';
import {pages} from './ui/pages';
import pages from './ui/pages';
import {matchSnapshot} from './visual';
import {stubNotification, waitForNotification} from './mock_browser_api';
import {duration} from './util';
export {expect} from '@playwright/test';
type ExtendedFixtures = {
axe: AxeBuilderExtended;
pw: PlaywrightExtended;
pages: typeof pages;
};
type AxeBuilderOptions = {
@ -29,15 +29,11 @@ export const test = base.extend<ExtendedFixtures>({
const ab = new AxeBuilderExtended();
await use(ab);
},
pw: async ({browser}, use) => {
const pw = new PlaywrightExtended(browser);
pw: async ({browser, page, isMobile}, use) => {
const pw = new PlaywrightExtended(browser, page, isMobile);
await use(pw);
await pw.testBrowser.close();
},
// eslint-disable-next-line no-empty-pattern
pages: async ({}, use) => {
await use(pages);
},
});
class PlaywrightExtended {
@ -60,8 +56,11 @@ class PlaywrightExtended {
readonly waitForAnimationEnd;
readonly waitUntil;
// ./ui/pages
readonly pages;
// unauthenticated page
readonly loginPage;
readonly landingLoginPage;
readonly signupPage;
readonly resetPasswordPage;
// ./visual
readonly matchSnapshot;
@ -70,7 +69,9 @@ class PlaywrightExtended {
readonly stubNotification;
readonly waitForNotification;
constructor(browser: Browser) {
readonly hasSeenLandingPage;
constructor(browser: Browser, page: Page, isMobile: boolean) {
// ./browser_context
this.testBrowser = new TestBrowser(browser);
@ -90,8 +91,11 @@ class PlaywrightExtended {
this.waitForAnimationEnd = waitForAnimationEnd;
this.waitUntil = waitUntil;
// ./ui/pages
this.pages = pages;
// unauthenticated page
this.loginPage = new pages.LoginPage(page);
this.landingLoginPage = new pages.LandingLoginPage(page, isMobile);
this.signupPage = new pages.SignupPage(page);
this.resetPasswordPage = new pages.ResetPasswordPage(page);
// ./visual
this.matchSnapshot = matchSnapshot;
@ -99,6 +103,12 @@ class PlaywrightExtended {
// ./mock_browser_api
this.stubNotification = stubNotification;
this.waitForNotification = waitForNotification;
this.hasSeenLandingPage = async () => {
// Visit the base URL to be able to set the localStorage
await page.goto('/');
return await waitUntilLocalStorageIsSet(page, '__landingPageSeen__', 'true');
};
}
}
@ -142,3 +152,20 @@ class AxeBuilderExtended {
return JSON.stringify(fingerprints, null, 2);
}
}
async function waitUntilLocalStorageIsSet(page: Page, key: string, value: string, timeout = duration.ten_sec) {
await waitUntil(
() =>
page.evaluate(
({key, value}) => {
if (localStorage.getItem(key) === value) {
return true;
}
localStorage.setItem(key, value);
return false;
},
{key, value},
),
{timeout},
);
}

View File

@ -13,7 +13,7 @@ export default class ChannelsCenterView {
readonly header;
readonly postCreate;
readonly scheduledDraftOptions;
readonly scheduledDraftChannelInfo;
readonly postBoxIndicator;
readonly scheduledDraftChannelIcon;
readonly scheduledDraftChannelInfoMessage;
readonly scheduledDraftChannelInfoMessageText;
@ -27,7 +27,7 @@ export default class ChannelsCenterView {
this.scheduledDraftOptions = new components.ChannelsPostCreate(
container.locator('#dropdown_send_post_options'),
);
this.scheduledDraftChannelInfo = container.locator('div.postBoxIndicator');
this.postBoxIndicator = container.locator('div.postBoxIndicator');
this.scheduledDraftChannelIcon = container.locator('#create_post i.icon-draft-indicator');
this.scheduledDraftChannelInfoMessage = container.locator('div.ScheduledPostIndicator span');
this.scheduledDraftChannelInfoMessageText = container.locator('span:has-text("Message scheduled for")');
@ -110,7 +110,7 @@ export default class ChannelsCenterView {
}
async verifyscheduledDraftChannelInfo() {
await this.scheduledDraftChannelInfo.isVisible();
await this.postBoxIndicator.isVisible();
await this.scheduledDraftChannelIcon.isVisible();
const messageLocator = this.scheduledDraftChannelInfoMessage.first();
await expect(messageLocator).toContainText('Message scheduled for');

View File

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator, Page} from '@playwright/test';
import {expect, Locator} from '@playwright/test';
/**
* This is the generic confirm modal that is used in the app.
@ -15,11 +15,10 @@ export default class GenericConfirmModal {
readonly confirmButton: Locator;
readonly cancelButton: Locator;
constructor(page: Page, id?: string) {
const modalId = `#confirmModal ${id}`.trim();
this.container = page.locator(modalId);
this.confirmButton = page.locator('#confirmModalButton');
this.cancelButton = page.locator('#cancelModalButton');
constructor(container: Locator) {
this.container = container;
this.confirmButton = container.locator('#confirmModalButton');
this.cancelButton = container.locator('#cancelModalButton');
}
async toBeVisible() {

View File

@ -11,7 +11,7 @@ export default class ChannelsSidebarRight {
readonly closeButton;
readonly postCreate;
readonly rhsPostBody;
readonly scheduledDraftChannelInfo;
readonly postBoxIndicator;
readonly scheduledDraftChannelInfoMessage;
readonly scheduledDraftSeeAllLink;
readonly scheduledDraftChannelInfoMessageText;
@ -19,7 +19,7 @@ export default class ChannelsSidebarRight {
constructor(container: Locator) {
this.container = container;
this.scheduledDraftChannelInfo = container.locator('div.postBoxIndicator');
this.postBoxIndicator = container.locator('div.postBoxIndicator');
this.scheduledDraftChannelInfoMessage = container.locator('div.ScheduledPostIndicator span');
this.scheduledDraftSeeAllLink = container.locator('a:has-text("See all scheduled messages")');
this.scheduledDraftChannelInfoMessageText = container.locator('span:has-text("Message scheduled for")');

View File

@ -21,4 +21,5 @@ const pages = {
DraftPage,
};
export {pages, ChannelsPage, LandingLoginPage, LoginPage, SignupPage, ScheduledDraftPage, DraftPage};
export {ChannelsPage, LandingLoginPage, LoginPage, SignupPage, ScheduledDraftPage, DraftPage};
export default pages;

View File

@ -3,14 +3,11 @@
import {expect, Page} from '@playwright/test';
import {AdminConfig} from '@mattermost/types/config';
import {UserProfile} from '@mattermost/types/users';
import {components} from '@e2e-support/ui/components';
export default class LoginPage {
readonly adminConfig: AdminConfig;
readonly page: Page;
readonly title;
@ -18,6 +15,7 @@ export default class LoginPage {
readonly bodyCard;
readonly loginInput;
readonly loginPlaceholder;
readonly loginWithAdLdapPlaceholder;
readonly passwordInput;
readonly passwordToggleButton;
readonly signInButton;
@ -30,19 +28,15 @@ export default class LoginPage {
readonly header;
readonly footer;
constructor(page: Page, adminConfig: AdminConfig) {
constructor(page: Page) {
this.page = page;
this.adminConfig = adminConfig;
const loginInputPlaceholder = adminConfig.LdapSettings.Enable
? 'Email, Username or AD/LDAP Username'
: 'Email or Username';
this.title = page.locator('h1:has-text("Log in to your account")');
this.subtitle = page.locator('text=Collaborate with your team in real-time');
this.bodyCard = page.locator('.login-body-card-content');
this.loginInput = page.locator('#input_loginId');
this.loginPlaceholder = page.locator(`[placeholder="${loginInputPlaceholder}"]`);
this.loginPlaceholder = page.locator(`[placeholder="Email or Username"]`);
this.loginWithAdLdapPlaceholder = page.locator(`[placeholder="Email, Username or AD/LDAP Username"]`);
this.passwordInput = page.locator('#input_password-input');
this.passwordToggleButton = page.getByRole('button', {name: 'Show or hide password'});
this.signInButton = page.locator('button:has-text("Log in")');

View File

@ -20,6 +20,10 @@ class SystemConsolePage {
readonly systemUsersDateRangeMenu;
readonly systemUsersColumnToggleMenu;
readonly systemUsersActionMenus;
// modal
readonly confirmModal;
readonly exportModal;
readonly saveChangesModal;
constructor(page: Page) {
@ -47,6 +51,9 @@ class SystemConsolePage {
this.systemUsersActionMenus = Array.from(Array(10).keys()).map(
(index) => new components.SystemUsersFilterMenu(page.locator(`#actionMenu-systemUsersTable-${index}`)),
);
this.confirmModal = new components.GenericConfirmModal(page.locator('#confirmModal'));
this.exportModal = new components.GenericConfirmModal(page.getByRole('dialog', {name: 'Export user data'}));
this.saveChangesModal = new components.SystemUsers(page.locator('div.modal-content'));
}

View File

@ -3,15 +3,14 @@
import {expect, test} from '@e2e-support/test_fixture';
test.fixme('Base channel accessibility', async ({pw, pages, axe}) => {
test.fixme('Base channel accessibility', async ({pw, axe}) => {
// # Create and sign in a new user
const {user} = await pw.initSetup();
// # Log in a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {page, channelsPage} = await pw.testBrowser.login(user);
// # Visit a default channel page
const channelsPage = new pages.ChannelsPage(page);
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('hello');
@ -24,17 +23,16 @@ test.fixme('Base channel accessibility', async ({pw, pages, axe}) => {
expect(accessibilityScanResults.violations).toHaveLength(0);
});
test('Post actions tab support', async ({pw, pages, axe}) => {
test('Post actions tab support', async ({pw, axe}) => {
// # Create and sign in a new user
const {user, adminClient} = await pw.initSetup();
const config = await adminClient.getConfig();
const license = await adminClient.getClientLicenseOld();
// # Log in a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {page, channelsPage} = await pw.testBrowser.login(user);
// # Visit a default channel page
const channelsPage = new pages.ChannelsPage(page);
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('hello');

View File

@ -3,77 +3,77 @@
import {expect, test} from '@e2e-support/test_fixture';
test('/login accessibility quick check', async ({pw, pages, page, axe}) => {
test('/login accessibility quick check', async ({pw, axe}) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// # Go to login page
const {adminClient} = await pw.getAdminClient();
const adminConfig = await adminClient.getConfig();
const loginPage = new pages.LoginPage(page, adminConfig);
await loginPage.goto();
await loginPage.toBeVisible();
await pw.loginPage.goto();
await pw.loginPage.toBeVisible();
// # Analyze the page
const accessibilityScanResults = await axe.builder(loginPage.page).analyze();
const accessibilityScanResults = await axe.builder(pw.loginPage.page).analyze();
// * Should have no violation
expect(accessibilityScanResults.violations).toHaveLength(0);
});
test('/login accessibility tab support', async ({pw, pages, page}) => {
test('/login accessibility tab support', async ({pw}) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// # Go to login page
const {adminClient} = await pw.getAdminClient();
const adminConfig = await adminClient.getConfig();
const loginPage = new pages.LoginPage(page, adminConfig);
await loginPage.goto();
await loginPage.toBeVisible();
await pw.loginPage.goto();
await pw.loginPage.toBeVisible();
// * Should have focused at login input on page load
expect(await loginPage.loginInput).toBeFocused();
expect(await pw.loginPage.loginInput).toBeFocused();
// * Should move focus to password input after tab
await loginPage.loginInput.press('Tab');
expect(await loginPage.passwordInput).toBeFocused();
await pw.loginPage.loginInput.press('Tab');
expect(await pw.loginPage.passwordInput).toBeFocused();
// * Should move focus to password toggle button after tab
await loginPage.passwordInput.press('Tab');
expect(await loginPage.passwordToggleButton).toBeFocused();
await pw.loginPage.passwordInput.press('Tab');
expect(await pw.loginPage.passwordToggleButton).toBeFocused();
// * Should move focus to forgot password link after tab
await loginPage.passwordToggleButton.press('Tab');
expect(await loginPage.forgotPasswordLink).toBeFocused();
await pw.loginPage.passwordToggleButton.press('Tab');
expect(await pw.loginPage.forgotPasswordLink).toBeFocused();
// * Should move focus to forgot password link after tab
await loginPage.forgotPasswordLink.press('Tab');
expect(await loginPage.signInButton).toBeFocused();
await pw.loginPage.forgotPasswordLink.press('Tab');
expect(await pw.loginPage.signInButton).toBeFocused();
// * Should move focus to about link after tab
await loginPage.signInButton.press('Tab');
expect(await loginPage.footer.aboutLink).toBeFocused();
await pw.loginPage.signInButton.press('Tab');
expect(await pw.loginPage.footer.aboutLink).toBeFocused();
// * Should move focus to privacy policy link after tab
await loginPage.footer.aboutLink.press('Tab');
expect(await loginPage.footer.privacyPolicyLink).toBeFocused();
await pw.loginPage.footer.aboutLink.press('Tab');
expect(await pw.loginPage.footer.privacyPolicyLink).toBeFocused();
// * Should move focus to terms link after tab
await loginPage.footer.privacyPolicyLink.press('Tab');
expect(await loginPage.footer.termsLink).toBeFocused();
await pw.loginPage.footer.privacyPolicyLink.press('Tab');
expect(await pw.loginPage.footer.termsLink).toBeFocused();
// * Should move focus to help link after tab
await loginPage.footer.termsLink.press('Tab');
expect(await loginPage.footer.helpLink).toBeFocused();
await pw.loginPage.footer.termsLink.press('Tab');
expect(await pw.loginPage.footer.helpLink).toBeFocused();
// # Move focus to login input
await loginPage.loginInput.focus();
expect(await loginPage.loginInput).toBeFocused();
await pw.loginPage.loginInput.focus();
expect(await pw.loginPage.loginInput).toBeFocused();
// * Should move focus to login body after shift+tab
await loginPage.loginInput.press('Shift+Tab');
expect(await loginPage.bodyCard).toBeFocused();
await pw.loginPage.loginInput.press('Shift+Tab');
expect(await pw.loginPage.bodyCard).toBeFocused();
// * Should move focus to create account link after shift+tab
await loginPage.bodyCard.press('Shift+Tab');
expect(await loginPage.createAccountLink).toBeFocused();
await pw.loginPage.bodyCard.press('Shift+Tab');
expect(await pw.loginPage.createAccountLink).toBeFocused();
// * Should move focus to login body after tab
await loginPage.createAccountLink.press('Shift+Tab');
expect(await loginPage.header.logo).toBeFocused();
await pw.loginPage.createAccountLink.press('Shift+Tab');
expect(await pw.loginPage.header.logo).toBeFocused();
});

View File

@ -3,53 +3,59 @@
import {expect, test} from '@e2e-support/test_fixture';
test('/reset_password accessibility quick check', async ({pages, page, axe}) => {
test('/reset_password accessibility quick check', async ({pw, axe}) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// # Go to reset password page
const resetPasswordPage = new pages.ResetPasswordPage(page);
await resetPasswordPage.goto();
await resetPasswordPage.toBeVisible();
await pw.resetPasswordPage.goto();
await pw.resetPasswordPage.toBeVisible();
// # Analyze the page
const accessibilityScanResults = await axe.builder(resetPasswordPage.page, {disableColorContrast: true}).analyze();
const accessibilityScanResults = await axe
.builder(pw.resetPasswordPage.page, {disableColorContrast: true})
.analyze();
// * Should have no violation
expect(accessibilityScanResults.violations).toHaveLength(0);
});
test('/reset_password accessibility tab support', async ({pages, page}) => {
test('/reset_password accessibility tab support', async ({pw}) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// # Go to reset password page
const resetPasswordPage = new pages.ResetPasswordPage(page);
await resetPasswordPage.goto();
await resetPasswordPage.toBeVisible();
await pw.resetPasswordPage.goto();
await pw.resetPasswordPage.toBeVisible();
// * Should have focused at email input on page load
expect(await resetPasswordPage.emailInput).toBeFocused();
expect(await pw.resetPasswordPage.emailInput).toBeFocused();
// * Should move focus to reset button after tab
await resetPasswordPage.emailInput.press('Tab');
expect(await resetPasswordPage.resetButton).toBeFocused();
await pw.resetPasswordPage.emailInput.press('Tab');
expect(await pw.resetPasswordPage.resetButton).toBeFocused();
// * Should move focus to about link after tab
await resetPasswordPage.resetButton.press('Tab');
expect(await resetPasswordPage.footer.aboutLink).toBeFocused();
await pw.resetPasswordPage.resetButton.press('Tab');
expect(await pw.resetPasswordPage.footer.aboutLink).toBeFocused();
// * Should move focus to privacy policy link after tab
await resetPasswordPage.footer.aboutLink.press('Tab');
expect(await resetPasswordPage.footer.privacyPolicyLink).toBeFocused();
await pw.resetPasswordPage.footer.aboutLink.press('Tab');
expect(await pw.resetPasswordPage.footer.privacyPolicyLink).toBeFocused();
// * Should move focus to terms link after tab
await resetPasswordPage.footer.privacyPolicyLink.press('Tab');
expect(await resetPasswordPage.footer.termsLink).toBeFocused();
await pw.resetPasswordPage.footer.privacyPolicyLink.press('Tab');
expect(await pw.resetPasswordPage.footer.termsLink).toBeFocused();
// * Should move focus to help link after tab
await resetPasswordPage.footer.termsLink.press('Tab');
expect(await resetPasswordPage.footer.helpLink).toBeFocused();
await pw.resetPasswordPage.footer.termsLink.press('Tab');
expect(await pw.resetPasswordPage.footer.helpLink).toBeFocused();
// # Move focus to email input
await resetPasswordPage.emailInput.focus();
expect(await resetPasswordPage.emailInput).toBeFocused();
await pw.resetPasswordPage.emailInput.focus();
expect(await pw.resetPasswordPage.emailInput).toBeFocused();
// * Should move focus to back button after shift+tab
await resetPasswordPage.emailInput.press('Shift+Tab');
expect(await resetPasswordPage.header.backButton).toBeFocused();
await pw.resetPasswordPage.emailInput.press('Shift+Tab');
expect(await pw.resetPasswordPage.header.backButton).toBeFocused();
});

View File

@ -3,109 +3,113 @@
import {expect, test} from '@e2e-support/test_fixture';
test('/signup_user_complete accessibility quick check', async ({pages, page, axe}) => {
test('/signup_user_complete accessibility quick check', async ({pw, axe}) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// # Go to reset password page
const signupPage = new pages.SignupPage(page);
await signupPage.goto();
await signupPage.toBeVisible();
await pw.signupPage.goto();
await pw.signupPage.toBeVisible();
// # Analyze the page
const accessibilityScanResults = await axe
.builder(signupPage.page, {disableColorContrast: true, disableLinkInTextBlock: true})
.builder(pw.signupPage.page, {disableColorContrast: true, disableLinkInTextBlock: true})
.analyze();
// * Should have no violation
expect(accessibilityScanResults.violations).toHaveLength(0);
});
test('/signup_user_complete accessibility tab support', async ({pages, page}, testInfo) => {
test('/signup_user_complete accessibility tab support', async ({pw}, testInfo) => {
// Set up the page not to redirect to the landing page
await pw.hasSeenLandingPage();
// # Go to reset password page
const signupPage = new pages.SignupPage(page);
await signupPage.goto();
await signupPage.toBeVisible();
await pw.signupPage.goto();
await pw.signupPage.toBeVisible();
// * Should have focused at email input on page load
expect(await signupPage.emailInput).toBeFocused();
expect(await pw.signupPage.emailInput).toBeFocused();
// * Should move focus to username input after tab
await signupPage.emailInput.press('Tab');
expect(await signupPage.usernameInput).toBeFocused();
await pw.signupPage.emailInput.press('Tab');
expect(await pw.signupPage.usernameInput).toBeFocused();
// * Should move focus to password input after tab
await signupPage.usernameInput.press('Tab');
expect(await signupPage.passwordInput).toBeFocused();
await pw.signupPage.usernameInput.press('Tab');
expect(await pw.signupPage.passwordInput).toBeFocused();
// * Should move focus to password toggle button after tab
await signupPage.passwordInput.press('Tab');
expect(await signupPage.passwordToggleButton).toBeFocused();
await pw.signupPage.passwordInput.press('Tab');
expect(await pw.signupPage.passwordToggleButton).toBeFocused();
// * Should move focus to newsletter checkbox after tab
await signupPage.passwordToggleButton.press('Tab');
expect(await signupPage.newsLetterCheckBox).toBeFocused();
await pw.signupPage.passwordToggleButton.press('Tab');
expect(await pw.signupPage.newsLetterCheckBox).toBeFocused();
// * Should move focus to newsletter privacy policy link after tab
await signupPage.newsLetterCheckBox.press('Tab');
expect(await signupPage.newsLetterPrivacyPolicyLink).toBeFocused();
await pw.signupPage.newsLetterCheckBox.press('Tab');
expect(await pw.signupPage.newsLetterPrivacyPolicyLink).toBeFocused();
// * Should move focus to newsletter unsubscribe link after tab
await signupPage.newsLetterPrivacyPolicyLink.press('Tab');
expect(await signupPage.newsLetterUnsubscribeLink).toBeFocused();
await pw.signupPage.newsLetterPrivacyPolicyLink.press('Tab');
expect(await pw.signupPage.newsLetterUnsubscribeLink).toBeFocused();
// * Should move focus to agreement terms of use link after tab
await signupPage.newsLetterUnsubscribeLink.press('Tab');
expect(await signupPage.agreementTermsOfUseLink).toBeFocused();
await pw.signupPage.newsLetterUnsubscribeLink.press('Tab');
expect(await pw.signupPage.agreementTermsOfUseLink).toBeFocused();
// * Should move focus to agreement privacy policy link after tab
await signupPage.agreementTermsOfUseLink.press('Tab');
expect(await signupPage.agreementPrivacyPolicyLink).toBeFocused();
await pw.signupPage.agreementTermsOfUseLink.press('Tab');
expect(await pw.signupPage.agreementPrivacyPolicyLink).toBeFocused();
// * Should move focus to privacy policy link after tab
await signupPage.footer.aboutLink.press('Tab');
expect(await signupPage.footer.privacyPolicyLink).toBeFocused();
await pw.signupPage.footer.aboutLink.press('Tab');
expect(await pw.signupPage.footer.privacyPolicyLink).toBeFocused();
// * Should move focus to terms link after tab
await signupPage.footer.privacyPolicyLink.press('Tab');
expect(await signupPage.footer.termsLink).toBeFocused();
await pw.signupPage.footer.privacyPolicyLink.press('Tab');
expect(await pw.signupPage.footer.termsLink).toBeFocused();
// * Should move focus to help link after tab
await signupPage.footer.termsLink.press('Tab');
expect(await signupPage.footer.helpLink).toBeFocused();
await pw.signupPage.footer.termsLink.press('Tab');
expect(await pw.signupPage.footer.helpLink).toBeFocused();
// # Move focus to email input
await signupPage.emailInput.focus();
expect(await signupPage.emailInput).toBeFocused();
await pw.signupPage.emailInput.focus();
expect(await pw.signupPage.emailInput).toBeFocused();
// * Should move focus to sign up body after shift+tab
await signupPage.emailInput.press('Shift+Tab');
expect(await signupPage.bodyCard).toBeFocused();
await pw.signupPage.emailInput.press('Shift+Tab');
expect(await pw.signupPage.bodyCard).toBeFocused();
// * Should move focus to sign up body after shift+tab
await signupPage.emailInput.press('Shift+Tab');
expect(await signupPage.bodyCard).toBeFocused();
await pw.signupPage.emailInput.press('Shift+Tab');
expect(await pw.signupPage.bodyCard).toBeFocused();
if (testInfo.project.name === 'ipad') {
// * Should move focus to header back button after shift+tab
await signupPage.bodyCard.press('Shift+Tab');
expect(await signupPage.header.backButton).toBeFocused();
await pw.signupPage.bodyCard.press('Shift+Tab');
expect(await pw.signupPage.header.backButton).toBeFocused();
// * Should move focus to log in link after shift+tab
await signupPage.header.backButton.press('Shift+Tab');
expect(await signupPage.loginLink).toBeFocused();
await pw.signupPage.header.backButton.press('Shift+Tab');
expect(await pw.signupPage.loginLink).toBeFocused();
// * Should move focus to header logo after shift+tab
await signupPage.loginLink.press('Shift+Tab');
expect(await signupPage.header.logo).toBeFocused();
await pw.signupPage.loginLink.press('Shift+Tab');
expect(await pw.signupPage.header.logo).toBeFocused();
} else {
// * Should move focus to log in link after shift+tab
await signupPage.bodyCard.press('Shift+Tab');
expect(await signupPage.loginLink).toBeFocused();
await pw.signupPage.bodyCard.press('Shift+Tab');
expect(await pw.signupPage.loginLink).toBeFocused();
// * Should move focus to header back button after shift+tab
await signupPage.loginLink.press('Shift+Tab');
expect(await signupPage.header.backButton).toBeFocused();
await pw.signupPage.loginLink.press('Shift+Tab');
expect(await pw.signupPage.header.backButton).toBeFocused();
// * Should move focus to header logo after shift+tab
await signupPage.header.backButton.press('Shift+Tab');
expect(await signupPage.header.logo).toBeFocused();
await pw.signupPage.header.backButton.press('Shift+Tab');
expect(await pw.signupPage.header.logo).toBeFocused();
}
});

View File

@ -22,7 +22,7 @@ const mimeType = 'image/png';
const {file} = getFileDataFromAsset(filename, mimeType);
const {blob} = getBlobDataFromAsset(filename, mimeType);
test.beforeAll(async ({pw}) => {
test.beforeEach(async ({pw}) => {
({userClient, user, team} = await pw.initSetup());
townSquareChannel = await userClient.getChannelByName(team.id, 'town-square');
});

View File

@ -4,7 +4,7 @@
import {expect, test} from '@e2e-support/test_fixture';
import {createRandomUser} from '@e2e-support/server';
test('MM-T53377 Profile popover should show correct fields after at-mention autocomplete', async ({pw, pages}) => {
test('MM-T53377 Profile popover should show correct fields after at-mention autocomplete', async ({pw}) => {
// # Initialize with specific config and get admin client
const {user, adminClient, team} = await pw.initSetup();
@ -20,22 +20,21 @@ test('MM-T53377 Profile popover should show correct fields after at-mention auto
await adminClient.addToTeam(team.id, testUser2.id);
// # Log in as user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Send mentions quickly
await channelPage.centerView.postCreate.postMessage(`@${user.username} @${testUser2.username}`);
await channelsPage.centerView.postCreate.postMessage(`@${user.username} @${testUser2.username}`);
// # Open profile popover for current user
const firstMention = channelPage.centerView.container.getByText(`@${user.username}`, {exact: true});
const firstMention = channelsPage.centerView.container.getByText(`@${user.username}`, {exact: true});
await firstMention.click();
// * Verify all fields are visible for current user
const popover = channelPage.userProfilePopover;
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();
@ -44,7 +43,7 @@ test('MM-T53377 Profile popover should show correct fields after at-mention auto
await popover.close();
// # Open profile popover for other user
const secondMention = channelPage.centerView.container.getByText(`@${testUser2.username}`, {exact: true});
const secondMention = channelsPage.centerView.container.getByText(`@${testUser2.username}`, {exact: true});
await secondMention.click();
// * Verify only username is visible for other user
@ -55,14 +54,14 @@ test('MM-T53377 Profile popover should show correct fields after at-mention auto
await popover.close();
// # Trigger autocomplete
await channelPage.centerView.postCreate.writeMessage(`@${user.username}`);
await channelsPage.centerView.postCreate.writeMessage(`@${user.username}`);
// # Wait for autocomplete
const suggestionList = channelPage.centerView.postCreate.suggestionList;
const suggestionList = channelsPage.centerView.postCreate.suggestionList;
await expect(suggestionList.getByText(`@${user.username}`)).toBeVisible();
// # Clear textbox
await channelPage.centerView.postCreate.writeMessage('');
await channelsPage.centerView.postCreate.writeMessage('');
// # Open profile popover for current user again
await firstMention.click();

View File

@ -6,7 +6,6 @@ import {createRandomPost} from '@e2e-support/server/post';
test('MM-T5435_1 Global Drafts link in sidebar should be hidden when another user deleted root post and user removes the deleted post ', async ({
pw,
pages,
}) => {
const {adminClient, team, adminUser, user} = await pw.initSetup();
@ -26,14 +25,13 @@ test('MM-T5435_1 Global Drafts link in sidebar should be hidden when another use
);
// # Log in as user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
const lastPostByAdmin = await channelPage.centerView.getLastPost();
const lastPostByAdmin = await channelsPage.centerView.getLastPost();
await lastPostByAdmin.toBeVisible();
// # Open the last post sent by admin in RHS
@ -42,7 +40,7 @@ test('MM-T5435_1 Global Drafts link in sidebar should be hidden when another use
await lastPostByAdmin.postMenu.reply();
// # Post a message as a user
const sidebarRight = channelPage.sidebarRight;
const sidebarRight = channelsPage.sidebarRight;
await sidebarRight.toBeVisible();
await sidebarRight.postCreate.postMessage('Replying to a thread');
@ -54,7 +52,7 @@ test('MM-T5435_1 Global Drafts link in sidebar should be hidden when another use
await sidebarRight.close();
// * Verify drafts link in channel sidebar is visible
await channelPage.sidebarLeft.draftsVisible();
await channelsPage.sidebarLeft.draftsVisible();
// # Delete the last post by admin
try {
@ -75,30 +73,29 @@ test('MM-T5435_1 Global Drafts link in sidebar should be hidden when another use
await deletedPostByAdminInRHS.remove();
// * Verify the drafts links should also be removed from sidebar
await channelPage.sidebarLeft.draftsNotVisible();
await channelsPage.sidebarLeft.draftsNotVisible();
});
test('MM-T5435_2 Global Drafts link in sidebar should be hidden when user deletes root post ', async ({pw, pages}) => {
test('MM-T5435_2 Global Drafts link in sidebar should be hidden when user deletes root post ', async ({pw}) => {
const {user} = await pw.initSetup();
// # Log in as user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Post a message in the channel
await channelPage.centerView.postCreate.postMessage('Message which will be deleted');
await channelsPage.centerView.postCreate.postMessage('Message which will be deleted');
// # Start a thread by clicking on reply menuitem from post options menu
const post = await channelPage.centerView.getLastPost();
const post = await channelsPage.centerView.getLastPost();
await post.hover();
await post.postMenu.toBeVisible();
await post.postMenu.reply();
const sidebarRight = channelPage.sidebarRight;
const sidebarRight = channelsPage.sidebarRight;
await sidebarRight.toBeVisible();
// # Post a message in the thread
@ -111,19 +108,19 @@ test('MM-T5435_2 Global Drafts link in sidebar should be hidden when user delete
await sidebarRight.close();
// * Verify drafts link in channel sidebar is visible
await channelPage.sidebarLeft.draftsVisible();
await channelsPage.sidebarLeft.draftsVisible();
// # Click on the dot menu of the post and select delete
await post.hover();
await post.postMenu.toBeVisible();
await post.postMenu.openDotMenu();
await channelPage.postDotMenu.toBeVisible();
await channelPage.postDotMenu.deleteMenuItem.click();
await channelsPage.postDotMenu.toBeVisible();
await channelsPage.postDotMenu.deleteMenuItem.click();
// # Confirm the delete from the modal
await channelPage.deletePostModal.toBeVisible();
await channelPage.deletePostModal.confirm();
await channelsPage.deletePostModal.toBeVisible();
await channelsPage.deletePostModal.confirm();
// * Verify drafts link in channel sidebar is visible
await channelPage.sidebarLeft.draftsNotVisible();
await channelsPage.sidebarLeft.draftsNotVisible();
});

View File

@ -5,37 +5,36 @@ import {expect, test} from '@e2e-support/test_fixture';
test.fixme(
'MM-T5445 Should search, select and post correct Gif when Gif picker is opened from center textbox',
async ({pw, pages}) => {
async ({pw}) => {
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open emoji/gif picker
await channelPage.centerView.postCreate.openEmojiPicker();
await channelPage.emojiGifPickerPopup.toBeVisible();
await channelsPage.centerView.postCreate.openEmojiPicker();
await channelsPage.emojiGifPickerPopup.toBeVisible();
// # Open gif tab
await channelPage.emojiGifPickerPopup.openGifTab();
await channelsPage.emojiGifPickerPopup.openGifTab();
// # Search for gif
await channelPage.emojiGifPickerPopup.searchGif('hello');
await channelsPage.emojiGifPickerPopup.searchGif('hello');
// # Select the first gif
const {img: firstSearchGifResult, alt: altOfFirstSearchGifResult} =
await channelPage.emojiGifPickerPopup.getNthGif(0);
await channelsPage.emojiGifPickerPopup.getNthGif(0);
await firstSearchGifResult.click();
// # Send the selected gif as a message
await channelPage.centerView.postCreate.sendMessage();
await channelsPage.centerView.postCreate.sendMessage();
// * Verify that last message has the gif
const lastPost = await channelPage.centerView.getLastPost();
const lastPost = await channelsPage.centerView.getLastPost();
await lastPost.toBeVisible();
await expect(lastPost.body.getByLabel('file thumbnail')).toHaveAttribute('alt', altOfFirstSearchGifResult);
},
@ -43,27 +42,26 @@ test.fixme(
test.fixme(
'MM-T5446 Should search, select and post correct Gif when Gif picker is opened from RHS textbox',
async ({pw, pages}) => {
async ({pw}) => {
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Send a message
await channelPage.centerView.postCreate.postMessage('Message to open RHS');
await channelsPage.centerView.postCreate.postMessage('Message to open RHS');
// # Open the last post sent in RHS
const lastPost = await channelPage.centerView.getLastPost();
const lastPost = await channelsPage.centerView.getLastPost();
await lastPost.hover();
await lastPost.postMenu.toBeVisible();
await lastPost.postMenu.reply();
const sidebarRight = channelPage.sidebarRight;
const sidebarRight = channelsPage.sidebarRight;
await sidebarRight.toBeVisible();
// # Send a message in the thread
@ -73,17 +71,17 @@ test.fixme(
// # Open emoji/gif picker
await sidebarRight.postCreate.openEmojiPicker();
await channelPage.emojiGifPickerPopup.toBeVisible();
await channelsPage.emojiGifPickerPopup.toBeVisible();
// # Open gif tab
await channelPage.emojiGifPickerPopup.openGifTab();
await channelsPage.emojiGifPickerPopup.openGifTab();
// # Search for gif
await channelPage.emojiGifPickerPopup.searchGif('hello');
await channelsPage.emojiGifPickerPopup.searchGif('hello');
// # Select the first gif
const {img: firstSearchGifResult, alt: altOfFirstSearchGifResult} =
await channelPage.emojiGifPickerPopup.getNthGif(0);
await channelsPage.emojiGifPickerPopup.getNthGif(0);
await firstSearchGifResult.click();
// # Send the selected gif as a message in the thread

View File

@ -4,48 +4,47 @@
import {expect, test} from '@e2e-support/test_fixture';
import MessagePriority from '@e2e-support/ui/components/channels/message_priority';
test('MM-T5139: Message Priority - Standard message priority and system setting', async ({pw, pages}) => {
test('MM-T5139: Message Priority - Standard message priority and system setting', async ({pw}) => {
// # Setup test environment
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {page, channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
const messagePriority = new MessagePriority(page.locator('body'));
// Open menu
await channelPage.centerView.postCreate.openPriorityMenu();
await channelsPage.centerView.postCreate.openPriorityMenu();
// Use messagePriority for dialog interactions
await messagePriority.verifyPriorityDialog();
await messagePriority.verifyStandardOptionSelected();
// # Close menu and post message
await channelPage.centerView.postCreate.priorityButton.click();
await channelsPage.centerView.postCreate.priorityButton.click();
const testMessage = 'This is just a test message';
await channelPage.postMessage(testMessage);
await channelsPage.postMessage(testMessage);
// # Verify message posts without priority label
const lastPost = await channelPage.centerView.getLastPost();
const lastPost = await channelsPage.centerView.getLastPost();
await lastPost.toBeVisible();
await lastPost.toContainText(testMessage);
await expect(lastPost.container.locator('.post-priority')).not.toBeVisible();
// # Open post in RHS and verify
await lastPost.container.click();
await channelPage.sidebarRight.toBeVisible();
await channelsPage.sidebarRight.toBeVisible();
// # Get RHS post and verify content
const rhsPost = await channelPage.sidebarRight.getLastPost();
const rhsPost = await channelsPage.sidebarRight.getLastPost();
await rhsPost.toBeVisible();
await rhsPost.toContainText(testMessage);
await expect(rhsPost.container.locator('.post-priority')).not.toBeVisible();
// # Verify RHS formatting bar doesn't have priority button
await expect(channelPage.sidebarRight.postCreate.priorityButton).not.toBeVisible();
await expect(channelsPage.sidebarRight.postCreate.priorityButton).not.toBeVisible();
});

View File

@ -3,7 +3,7 @@
import {expect, test} from '@e2e-support/test_fixture';
test('MM-T483 Channel-wide mentions with uppercase letters', async ({pw, pages, headless, browserName}) => {
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.',
@ -13,23 +13,21 @@ test('MM-T483 Channel-wide mentions with uppercase letters', async ({pw, pages,
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} = await pw.testBrowser.login(adminUser);
const adminChannelPage = new pages.ChannelsPage(adminPage);
await adminChannelPage.goto(team.name, 'town-square');
await adminChannelPage.toBeVisible();
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');
// Log in as the regular user in a separate browser and navigate to the "off-topic" channel
const {page: otherPage} = await pw.testBrowser.login(user);
const otherChannelPage = new pages.ChannelsPage(otherPage);
await otherChannelPage.goto(team.name, 'off-topic');
await otherChannelPage.toBeVisible();
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 otherChannelPage.postMessage(message);
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);
@ -44,14 +42,14 @@ test('MM-T483 Channel-wide mentions with uppercase letters', async ({pw, pages,
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 otherChannelPage.centerView.getLastPost();
const otherLastPost = await otherChannelsPage.centerView.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 adminChannelPage.goto(team.name, 'off-topic');
const adminLastPost = await adminChannelPage.centerView.getLastPost();
await adminChannelsPage.goto(team.name, 'off-topic');
const adminLastPost = await adminChannelsPage.centerView.getLastPost();
await adminLastPost.toContainText(message);
await expect(adminLastPost.container.locator('.mention--highlight')).toBeVisible();
await expect(adminLastPost.container.locator('.mention--highlight').getByText('@ALL')).toBeVisible();

View File

@ -3,7 +3,7 @@ import {test} from '@e2e-support/test_fixture';
import {ChannelsPage, ScheduledDraftPage} from '@e2e-support/ui/pages';
import {duration, wait} from '@e2e-support/util';
test.fixme('MM-T5643_1 should create a scheduled message from a channel', async ({pw, pages}) => {
test.fixme('MM-T5643_1 should create a scheduled message from a channel', async ({pw}) => {
test.setTimeout(120000);
const draftMessage = 'Scheduled Draft';
@ -11,18 +11,16 @@ test.fixme('MM-T5643_1 should create a scheduled message from a channel', async
await pw.skipIfNoLicense();
const {user, team} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const {page, channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelPage, draftMessage);
await scheduleMessage(channelPage);
await setupChannelPage(channelsPage, draftMessage);
await scheduleMessage(channelsPage);
await channelPage.centerView.verifyscheduledDraftChannelInfo();
await channelsPage.centerView.verifyscheduledDraftChannelInfo();
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
// # Hover and verify options
await scheduledDraftPage.verifyOnHoverActionItems(draftMessage);
@ -31,14 +29,14 @@ test.fixme('MM-T5643_1 should create a scheduled message from a channel', async
await goBackToChannelAndWaitForMessageToArrive(page);
// * Verify the message has been sent and there's no more scheduled messages
await expect(channelPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelPage.getLastPost()).toHaveText(draftMessage);
await expect(channelsPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelsPage.getLastPost()).toHaveText(draftMessage);
await verifyNoscheduledDraftsPending(channelPage, team, scheduledDraftPage, draftMessage);
await verifyNoscheduledDraftsPending(channelsPage, team, scheduledDraftPage, draftMessage);
});
test.fixme('MM-T5643_6 should create a scheduled message under a thread post ', async ({pw, pages}) => {
test.fixme('MM-T5643_6 should create a scheduled message under a thread post ', async ({pw}) => {
test.setTimeout(120000);
const draftMessage = 'Scheduled Threaded Message';
@ -48,20 +46,19 @@ test.fixme('MM-T5643_6 should create a scheduled message under a thread post ',
const {user, team} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {page, channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelPage.centerView.postCreate.postMessage('Root Message');
await channelsPage.centerView.postCreate.postMessage('Root Message');
// # Start a thread by clicking on reply menuitem from post options menu
const post = await channelPage.centerView.getLastPost();
const post = await channelsPage.centerView.getLastPost();
await replyToLastPost(post);
const sidebarRight = channelPage.sidebarRight;
const sidebarRight = channelsPage.sidebarRight;
await sidebarRight.toBeVisible();
// # Post a message in the thread
@ -74,19 +71,18 @@ test.fixme('MM-T5643_6 should create a scheduled message under a thread post ',
await sidebarRight.postCreate.scheduleDraftMessageButton.isVisible();
await sidebarRight.postCreate.scheduleDraftMessageButton.click();
await scheduleMessage(channelPage);
await scheduleMessage(channelsPage);
await sidebarRight.scheduledDraftChannelInfo.isVisible();
await sidebarRight.postBoxIndicator.isVisible();
const messageLocator = sidebarRight.scheduledDraftChannelInfoMessage.first();
await expect(messageLocator).toContainText('Message scheduled for');
// Save the time displayed in the thread
const scheduledDraftThreadedPanelInfo = await sidebarRight.scheduledDraftChannelInfo.innerText();
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const scheduledDraftThreadedPanelInfo = await sidebarRight.postBoxIndicator.innerText();
await channelPage.sidebarRight.clickOnSeeAllscheduledDrafts();
await channelsPage.sidebarRight.clickOnSeeAllscheduledDrafts();
const scheduledDraftPageInfo = await scheduledDraftPage.scheduledDraftPageInfo.innerHTML();
await channelPage.sidebarLeft.assertscheduledDraftCountLHS('1');
await channelsPage.sidebarLeft.assertscheduledDraftCountLHS('1');
await scheduledDraftPage.toBeVisible();
await scheduledDraftPage.assertBadgeCountOnTab('1');
@ -103,64 +99,60 @@ test.fixme('MM-T5643_6 should create a scheduled message under a thread post ',
await replyToLastPost(post);
// * Verify the message has been sent and there's no more scheduled messages
await expect(channelPage.sidebarRight.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(channelsPage.sidebarRight.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
const lastPost = channelPage.sidebarRight.rhsPostBody.last();
const lastPost = channelsPage.sidebarRight.rhsPostBody.last();
await expect(lastPost).toHaveText(draftMessage);
await expect(scheduledDraftPage.scheduledDraftPanel(draftMessage)).not.toBeVisible();
await verifyNoscheduledDraftsPending(channelPage, team, scheduledDraftPage, draftMessage);
await verifyNoscheduledDraftsPending(channelsPage, team, scheduledDraftPage, draftMessage);
});
test.fixme('MM-T5644 should rechedule a scheduled message', async ({pw, pages}) => {
test.fixme('MM-T5644 should reschedule a scheduled message', async ({pw}) => {
const draftMessage = 'Scheduled Draft';
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const {channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelPage, draftMessage);
await scheduleMessage(channelPage);
await setupChannelPage(channelsPage, draftMessage);
await scheduleMessage(channelsPage);
// * Verify the Initial Date and time of scheduled Draft
await channelPage.centerView.verifyscheduledDraftChannelInfo();
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await channelsPage.centerView.verifyscheduledDraftChannelInfo();
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
await scheduledDraftPage.openRescheduleModal(draftMessage);
// # Reschedule it to 2 days from today
await channelPage.scheduledDraftModal.selectDay(2);
await channelPage.scheduledDraftModal.confirm();
await channelsPage.scheduledDraftModal.selectDay(2);
await channelsPage.scheduledDraftModal.confirm();
// # Note the new Scheduled time
const scheduledDraftPageInfo = await scheduledDraftPage.getTimeStampOfMessage(draftMessage);
// # Go to Channel
await channelPage.goto();
await channelsPage.goto();
// * Verify the New Time reflecting in the channel
const rescheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
const rescheduledDraftChannelInfo = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await compareMessageTimestamps(rescheduledDraftChannelInfo, scheduledDraftPageInfo, scheduledDraftPage);
});
test.fixme('MM-T5645 should delete a scheduled message', async ({pw, pages}) => {
test.fixme('MM-T5645 should delete a scheduled message', async ({pw}) => {
const draftMessage = 'Scheduled Draft';
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const {channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelPage, draftMessage);
await scheduleMessage(channelPage);
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await setupChannelPage(channelsPage, draftMessage);
await scheduleMessage(channelsPage);
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
await scheduledDraftPage.deleteScheduledMessage(draftMessage);
@ -168,32 +160,30 @@ test.fixme('MM-T5645 should delete a scheduled message', async ({pw, pages}) =>
await expect(scheduledDraftPage.noscheduledDraftIcon).toBeVisible();
});
test.fixme('MM-T5643_9 should send a scheduled message immediately', async ({pw, pages}) => {
test.fixme('MM-T5643_9 should send a scheduled message immediately', async ({pw}) => {
const draftMessage = 'Scheduled Draft';
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const {channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelPage, draftMessage);
await scheduleMessage(channelPage);
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await setupChannelPage(channelsPage, draftMessage);
await scheduleMessage(channelsPage);
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
await scheduledDraftPage.sendScheduledMessage(draftMessage);
await expect(scheduledDraftPage.scheduledDraftPanel(draftMessage)).not.toBeVisible();
// Verify message has arrived
await expect(channelPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelPage.getLastPost()).toHaveText(draftMessage);
await expect(channelsPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelsPage.getLastPost()).toHaveText(draftMessage);
});
test.fixme('MM-T5643_3 should create a scheduled message from a DM', async ({pw, pages}) => {
test.fixme('MM-T5643_3 should create a scheduled message from a DM', async ({pw}) => {
test.setTimeout(120000);
const draftMessage = 'Scheduled Draft';
@ -203,18 +193,16 @@ test.fixme('MM-T5643_3 should create a scheduled message from a DM', async ({pw,
const {user, team} = await pw.initSetup();
const {user: user2} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const {page, channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelPage, draftMessage, team.name, `@${user2.username}`);
await scheduleMessage(channelPage);
await setupChannelPage(channelsPage, draftMessage, team.name, `@${user2.username}`);
await scheduleMessage(channelsPage);
await channelPage.centerView.verifyscheduledDraftChannelInfo();
await channelsPage.centerView.verifyscheduledDraftChannelInfo();
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
// # Hover and verify options
await scheduledDraftPage.verifyOnHoverActionItems(draftMessage);
@ -223,49 +211,46 @@ test.fixme('MM-T5643_3 should create a scheduled message from a DM', async ({pw,
await goBackToChannelAndWaitForMessageToArrive(page);
// * Verify the message has been sent and there's no more scheduled messages
await expect(channelPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelPage.getLastPost()).toHaveText(draftMessage);
await expect(channelsPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelsPage.getLastPost()).toHaveText(draftMessage);
await verifyNoscheduledDraftsPending(channelPage, team, scheduledDraftPage, draftMessage);
await verifyNoscheduledDraftsPending(channelsPage, team, scheduledDraftPage, draftMessage);
});
test('MM-T5648 should create a draft and then schedule it', async ({pw, pages}) => {
test('MM-T5648 should create a draft and then schedule it', async ({pw}) => {
test.setTimeout(120000);
const draftMessage = 'Draft to be Scheduled';
await pw.skipIfNoLicense();
const {user, team} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const {channelsPage, draftPage, scheduledDraftPage} = await pw.testBrowser.login(user);
// await setupChannelPage(channelPage, draftMessage);
await channelPage.goto();
await channelPage.toBeVisible();
await channelPage.centerView.postCreate.writeMessage(draftMessage);
// await setupChannelPage(channelsPage, draftMessage);
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.writeMessage(draftMessage);
// go to drafts page
const draftsPage = new pages.DraftPage(page);
await draftsPage.goTo(team.name);
await draftsPage.toBeVisible();
await draftsPage.assertBadgeCountOnTab('1');
await draftsPage.assertDraftBody(draftMessage);
await draftsPage.verifyScheduleIcon(draftMessage);
await draftsPage.openScheduleModal(draftMessage);
await draftPage.goTo(team.name);
await draftPage.toBeVisible();
await draftPage.assertBadgeCountOnTab('1');
await draftPage.assertDraftBody(draftMessage);
await draftPage.verifyScheduleIcon(draftMessage);
await draftPage.openScheduleModal(draftMessage);
// # Reschedule it to 2 days from today
await channelPage.scheduledDraftModal.selectDay(2);
await channelPage.scheduledDraftModal.confirm();
await channelsPage.scheduledDraftModal.selectDay(2);
await channelsPage.scheduledDraftModal.confirm();
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
await scheduledDraftPage.goTo(team.name);
await scheduledDraftPage.toBeVisible();
await scheduledDraftPage.assertBadgeCountOnTab('1');
await scheduledDraftPage.assertscheduledDraftBody(draftMessage);
});
test.fixme('MM-T5644 should edit scheduled message', async ({pw, pages}) => {
test.fixme('MM-T5644 should edit scheduled message', async ({pw}) => {
test.setTimeout(120000);
const draftMessage = 'Scheduled Draft';
@ -273,18 +258,16 @@ test.fixme('MM-T5644 should edit scheduled message', async ({pw, pages}) => {
await pw.skipIfNoLicense();
const {user, team} = await pw.initSetup();
const {page} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
const {page, channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
await setupChannelPage(channelPage, draftMessage);
await scheduleMessage(channelPage);
await setupChannelPage(channelsPage, draftMessage);
await scheduleMessage(channelsPage);
await channelPage.centerView.verifyscheduledDraftChannelInfo();
await channelsPage.centerView.verifyscheduledDraftChannelInfo();
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
// # Hover and verify options
await scheduledDraftPage.verifyOnHoverActionItems(draftMessage);
@ -296,60 +279,57 @@ test.fixme('MM-T5644 should edit scheduled message', async ({pw, pages}) => {
await goBackToChannelAndWaitForMessageToArrive(page);
// * Verify the message has been sent and there's no more scheduled messages
await expect(channelPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelPage.getLastPost()).toHaveText(draftMessage);
await expect(channelsPage.centerView.scheduledDraftChannelInfoMessage).not.toBeVisible();
await expect(channelsPage.sidebarLeft.scheduledDraftCountonLHS).not.toBeVisible();
await expect(await channelsPage.getLastPost()).toHaveText(draftMessage);
await verifyNoscheduledDraftsPending(channelPage, team, scheduledDraftPage, draftMessage);
await verifyNoscheduledDraftsPending(channelsPage, team, scheduledDraftPage, draftMessage);
});
test.fixme('MM-T5650 should copy scheduled message', async ({pw, pages, browserName}) => {
test.fixme('MM-T5650 should copy scheduled message', async ({pw, browserName}) => {
test.setTimeout(120000);
// Skip this test in Firefox clipboard permissions are not supported
test.skip(browserName === 'firefox', 'Test not supported in Firefox');
const draftMessage = 'Scheduled Draft';
// # Skip test if no license
await pw.skipIfNoLicense();
const draftMessage = 'Scheduled Draft';
const {user} = await pw.initSetup();
const {page, context} = await pw.testBrowser.login(user);
await context.grantPermissions(['clipboard-read', 'clipboard-write']);
const {page, channelsPage, scheduledDraftPage} = await pw.testBrowser.login(user);
const channelPage = new pages.ChannelsPage(page);
const scheduledDraftPage = new pages.ScheduledDraftPage(page);
await setupChannelPage(channelsPage, draftMessage);
await scheduleMessage(channelsPage);
await setupChannelPage(channelPage, draftMessage);
await scheduleMessage(channelPage);
await channelsPage.centerView.verifyscheduledDraftChannelInfo();
await channelPage.centerView.verifyscheduledDraftChannelInfo();
const postBoxIndicator = await channelsPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
const scheduledDraftChannelInfo = await channelPage.centerView.scheduledDraftChannelInfoMessageText.innerText();
await verifyscheduledDrafts(channelPage, pages, draftMessage, scheduledDraftChannelInfo);
await verifyScheduledDraft(channelsPage, scheduledDraftPage, draftMessage, postBoxIndicator);
await scheduledDraftPage.copyScheduledMessage(draftMessage);
await page.goBack();
await channelPage.centerView.postCreate.input.focus();
await channelsPage.centerView.postCreate.input.focus();
await page.keyboard.down('Meta');
await page.keyboard.press('V');
await page.keyboard.up('Meta');
// * Assert the message typed is same as the copied message
await expect(channelPage.centerView.postCreate.input).toHaveText(draftMessage);
await expect(channelsPage.centerView.postCreate.input).toHaveText(draftMessage);
});
async function verifyNoscheduledDraftsPending(
channelPage: ChannelsPage,
channelsPage: ChannelsPage,
team: any,
scheduledDraftPage: ScheduledDraftPage,
draftMessage: string,
): Promise<void> {
await channelPage.goto(team.name, 'scheduled_posts');
await channelsPage.goto(team.name, 'scheduled_posts');
await expect(scheduledDraftPage.scheduledDraftPanel(draftMessage)).not.toBeVisible();
await expect(scheduledDraftPage.noscheduledDraftIcon).toBeVisible();
}
@ -367,16 +347,16 @@ async function replyToLastPost(post: any): Promise<void> {
}
async function setupChannelPage(
channelPage: ChannelsPage,
channelsPage: ChannelsPage,
draftMessage: string,
teamName?: string,
channelName?: string,
): Promise<void> {
await channelPage.goto(teamName, channelName);
await channelPage.toBeVisible();
await channelsPage.goto(teamName, channelName);
await channelsPage.toBeVisible();
await channelPage.centerView.postCreate.writeMessage(draftMessage);
await channelPage.centerView.postCreate.clickOnScheduleDraftDropdownButton();
await channelsPage.centerView.postCreate.writeMessage(draftMessage);
await channelsPage.centerView.postCreate.clickOnScheduleDraftDropdownButton();
}
/**
@ -395,21 +375,19 @@ async function scheduleMessage(pageObject: ChannelsPage): Promise<void> {
/**
* Extracts and verifies the scheduled message on the scheduled page and in the channel.
*/
async function verifyscheduledDrafts(
channelPage: ChannelsPage,
pages: any,
async function verifyScheduledDraft(
channelsPage: ChannelsPage,
scheduledDraftPage: ScheduledDraftPage,
draftMessage: string,
scheduledDraftChannelInfo: string,
postBoxIndicator: string,
): Promise<void> {
const scheduledDraftPage = new pages.ScheduledDraftPage(channelPage.page);
await verifyscheduledDraftCount(channelPage, '1');
await verifyscheduledDraftCount(channelsPage, '1');
await scheduledDraftPage.toBeVisible();
await scheduledDraftPage.assertBadgeCountOnTab('1');
await scheduledDraftPage.assertscheduledDraftBody(draftMessage);
const scheduledDraftPageInfo = await scheduledDraftPage.getTimeStampOfMessage(draftMessage);
await compareMessageTimestamps(scheduledDraftChannelInfo, scheduledDraftPageInfo, scheduledDraftPage);
await compareMessageTimestamps(postBoxIndicator, scheduledDraftPageInfo, scheduledDraftPage);
}
/**

View File

@ -6,7 +6,6 @@ import {createRandomChannel} from '@e2e-support/server';
test('MM-T5424 Find channel search returns only 50 results when there are more than 50 channels with similar names', async ({
pw,
pages,
}) => {
const {adminClient, user, team} = await pw.initSetup();
@ -29,10 +28,9 @@ test('MM-T5424 Find channel search returns only 50 results when there are more t
await Promise.all(channelsRes);
// # Log in a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit a default channel page
const channelsPage = new pages.ChannelsPage(page);
await channelsPage.goto();
await channelsPage.toBeVisible();

View File

@ -3,14 +3,13 @@
import {expect, test} from '@e2e-support/test_fixture';
test('Search box suggestion must be case insensitive', async ({pw, pages}) => {
test('Search box suggestion must be case insensitive', async ({pw}) => {
const {user} = await pw.initSetup();
// # Log in a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit a default channel page
const channelsPage = new pages.ChannelsPage(page);
await channelsPage.goto();
await channelsPage.toBeVisible();

View File

@ -11,33 +11,32 @@ const keywords = [`AB${getRandomId()}`, `CD${getRandomId()}`, `EF${getRandomId()
const highlightWithoutNotificationClass = 'non-notification-highlight';
test('MM-T5465-1 Should add the keyword when enter, comma or tab is pressed on the textbox', async ({pw, pages}) => {
test('MM-T5465-1 Should add the keyword when enter, comma or tab is pressed on the textbox', async ({pw}) => {
// # Skip test if no license
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelPage.centerView.postCreate.postMessage('Hello World');
await channelsPage.centerView.postCreate.postMessage('Hello World');
// # Open settings modal
await channelPage.globalHeader.openSettings();
await channelPage.settingsModal.toBeVisible();
await channelsPage.globalHeader.openSettings();
await channelsPage.settingsModal.toBeVisible();
// # Open notifications tab
await channelPage.settingsModal.openNotificationsTab();
await channelsPage.settingsModal.openNotificationsTab();
// # Open keywords that get highlighted section
await channelPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
await channelsPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
const keywordsInput = await channelPage.settingsModal.notificationsSettings.getKeywordsInput();
const keywordsInput = await channelsPage.settingsModal.notificationsSettings.getKeywordsInput();
// # Enter keyword 1
await keywordsInput.fill(keywords[0]);
@ -58,55 +57,51 @@ test('MM-T5465-1 Should add the keyword when enter, comma or tab is pressed on t
await keywordsInput.press('Enter');
// * Verify that the keywords have been added to the collapsed description
const keysWithHighlightDesc = channelPage.settingsModal.notificationsSettings.keysWithHighlightDesc;
const keysWithHighlightDesc = channelsPage.settingsModal.notificationsSettings.keysWithHighlightDesc;
await keysWithHighlightDesc.waitFor();
for (const keyword of keywords.slice(0, 3)) {
expect(await keysWithHighlightDesc).toContainText(keyword);
}
});
test('MM-T5465-2 Should highlight the keywords when a message is sent with the keyword in center', async ({
pw,
pages,
}) => {
test('MM-T5465-2 Should highlight the keywords when a message is sent with the keyword in center', async ({pw}) => {
// # Skip test if no license
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open settings modal
await channelPage.globalHeader.openSettings();
await channelPage.settingsModal.toBeVisible();
await channelsPage.globalHeader.openSettings();
await channelsPage.settingsModal.toBeVisible();
// # Open notifications tab
await channelPage.settingsModal.openNotificationsTab();
await channelsPage.settingsModal.openNotificationsTab();
// # Open keywords that get highlighted section
await channelPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
await channelsPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
// # Enter the keyword
const keywordsInput = await channelPage.settingsModal.notificationsSettings.getKeywordsInput();
const keywordsInput = await channelsPage.settingsModal.notificationsSettings.getKeywordsInput();
await keywordsInput.fill(keywords[3]);
await keywordsInput.press('Tab');
// # Save the keyword
await channelPage.settingsModal.notificationsSettings.save();
await channelsPage.settingsModal.notificationsSettings.save();
// # Close the settings modal
await channelPage.settingsModal.closeModal();
await channelsPage.settingsModal.closeModal();
// # Post a message without the keyword
const messageWithoutKeyword = 'This message does not contain the keyword';
await channelPage.centerView.postCreate.postMessage(messageWithoutKeyword);
const lastPostWithoutHighlight = await channelPage.centerView.getLastPost();
await channelsPage.centerView.postCreate.postMessage(messageWithoutKeyword);
const lastPostWithoutHighlight = await channelsPage.centerView.getLastPost();
// * Verify that the keywords are not highlighted
await expect(lastPostWithoutHighlight.container.getByText(messageWithoutKeyword)).toBeVisible();
@ -116,116 +111,114 @@ 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 channelPage.centerView.postCreate.postMessage(messageWithKeyword);
const lastPostWithHighlight = await channelPage.centerView.getLastPost();
await channelsPage.centerView.postCreate.postMessage(messageWithKeyword);
const lastPostWithHighlight = await channelsPage.centerView.getLastPost();
// * Verify that the keywords are highlighted
await expect(lastPostWithHighlight.container.getByText(messageWithKeyword)).toBeVisible();
await expect(lastPostWithHighlight.container.getByText(keywords[3])).toHaveClass(highlightWithoutNotificationClass);
});
test('MM-T5465-3 Should highlight the keywords when a message is sent with the keyword in rhs', async ({pw, pages}) => {
test('MM-T5465-3 Should highlight the keywords when a message is sent with the keyword in rhs', async ({pw}) => {
// # Skip test if no license
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open settings modal
await channelPage.globalHeader.openSettings();
await channelPage.settingsModal.toBeVisible();
await channelsPage.globalHeader.openSettings();
await channelsPage.settingsModal.toBeVisible();
// # Open notifications tab
await channelPage.settingsModal.openNotificationsTab();
await channelsPage.settingsModal.openNotificationsTab();
// # Open keywords that get highlighted section
await channelPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
await channelsPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
// # Enter the keyword
const keywordsInput = await channelPage.settingsModal.notificationsSettings.getKeywordsInput();
const keywordsInput = await channelsPage.settingsModal.notificationsSettings.getKeywordsInput();
await keywordsInput.fill(keywords[3]);
await keywordsInput.press('Tab');
// # Save the keyword
await channelPage.settingsModal.notificationsSettings.save();
await channelsPage.settingsModal.notificationsSettings.save();
// # Close the settings modal
await channelPage.settingsModal.closeModal();
await channelsPage.settingsModal.closeModal();
// # Post a message without the keyword
const messageWithoutKeyword = 'This message does not contain the keyword';
await channelPage.centerView.postCreate.postMessage(messageWithoutKeyword);
const lastPostWithoutHighlight = await channelPage.centerView.getLastPost();
await channelsPage.centerView.postCreate.postMessage(messageWithoutKeyword);
const lastPostWithoutHighlight = await channelsPage.centerView.getLastPost();
// # Open the message in the RHS
await lastPostWithoutHighlight.hover();
await lastPostWithoutHighlight.postMenu.toBeVisible();
await lastPostWithoutHighlight.postMenu.reply();
await channelPage.sidebarRight.toBeVisible();
await channelsPage.sidebarRight.toBeVisible();
// # Post a message with the keyword in the RHS
const messageWithKeyword = `This message contains the keyword ${keywords[3]}`;
await channelPage.sidebarRight.postCreate.postMessage(messageWithKeyword);
await channelsPage.sidebarRight.postCreate.postMessage(messageWithKeyword);
// * Verify that the keywords are highlighted
const lastPostWithHighlightInRHS = await channelPage.sidebarRight.getLastPost();
const lastPostWithHighlightInRHS = await channelsPage.sidebarRight.getLastPost();
await expect(lastPostWithHighlightInRHS.container.getByText(messageWithKeyword)).toBeVisible();
await expect(lastPostWithHighlightInRHS.container.getByText(keywords[3])).toHaveClass(
highlightWithoutNotificationClass,
);
});
test('MM-T5465-4 Highlighted keywords should not appear in the Recent Mentions', async ({pw, pages}) => {
test('MM-T5465-4 Highlighted keywords should not appear in the Recent Mentions', async ({pw}) => {
// # Skip test if no license
await pw.skipIfNoLicense();
const {user} = await pw.initSetup();
// # Log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open settings modal
await channelPage.globalHeader.openSettings();
await channelPage.settingsModal.toBeVisible();
await channelsPage.globalHeader.openSettings();
await channelsPage.settingsModal.toBeVisible();
// # Open notifications tab
await channelPage.settingsModal.openNotificationsTab();
await channelsPage.settingsModal.openNotificationsTab();
// # Open keywords that get highlighted section
await channelPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
await channelsPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
// # Enter the keyword
const keywordsInput = await channelPage.settingsModal.notificationsSettings.getKeywordsInput();
const keywordsInput = await channelsPage.settingsModal.notificationsSettings.getKeywordsInput();
await keywordsInput.fill(keywords[0]);
await keywordsInput.press('Tab');
// # Save the keyword
await channelPage.settingsModal.notificationsSettings.save();
await channelsPage.settingsModal.notificationsSettings.save();
// # Close the settings modal
await channelPage.settingsModal.closeModal();
await channelsPage.settingsModal.closeModal();
// # Open the recent mentions
await channelPage.globalHeader.openRecentMentions();
await channelsPage.globalHeader.openRecentMentions();
// * Verify recent mentions is empty
await channelPage.sidebarRight.toBeVisible();
await expect(channelPage.sidebarRight.container.getByText('No mentions yet')).toBeVisible();
await channelsPage.sidebarRight.toBeVisible();
await expect(channelsPage.sidebarRight.container.getByText('No mentions yet')).toBeVisible();
});
test('MM-T5465-5 Should highlight keywords in message sent from another user', async ({pw, pages}) => {
test('MM-T5465-5 Should highlight keywords in message sent from another user', async ({pw}) => {
// # Skip test if no license
await pw.skipIfNoLicense();
@ -239,7 +232,7 @@ test('MM-T5465-5 Should highlight keywords in message sent from another user', a
const channel = await adminClient.getChannelByName(team.id, 'town-square');
const highlightKeyword = keywords[0];
const messageWithKeyword = `This recieved message contains the ${highlightKeyword} keyword `;
const messageWithKeyword = `This received message contains the ${highlightKeyword} keyword `;
// # Create a post containing the keyword in the channel by admin
await adminClient.createPost(
@ -251,36 +244,35 @@ test('MM-T5465-5 Should highlight keywords in message sent from another user', a
);
// # Now log in as a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {channelsPage} = await pw.testBrowser.login(user);
// # Visit default channel page
const channelPage = new pages.ChannelsPage(page);
await channelPage.goto();
await channelPage.toBeVisible();
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open settings modal
await channelPage.globalHeader.openSettings();
await channelPage.settingsModal.toBeVisible();
await channelsPage.globalHeader.openSettings();
await channelsPage.settingsModal.toBeVisible();
// # Open notifications tab
await channelPage.settingsModal.openNotificationsTab();
await channelsPage.settingsModal.openNotificationsTab();
// # Open keywords that get highlighted section
await channelPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
await channelsPage.settingsModal.notificationsSettings.expandSection('keysWithHighlight');
// # Enter the keyword
const keywordsInput = await channelPage.settingsModal.notificationsSettings.getKeywordsInput();
const keywordsInput = await channelsPage.settingsModal.notificationsSettings.getKeywordsInput();
await keywordsInput.fill(keywords[0]);
await keywordsInput.press('Tab');
// # Save the keyword
await channelPage.settingsModal.notificationsSettings.save();
await channelsPage.settingsModal.notificationsSettings.save();
// # Close the settings modal
await channelPage.settingsModal.closeModal();
await channelsPage.settingsModal.closeModal();
// * Verify that the keywords are highlighted in the last message recieved
const lastPostWithHighlight = await channelPage.centerView.getLastPost();
// * Verify that the keywords are highlighted in the last message received
const lastPostWithHighlight = await channelsPage.centerView.getLastPost();
await expect(lastPostWithHighlight.container.getByText(messageWithKeyword)).toBeVisible();
await expect(lastPostWithHighlight.container.getByText(highlightKeyword)).toHaveClass(
highlightWithoutNotificationClass,

View File

@ -1,5 +1,6 @@
import {Page} from '@playwright/test';
import {expect, test} from '@e2e-support/test_fixture';
import {duration} from '@e2e-support/util';
// Helper function to intercept API request and modify the response
async function interceptConfigWithLandingPage(page: Page, enabled: boolean) {
@ -16,9 +17,7 @@ async function interceptConfigWithLandingPage(page: Page, enabled: boolean) {
});
}
test('MM-T5640_1 should not see landing page ', async ({pw, pages, page}) => {
const {adminClient} = await pw.getAdminClient();
const adminConfig = await adminClient.getConfig();
test('MM-T5640_1 should not see landing page ', async ({pw, page}) => {
await interceptConfigWithLandingPage(page, false);
// Navigate to your starting URL
@ -31,25 +30,19 @@ test('MM-T5640_1 should not see landing page ', async ({pw, pages, page}) => {
expect(page.url()).toContain('/login');
// Verify the login page is visible
const loginPage = new pages.LoginPage(page, adminConfig);
await loginPage.toBeVisible();
await pw.loginPage.toBeVisible();
});
test('MM-T5640_2 should see landing page', async ({pages, isMobile, page}) => {
test('MM-T5640_2 should see landing page', async ({pw, page}) => {
// Navigate to your starting URL
await page.goto('/');
await page.evaluate(() => localStorage.clear());
await page.goto('/');
// Wait until the URL contains '/landing'
await page.waitForURL(/.*\/landing.*/);
await page.waitForURL(/.*\/landing.*/, {timeout: duration.ten_sec});
// At this point, the URL should contain '/landing'
expect(page.url()).toContain('/landing');
// Verify the landing page is visible
const landingLoginPage = new pages.LandingLoginPage(page, isMobile);
await landingLoginPage.toBeVisible();
await pw.landingLoginPage.toBeVisible();
});

View File

@ -4,8 +4,6 @@
import {TestBrowser} from '@e2e-support//browser_context';
import {Client, createRandomTeam, createRandomUser} from '@e2e-support/server';
import {expect, test} from '@e2e-support/test_fixture';
import {components} from '@e2e-support/ui/components';
import {SystemConsolePage} from '@e2e-support/ui/pages/system_console';
import {getRandomId} from '@e2e-support/util';
import {UserProfile} from '@mattermost/types/users';
@ -15,10 +13,10 @@ import {UserProfile} from '@mattermost/types/users';
* @param pages
* @returns A function to get the refreshed user, and the System Console page for navigation
*/
async function setupAndGetRandomUser(
pw: {testBrowser: TestBrowser; initSetup: () => Promise<{adminUser: UserProfile | null; adminClient: Client}>},
pages: {SystemConsolePage: typeof SystemConsolePage},
) {
async function setupAndGetRandomUser(pw: {
testBrowser: TestBrowser;
initSetup: () => Promise<{adminUser: UserProfile | null; adminClient: Client}>;
}) {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -26,7 +24,7 @@ async function setupAndGetRandomUser(
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create a random user to edit for
const user = await adminClient.createUser(createRandomUser(), '', '');
@ -34,7 +32,6 @@ async function setupAndGetRandomUser(
await adminClient.addToTeam(team.id, user.id);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -52,8 +49,8 @@ async function setupAndGetRandomUser(
return {getUser: () => adminClient.getUser(user.id), systemConsolePage};
}
test('MM-T5520-1 should activate and deactivate users', async ({pw, pages}) => {
const {getUser, systemConsolePage} = await setupAndGetRandomUser(pw, pages);
test('MM-T5520-1 should activate and deactivate users', async ({pw}) => {
const {getUser, systemConsolePage} = await setupAndGetRandomUser(pw);
// # Open menu and deactivate the user
await systemConsolePage.systemUsers.actionMenuButtons[0].click();
@ -61,8 +58,7 @@ test('MM-T5520-1 should activate and deactivate users', async ({pw, pages}) => {
await deactivate.click();
// # Press confirm on the modal
const confirmModal = new components.GenericConfirmModal(systemConsolePage.page);
await confirmModal.confirm();
await systemConsolePage.confirmModal.confirm();
// * Verify user is deactivated
const firstRow = await systemConsolePage.systemUsers.getNthRow(1);
@ -80,8 +76,8 @@ test('MM-T5520-1 should activate and deactivate users', async ({pw, pages}) => {
expect(await firstRow.innerText()).toContain('Member');
});
test('MM-T5520-2 should change user roles', async ({pw, pages}) => {
const {getUser, systemConsolePage} = await setupAndGetRandomUser(pw, pages);
test('MM-T5520-2 should change user roles', async ({pw}) => {
const {getUser, systemConsolePage} = await setupAndGetRandomUser(pw);
// # Open menu and click Manage roles
await systemConsolePage.systemUsers.actionMenuButtons[0].click();
@ -121,8 +117,8 @@ test('MM-T5520-2 should change user roles', async ({pw, pages}) => {
expect((await getUser()).roles).toContain('system_user');
});
test('MM-T5520-3 should be able to manage teams', async ({pw, pages}) => {
const {systemConsolePage} = await setupAndGetRandomUser(pw, pages);
test('MM-T5520-3 should be able to manage teams', async ({pw}) => {
const {systemConsolePage} = await setupAndGetRandomUser(pw);
// # Open menu and click Manage teams
await systemConsolePage.systemUsers.actionMenuButtons[0].click();
@ -157,8 +153,8 @@ test('MM-T5520-3 should be able to manage teams', async ({pw, pages}) => {
expect(team).not.toBeVisible();
});
test('MM-T5520-4 should reset the users password', async ({pw, pages}) => {
const {systemConsolePage} = await setupAndGetRandomUser(pw, pages);
test('MM-T5520-4 should reset the users password', async ({pw}) => {
const {systemConsolePage} = await setupAndGetRandomUser(pw);
// # Open menu and click Reset Password
await systemConsolePage.systemUsers.actionMenuButtons[0].click();
@ -174,8 +170,8 @@ test('MM-T5520-4 should reset the users password', async ({pw, pages}) => {
await passwordInput.waitFor({state: 'detached'});
});
test('MM-T5520-5 should change the users email', async ({pw, pages}) => {
const {getUser, systemConsolePage} = await setupAndGetRandomUser(pw, pages);
test('MM-T5520-5 should change the users email', async ({pw}) => {
const {getUser, systemConsolePage} = await setupAndGetRandomUser(pw);
const newEmail = `${getRandomId()}@example.com`;
// # Open menu and click Update Email
@ -197,8 +193,8 @@ test('MM-T5520-5 should change the users email', async ({pw, pages}) => {
expect((await getUser()).email).toEqual(newEmail);
});
test('MM-T5520-6 should revoke sessions', async ({pw, pages}) => {
const {systemConsolePage} = await setupAndGetRandomUser(pw, pages);
test('MM-T5520-6 should revoke sessions', async ({pw}) => {
const {systemConsolePage} = await setupAndGetRandomUser(pw);
// # Open menu and revoke sessions
await systemConsolePage.systemUsers.actionMenuButtons[0].click();
@ -206,8 +202,7 @@ test('MM-T5520-6 should revoke sessions', async ({pw, pages}) => {
await removeSessions.click();
// # Press confirm on the modal
const confirmModal = new components.GenericConfirmModal(systemConsolePage.page);
await confirmModal.confirm();
await systemConsolePage.confirmModal.confirm();
const firstRow = await systemConsolePage.systemUsers.getNthRow(1);
expect(await firstRow.innerHTML()).not.toContain('class="error"');

View File

@ -7,7 +7,7 @@ import {test} from '@e2e-support/test_fixture';
import {createRandomUser} from '@e2e-support/server';
import {simpleEmailRe} from '@e2e-support/util';
test('MM-T5523-1 Sortable columns should sort the list when clicked', async ({pw, pages}) => {
test('MM-T5523-1 Sortable columns should sort the list when clicked', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -15,7 +15,7 @@ test('MM-T5523-1 Sortable columns should sort the list when clicked', async ({pw
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 10 random users
for (let i = 0; i < 10; i++) {
@ -23,7 +23,6 @@ test('MM-T5523-1 Sortable columns should sort the list when clicked', async ({pw
}
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -52,7 +51,7 @@ test('MM-T5523-1 Sortable columns should sort the list when clicked', async ({pw
expect(firstRowEmailWithoutSort).not.toBe(firstRowEmailWithSort);
});
test('MM-T5523-2 Non sortable columns should not sort the list when clicked', async ({pw, pages}) => {
test('MM-T5523-2 Non sortable columns should not sort the list when clicked', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -60,7 +59,7 @@ test('MM-T5523-2 Non sortable columns should not sort the list when clicked', as
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 10 random users
for (let i = 0; i < 10; i++) {
@ -68,7 +67,6 @@ test('MM-T5523-2 Non sortable columns should not sort the list when clicked', as
}
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();

View File

@ -5,7 +5,7 @@ import {expect} from '@playwright/test';
import {test} from '@e2e-support/test_fixture';
test('MM-T5523-3 Should list the column names with checkboxes in the correct order', async ({pw, pages}) => {
test('MM-T5523-3 Should list the column names with checkboxes in the correct order', async ({pw}) => {
const {adminUser} = await pw.initSetup();
if (!adminUser) {
@ -13,10 +13,9 @@ test('MM-T5523-3 Should list the column names with checkboxes in the correct ord
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -47,7 +46,7 @@ test('MM-T5523-3 Should list the column names with checkboxes in the correct ord
]);
});
test('MM-T5523-4 Should allow certain columns to be checked and others to be disabled', async ({pw, pages}) => {
test('MM-T5523-4 Should allow certain columns to be checked and others to be disabled', async ({pw}) => {
const {adminUser} = await pw.initSetup();
if (!adminUser) {
@ -55,10 +54,9 @@ test('MM-T5523-4 Should allow certain columns to be checked and others to be dis
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -83,7 +81,7 @@ test('MM-T5523-4 Should allow certain columns to be checked and others to be dis
expect(emailMenuItem).not.toBeDisabled();
});
test('MM-T5523-5 Should show/hide the columns which are toggled on/off', async ({pw, pages}) => {
test('MM-T5523-5 Should show/hide the columns which are toggled on/off', async ({pw}) => {
const {adminUser} = await pw.initSetup();
if (!adminUser) {
@ -91,10 +89,9 @@ test('MM-T5523-5 Should show/hide the columns which are toggled on/off', async (
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();

View File

@ -5,9 +5,8 @@ import {expect} from '@playwright/test';
import {test} from '@e2e-support/test_fixture';
import {duration} from '@e2e-support/util';
import {components} from '@e2e-support/ui/components';
test.fixme('MM-T5522 Should begin export of data when export button is pressed', async ({pw, pages}) => {
test.fixme('MM-T5522 Should begin export of data when export button is pressed', async ({pw}) => {
test.slow();
// # Skip test if no license
@ -19,10 +18,9 @@ test.fixme('MM-T5522 Should begin export of data when export button is pressed',
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {page, channelsPage, systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -36,8 +34,7 @@ test.fixme('MM-T5522 Should begin export of data when export button is pressed',
// # Click Export button and confirm the modal
await systemConsolePage.systemUsers.exportButton.click();
const confirmModal = new components.GenericConfirmModal(page, 'exportUserDataModal');
await confirmModal.confirm();
await systemConsolePage.exportModal.confirm();
// # Change the export duration to all time
await systemConsolePage.systemUsers.dateRangeSelectorMenuButton.click();
@ -45,17 +42,16 @@ test.fixme('MM-T5522 Should begin export of data when export button is pressed',
// # Click Export button and confirm the modal
await systemConsolePage.systemUsers.exportButton.click();
await confirmModal.confirm();
await systemConsolePage.exportModal.confirm();
// # Click Export again button and confirm the modal
await systemConsolePage.systemUsers.exportButton.click();
await confirmModal.confirm();
await systemConsolePage.exportModal.confirm();
// * Verify that we are told that one is already running
expect(page.getByText('Export is in progress')).toBeVisible();
// # Go back to Channels and open the system bot DM
const channelsPage = new pages.ChannelsPage(page);
channelsPage.goto('ad-1/messages', '@system-bot');
await channelsPage.centerView.toBeVisible();

View File

@ -4,7 +4,7 @@
import {test} from '@e2e-support/test_fixture';
import {createRandomTeam, createRandomUser} from '@e2e-support/server';
test('MM-T5521-7 Should be able to filter users with team filter', async ({pw, pages}) => {
test('MM-T5521-7 Should be able to filter users with team filter', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -12,7 +12,7 @@ test('MM-T5521-7 Should be able to filter users with team filter', async ({pw, p
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create a team with a user
const team1 = await adminClient.createTeam(createRandomTeam());
@ -25,7 +25,6 @@ test('MM-T5521-7 Should be able to filter users with team filter', async ({pw, p
await adminClient.addToTeam(team2.id, user2.id);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -53,7 +52,7 @@ test('MM-T5521-7 Should be able to filter users with team filter', async ({pw, p
await systemConsolePage.systemUsers.verifyRowWithTextIsNotFound(user2.email);
});
test('MM-T5521-8 Should be able to filter users with role filter', async ({pw, pages}) => {
test('MM-T5521-8 Should be able to filter users with role filter', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -61,7 +60,7 @@ test('MM-T5521-8 Should be able to filter users with role filter', async ({pw, p
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create a guest user
const guestUser = await adminClient.createUser(createRandomUser(), '', '');
@ -71,7 +70,6 @@ test('MM-T5521-8 Should be able to filter users with role filter', async ({pw, p
const regularUser = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -109,7 +107,7 @@ test('MM-T5521-8 Should be able to filter users with role filter', async ({pw, p
await systemConsolePage.systemUsers.verifyRowWithTextIsFound('No data');
});
test('MM-T5521-9 Should be able to filter users with status filter', async ({pw, pages}) => {
test('MM-T5521-9 Should be able to filter users with status filter', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -117,7 +115,7 @@ test('MM-T5521-9 Should be able to filter users with status filter', async ({pw,
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create a user and then deactivate it
const deactivatedUser = await adminClient.createUser(createRandomUser(), '', '');
@ -127,7 +125,6 @@ test('MM-T5521-9 Should be able to filter users with status filter', async ({pw,
const regularUser = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();

View File

@ -5,7 +5,7 @@ import {test} from '@e2e-support/test_fixture';
import {createRandomUser} from '@e2e-support/server';
import {getRandomId} from '@e2e-support/util';
test('MM-T5521-1 Should be able to search users with their first names', async ({pw, pages}) => {
test('MM-T5521-1 Should be able to search users with their first names', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -13,14 +13,13 @@ test('MM-T5521-1 Should be able to search users with their first names', async (
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 2 users
const user1 = await adminClient.createUser(createRandomUser(), '', '');
const user2 = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -38,7 +37,7 @@ test('MM-T5521-1 Should be able to search users with their first names', async (
await systemConsolePage.systemUsers.verifyRowWithTextIsNotFound(user2.email);
});
test('MM-T5521-2 Should be able to search users with their last names', async ({pw, pages}) => {
test('MM-T5521-2 Should be able to search users with their last names', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -46,14 +45,13 @@ test('MM-T5521-2 Should be able to search users with their last names', async ({
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 2 users
const user1 = await adminClient.createUser(createRandomUser(), '', '');
const user2 = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -71,7 +69,7 @@ test('MM-T5521-2 Should be able to search users with their last names', async ({
await systemConsolePage.systemUsers.verifyRowWithTextIsNotFound(user2.email);
});
test('MM-T5521-3 Should be able to search users with their emails', async ({pw, pages}) => {
test('MM-T5521-3 Should be able to search users with their emails', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -79,14 +77,13 @@ test('MM-T5521-3 Should be able to search users with their emails', async ({pw,
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 2 users
const user1 = await adminClient.createUser(createRandomUser(), '', '');
const user2 = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -104,7 +101,7 @@ test('MM-T5521-3 Should be able to search users with their emails', async ({pw,
await systemConsolePage.systemUsers.verifyRowWithTextIsNotFound(user2.email);
});
test('MM-T5521-4 Should be able to search users with their usernames', async ({pw, pages}) => {
test('MM-T5521-4 Should be able to search users with their usernames', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -112,14 +109,13 @@ test('MM-T5521-4 Should be able to search users with their usernames', async ({p
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 2 users
const user1 = await adminClient.createUser(createRandomUser(), '', '');
const user2 = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -137,7 +133,7 @@ test('MM-T5521-4 Should be able to search users with their usernames', async ({p
await systemConsolePage.systemUsers.verifyRowWithTextIsNotFound(user2.email);
});
test('MM-T5521-5 Should be able to search users with their nick names', async ({pw, pages}) => {
test('MM-T5521-5 Should be able to search users with their nick names', async ({pw}) => {
const {adminUser, adminClient} = await pw.initSetup();
if (!adminUser) {
@ -145,14 +141,13 @@ test('MM-T5521-5 Should be able to search users with their nick names', async ({
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Create 2 users
const user1 = await adminClient.createUser(createRandomUser(), '', '');
const user2 = await adminClient.createUser(createRandomUser(), '', '');
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();
@ -169,7 +164,7 @@ test('MM-T5521-5 Should be able to search users with their nick names', async ({
await systemConsolePage.systemUsers.verifyRowWithTextIsNotFound(user2.email);
});
test('MM-T5521-6 Should show no user is found when user doesnt exists', async ({pw, pages}) => {
test('MM-T5521-6 Should show no user is found when user doesnt exists', async ({pw}) => {
const {adminUser} = await pw.initSetup();
if (!adminUser) {
@ -177,10 +172,9 @@ test('MM-T5521-6 Should show no user is found when user doesnt exists', async ({
}
// # Log in as admin
const {page} = await pw.testBrowser.login(adminUser);
const {systemConsolePage} = await pw.testBrowser.login(adminUser);
// # Visit system console
const systemConsolePage = new pages.SystemConsolePage(page);
await systemConsolePage.goto();
await systemConsolePage.toBeVisible();

View File

@ -3,15 +3,14 @@
import {expect, test} from '@e2e-support/test_fixture';
test.fixme('Intro to channel as regular user', async ({pw, pages, browserName, viewport}, testInfo) => {
test.fixme('Intro to channel as regular user', async ({pw, browserName, viewport}, testInfo) => {
// Create and sign in a new user
const {user} = await pw.initSetup();
// Log in a user in new browser context
const {page} = await pw.testBrowser.login(user);
const {page, channelsPage} = await pw.testBrowser.login(user);
// Visit a default channel page
const channelsPage = new pages.ChannelsPage(page);
await channelsPage.goto();
await channelsPage.toBeVisible();
@ -22,6 +21,6 @@ test.fixme('Intro to channel as regular user', async ({pw, pages, browserName, v
await pw.hideDynamicChannelsContent(page);
// Match snapshot of channel intro page
const testArgs = {page, browserName, viewport};
const testArgs = {page: page, browserName, viewport};
await pw.matchSnapshot(testInfo, testArgs);
});

View File

@ -3,11 +3,10 @@
import {test} from '@e2e-support/test_fixture';
test('/landing#/login', async ({pw, pages, page, isMobile, browserName, viewport}, testInfo) => {
test('/landing#/login', async ({pw, page, browserName, viewport}, testInfo) => {
// Go to landing login page
const landingLoginPage = new pages.LandingLoginPage(page, isMobile);
await landingLoginPage.goto();
await landingLoginPage.toBeVisible();
await pw.landingLoginPage.goto();
await pw.landingLoginPage.toBeVisible();
// Match snapshot of landing page
await pw.matchSnapshot(testInfo, {page, browserName, viewport});

View File

@ -3,27 +3,28 @@
import {test} from '@e2e-support/test_fixture';
test('/login', async ({pw, pages, page, browserName, viewport}, testInfo) => {
test('/login', 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();
const adminConfig = await adminClient.getConfig();
const license = await adminClient.getClientLicenseOld();
const loginPage = new pages.LoginPage(page, adminConfig);
await loginPage.goto();
await loginPage.toBeVisible();
await pw.loginPage.goto();
await pw.loginPage.toBeVisible();
// Click to other element to remove focus from email input
await loginPage.title.click();
await pw.loginPage.title.click();
// Match snapshot of login 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);
// Click sign in button without entering user credential
await loginPage.signInButton.click();
await loginPage.userErrorLabel.waitFor();
await pw.waitForAnimationEnd(loginPage.bodyCard);
await pw.loginPage.signInButton.click();
await pw.loginPage.userErrorLabel.waitFor();
await pw.waitForAnimationEnd(pw.loginPage.bodyCard);
// Match snapshot of login page with error
await pw.matchSnapshot({...testInfo, title: `${testInfo.title} error ${editionSuffix}`}, testArgs);

View File

@ -3,37 +3,37 @@
import {test} from '@e2e-support/test_fixture';
test('/signup_email', async ({pw, pages, page, browserName, viewport}, testInfo) => {
test('/signup_email', 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();
const adminConfig = await adminClient.getConfig();
const license = await adminClient.getClientLicenseOld();
const loginPage = new pages.LoginPage(page, adminConfig);
await loginPage.goto();
await loginPage.toBeVisible();
await pw.loginPage.goto();
await pw.loginPage.toBeVisible();
// Create an account
await loginPage.createAccountLink.click();
await pw.loginPage.createAccountLink.click();
// Should have redirected to signup page
const signupPage = new pw.pages.SignupPage(page);
await signupPage.toBeVisible();
await pw.signupPage.toBeVisible();
// Click to other element to remove focus from email input
await signupPage.title.click();
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);
// Click sign in button without entering user credential
const invalidUser = {email: 'invalid', username: 'a', password: 'b'};
await signupPage.create(invalidUser, false);
await signupPage.emailError.waitFor();
await signupPage.usernameError.waitFor();
await signupPage.passwordError.waitFor();
await pw.waitForAnimationEnd(signupPage.bodyCard);
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);
// Match snapshot of signup_email page
await pw.matchSnapshot({...testInfo, title: `${testInfo.title} error ${editionSuffix}`}, testArgs);