End to End test for Admin Reporting for Users, new User Management screen (#26077)

https://mattermost.atlassian.net/browse/MM-56672
https://mattermost.atlassian.net/browse/MM-56666
https://mattermost.atlassian.net/browse/MM-56673
Этот коммит содержится в:
M-ZubairAhmed
2024-02-12 08:28:47 +00:00
коммит произвёл GitHub
родитель 4c8a134659
Коммит 90b21cad33
19 изменённых файлов: 1371 добавлений и 1 удалений

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

@@ -0,0 +1,46 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator, Page} from '@playwright/test';
/**
* This is the generic confirm modal that is used in the app.
* It has optional cancel button, optional checkbox and confirm button along with title and message body.
* It can present in different parts of the app such as channel, system console, etc and hence its constructor
* should be able to accept the page object of the app and an optional id to uniquely identify the modal.
*/
export default class GenericConfirmModal {
readonly container: Locator;
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');
}
async toBeVisible() {
await expect(this.container).toBeVisible();
}
async confirm() {
await this.confirmButton.waitFor();
await this.confirmButton.click();
// Wait for the modal to disappear
await expect(this.container).not.toBeVisible();
}
async cancel() {
await this.cancelButton.waitFor();
await this.cancelButton.click();
// Wait for the modal to disappear
await expect(this.container).not.toBeVisible();
}
}
export {GenericConfirmModal};

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

@@ -19,6 +19,15 @@ import {PostReminderMenu} from './channels/post_reminder_menu';
import {PostMenu} from './channels/post_menu';
import {ThreadFooter} from './channels/thread_footer';
import {EmojiGifPicker} from './channels/emoji_gif_picker';
import {GenericConfirmModal} from './channels/generic_confirm_modal';
import {SystemConsoleSidebar} from './system_console/sidebar';
import {SystemConsoleNavbar} from './system_console/navbar';
import {SystemUsers} from './system_console/sections/system_users/system_users';
import {SystemUsersFilterPopover} from './system_console/sections/system_users/filter_popover';
import {SystemUsersFilterMenu} from './system_console/sections/system_users/filter_menu';
import {SystemUsersColumnToggleMenu} from './system_console/sections/system_users/column_toggle_menu';
const components = {
GlobalHeader,
@@ -39,6 +48,13 @@ const components = {
MainHeader,
PostReminderMenu,
EmojiGifPicker,
GenericConfirmModal,
SystemConsoleSidebar,
SystemConsoleNavbar,
SystemUsers,
SystemUsersFilterPopover,
SystemUsersFilterMenu,
SystemUsersColumnToggleMenu,
};
export {

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

@@ -0,0 +1,18 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator} from '@playwright/test';
export default class SystemConsoleNavbar {
readonly container: Locator;
constructor(container: Locator) {
this.container = container;
}
async toBeVisible() {
await expect(this.container).toBeVisible();
}
}
export {SystemConsoleNavbar};

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

@@ -0,0 +1,52 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator} from '@playwright/test';
class SystemUsersColumnToggleMenu {
readonly container: Locator;
constructor(container: Locator) {
this.container = container;
}
async toBeVisible() {
await expect(this.container).toBeVisible();
}
/**
* Return the locator for the menu item with the given name.
*/
async getMenuItem(menuItem: string) {
const menuItemLocator = this.container.getByRole('menuitemcheckbox').filter({hasText: menuItem});
await menuItemLocator.waitFor();
return menuItemLocator;
}
/**
* Returns the list of locators for all the menu items.
*/
async getAllMenuItems() {
const menuItemLocators = this.container.getByRole('menuitemcheckbox');
return menuItemLocators;
}
/**
* Pass in the item name to check/uncheck the menu item.
*/
async clickMenuItem(menuItem: string) {
const menuItemLocator = await this.getMenuItem(menuItem);
await menuItemLocator.click();
}
/**
* Close column toggle menu.
*/
async close() {
await this.container.press('Escape');
await expect(this.container).not.toBeVisible();
}
}
export {SystemUsersColumnToggleMenu};

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

@@ -0,0 +1,46 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator} from '@playwright/test';
/**
* The dropdown menu which appears for both Role and Status filter.
*/
class SystemUsersFilterMenu {
readonly container: Locator;
constructor(container: Locator) {
this.container = container;
}
async toBeVisible() {
await expect(this.container).toBeVisible();
}
/**
* Return the locator for the menu item with the given name.
*/
async getMenuItem(menuItem: string) {
const menuItemLocator = this.container.getByText(menuItem);
await menuItemLocator.waitFor();
return menuItemLocator;
}
/**
* Clicks on the menu item with the given name.
*/
async clickMenuItem(menuItem: string) {
const menuItemLocator = await this.getMenuItem(menuItem);
await menuItemLocator.click();
}
/**
* Close the menu.
*/
async close() {
await this.container.press('Escape');
}
}
export {SystemUsersFilterMenu};

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

@@ -0,0 +1,70 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator} from '@playwright/test';
class SystemUsersFilterPopover {
readonly container: Locator;
readonly teamMenuInput: Locator;
readonly roleMenuButton: Locator;
readonly statusMenuButton: Locator;
readonly applyButton: Locator;
constructor(container: Locator) {
this.container = container;
this.teamMenuInput = this.container.locator('#asyncTeamSelectInput');
this.roleMenuButton = this.container.locator('#DropdownInput_filterRole');
this.statusMenuButton = this.container.locator('#DropdownInput_filterStatus');
this.applyButton = this.container.getByText('Apply');
}
async toBeVisible() {
await expect(this.container).toBeVisible();
await expect(this.applyButton).toBeVisible();
}
/**
* Save the filter settings.
*/
async save() {
await this.applyButton.click();
}
/**
* Allows to type in the team filter for searching.
*/
async searchInTeamMenu(teamDisplayName: string) {
expect(this.teamMenuInput).toBeVisible();
await this.teamMenuInput.fill(teamDisplayName);
}
/**
* Opens the role filter menu.
*/
async openRoleMenu() {
expect(this.roleMenuButton).toBeVisible();
await this.roleMenuButton.click();
}
/**
* Opens the status filter menu.
*/
async openStatusMenu() {
expect(this.statusMenuButton).toBeVisible();
await this.statusMenuButton.click();
}
/**
* Closes the filter popover.
*/
async close() {
await this.container.press('Escape');
await expect(this.container).not.toBeVisible();
}
}
export {SystemUsersFilterPopover};

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

@@ -0,0 +1,132 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator} from '@playwright/test';
/**
* System Console -> User Management -> Users
*/
export default class SystemUsers {
readonly container: Locator;
readonly searchInput: Locator;
readonly columnToggleMenuButton: Locator;
readonly dateRangeSelectorMenuButton: Locator;
readonly exportButton: Locator;
readonly filterPopoverButton: Locator;
readonly actionMenuButtons: Locator[];
readonly loadingSpinner: Locator;
constructor(container: Locator) {
this.container = container;
this.searchInput = this.container.getByLabel('Search users');
this.columnToggleMenuButton = this.container.locator('#systemUsersColumnTogglerMenuButton');
this.dateRangeSelectorMenuButton = this.container.locator('#systemUsersDateRangeSelectorMenuButton');
this.exportButton = this.container.getByText('Export');
this.filterPopoverButton = this.container.getByText(/Filters \(\d+\)/);
this.actionMenuButtons = Array.from(Array(10).keys()).map((index) =>
this.container.locator(`#actionMenuButton-systemUsersTable-${index}`),
);
this.loadingSpinner = this.container.getByText('Loading');
}
async toBeVisible() {
await expect(this.container).toBeVisible();
}
async isLoadingComplete() {
await expect(this.loadingSpinner).toHaveCount(0);
}
/**
* Returns the locator for the header of the given column.
*/
async getColumnHeader(columnName: string) {
const columnHeader = this.container.getByRole('columnheader').filter({hasText: columnName});
return columnHeader;
}
/**
* Checks if given column exists in the table. By searching for the column header.
*/
async doesColumnExist(columnName: string) {
const columnHeader = await this.getColumnHeader(columnName);
return await columnHeader.isVisible();
}
/**
* Clicks on the column header of the given column for sorting.
*/
async clickSortOnColumn(columnName: string) {
const columnHeader = await this.getColumnHeader(columnName);
await columnHeader.waitFor();
await columnHeader.click();
}
/**
* Return the locator for the given row number. If '0' is passed, it will return the header row.
*/
async getNthRow(rowNumber: number) {
const row = this.container.getByRole('row').nth(rowNumber);
await row.waitFor();
return row;
}
/**
* Opens the Filter popover
*/
async openFilterPopover() {
expect(this.filterPopoverButton).toBeVisible();
await this.filterPopoverButton.click();
}
/**
* Open the column toggle menu
*/
async openColumnToggleMenu() {
expect(this.columnToggleMenuButton).toBeVisible();
await this.columnToggleMenuButton.click();
}
/**
* Open the date range selector menu
*/
async openDateRangeSelectorMenu() {
expect(this.dateRangeSelectorMenuButton).toBeVisible();
await this.dateRangeSelectorMenuButton.click();
}
/**
* Enter the given search term in the search input
*/
async enterSearchText(searchText: string) {
expect(this.searchInput).toBeVisible();
await this.searchInput.fill(`${searchText}`);
await this.isLoadingComplete();
}
/**
* Searches and verifies that the row with given text is found
*/
async verifyRowWithTextIsFound(text: string) {
const foundUser = this.container.getByText(text);
await foundUser.waitFor();
await expect(foundUser).toBeVisible();
}
/**
* Searches and verifies that the row with given text is not found
*/
async verifyRowWithTextIsNotFound(text: string) {
const foundUser = this.container.getByText(text);
await expect(foundUser).not.toBeVisible();
}
}
export {SystemUsers};

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

@@ -0,0 +1,41 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {expect, Locator} from '@playwright/test';
export default class SystemConsoleSidebar {
readonly container: Locator;
readonly searchInput: Locator;
constructor(container: Locator) {
this.container = container;
this.searchInput = container.getByPlaceholder('Find settings');
}
async toBeVisible() {
await expect(this.container).toBeVisible();
await expect(this.searchInput).toBeVisible();
}
/**
* Clicks on the sidebar section link with the given name. Pass the exact name of the section.
* @param sectionName
*/
async goToItem(sectionName: string) {
const section = this.container.getByText(sectionName, {exact: true});
await section.waitFor();
await section.click();
}
/**
* Searches for the given item in the sidebar search input.
* @param itemName
*/
async searchForItem(itemName: string) {
await this.searchInput.fill(itemName);
}
}
export {SystemConsoleSidebar};