Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
336 lines
10 KiB
TypeScript
336 lines
10 KiB
TypeScript
import type { Locator, Page } from '@playwright/test';
|
|
|
|
import {
|
|
EditStatusModal,
|
|
CreateNewChannelModal,
|
|
CreateNewDiscussionModal,
|
|
CreateNewDMModal,
|
|
CreateNewTeamModal,
|
|
CreateNewCategoryModal,
|
|
} from './modals';
|
|
import { expect } from '../../utils/test';
|
|
|
|
export class Navbar {
|
|
readonly modals: {
|
|
'Channel': CreateNewChannelModal;
|
|
'Team': CreateNewTeamModal;
|
|
'Discussion': CreateNewDiscussionModal;
|
|
'Direct message': CreateNewDMModal;
|
|
'editStatus': EditStatusModal;
|
|
'Category': CreateNewCategoryModal;
|
|
};
|
|
|
|
constructor(private readonly root: Page) {
|
|
this.modals = {
|
|
'Channel': new CreateNewChannelModal(root),
|
|
'Team': new CreateNewTeamModal(root),
|
|
'Discussion': new CreateNewDiscussionModal(root),
|
|
'Direct message': new CreateNewDMModal(root),
|
|
'editStatus': new EditStatusModal(root),
|
|
'Category': new CreateNewCategoryModal(root),
|
|
};
|
|
}
|
|
|
|
get btnVoiceAndOmnichannel(): Locator {
|
|
return this.root.getByRole('button', { name: 'Voice and omnichannel' });
|
|
}
|
|
|
|
get groupHistoryNavigation(): Locator {
|
|
return this.root.getByRole('group', { name: 'History navigation' });
|
|
}
|
|
|
|
get pagesGroup(): Locator {
|
|
return this.root.getByRole('group', { name: 'Pages and actions' });
|
|
}
|
|
|
|
get omnichannelGroup(): Locator {
|
|
return this.root.getByRole('group', { name: 'Omnichannel' });
|
|
}
|
|
|
|
get btnContactCenter(): Locator {
|
|
return this.omnichannelGroup.getByRole('button', { name: 'Contact Center' });
|
|
}
|
|
|
|
get voiceCallGroup(): Locator {
|
|
return this.root.getByRole('group', { name: 'Voice call' });
|
|
}
|
|
|
|
get btnNewVoiceCall(): Locator {
|
|
return this.voiceCallGroup.getByRole('button', { name: 'New voice call' });
|
|
}
|
|
|
|
get btnSwitchOmnichannelStatus(): Locator {
|
|
return this.omnichannelGroup.getByRole('button', { name: 'answer chats' });
|
|
}
|
|
|
|
get btnHome(): Locator {
|
|
return this.pagesGroup.getByRole('button', { name: 'Home' });
|
|
}
|
|
|
|
get btnDirectory(): Locator {
|
|
return this.pagesGroup.getByRole('button', { name: 'Directory' });
|
|
}
|
|
|
|
get btnMarketplace(): Locator {
|
|
return this.pagesGroup.getByRole('button', { name: 'Marketplace' });
|
|
}
|
|
|
|
get btnMenuPages(): Locator {
|
|
return this.pagesGroup.getByRole('button', { name: 'Pages' });
|
|
}
|
|
|
|
get btnDisplay(): Locator {
|
|
return this.pagesGroup.getByRole('button', { name: 'Display' });
|
|
}
|
|
|
|
get menuDisplay(): Locator {
|
|
return this.root.getByRole('menu', { name: 'Display' });
|
|
}
|
|
|
|
get groupDisplay(): Locator {
|
|
return this.menuDisplay.getByRole('group', { name: 'Display' });
|
|
}
|
|
|
|
getDisplayMenuItem(mode: 'Extended' | 'Medium' | 'Condensed' | 'Avatars'): Locator {
|
|
return this.groupDisplay.getByRole('menuitemcheckbox', { name: mode });
|
|
}
|
|
|
|
get groupSortBy(): Locator {
|
|
return this.menuDisplay.getByRole('group', { name: 'Sort by' });
|
|
}
|
|
|
|
getSortMenuItem(mode: 'Activity' | 'Name'): Locator {
|
|
return this.groupSortBy.getByRole('menuitemcheckbox', { name: mode });
|
|
}
|
|
|
|
get groupGroupBy(): Locator {
|
|
return this.menuDisplay.getByRole('group', { name: 'Group by' });
|
|
}
|
|
|
|
getGroupByMenuItem(mode: 'Unread' | 'Favorites' | 'Types'): Locator {
|
|
return this.groupGroupBy.getByRole('menuitemcheckbox', { name: mode });
|
|
}
|
|
|
|
get btnCreateNew(): Locator {
|
|
return this.pagesGroup.getByRole('button', { name: 'Create new' });
|
|
}
|
|
|
|
get createNewMenu(): Locator {
|
|
return this.root.getByRole('menu', { name: 'Create new' });
|
|
}
|
|
|
|
get navbarSearchSection(): Locator {
|
|
return this.root.getByRole('search');
|
|
}
|
|
|
|
get searchInput(): Locator {
|
|
return this.navbarSearchSection.getByRole('combobox');
|
|
}
|
|
|
|
get searchList(): Locator {
|
|
return this.navbarSearchSection.getByRole('listbox', { name: 'Channels' });
|
|
}
|
|
|
|
get workspaceGroup(): Locator {
|
|
return this.root.getByRole('group', { name: 'Workspace and user preferences' });
|
|
}
|
|
|
|
get btnManageWorkspace(): Locator {
|
|
return this.workspaceGroup.getByRole('button', { name: 'Manage' });
|
|
}
|
|
|
|
async openManageMenuItem(name: 'Workspace' | 'Omnichannel'): Promise<void> {
|
|
await this.btnManageWorkspace.click();
|
|
await this.root.getByRole('menu', { name: 'Manage' }).getByRole('menuitem', { name }).click();
|
|
}
|
|
|
|
get btnUserMenu(): Locator {
|
|
return this.workspaceGroup.getByRole('button', { name: 'User menu' });
|
|
}
|
|
|
|
get userMenu(): Locator {
|
|
return this.root.getByRole('menu', { name: 'User menu' });
|
|
}
|
|
|
|
get btnLogout(): Locator {
|
|
return this.userMenu.getByRole('menuitemcheckbox', { name: 'Logout' });
|
|
}
|
|
|
|
get btnCustomStatus(): Locator {
|
|
return this.userMenu.getByRole('menuitemcheckbox', { name: 'Custom...' });
|
|
}
|
|
|
|
getUserProfileMenuOption(name: string): Locator {
|
|
return this.userMenu.getByRole('menuitemcheckbox', { name });
|
|
}
|
|
|
|
createNewMenuItem(name: 'Direct message' | 'Discussion' | 'Channel' | 'Team' | 'Outbound message' | 'Category'): Locator {
|
|
return this.createNewMenu.getByRole('menuitem', { name });
|
|
}
|
|
|
|
async openCreate(name: 'Direct message' | 'Discussion' | 'Channel' | 'Team' | 'Category'): Promise<void> {
|
|
await this.btnCreateNew.click();
|
|
await this.createNewMenuItem(name).click();
|
|
}
|
|
|
|
async openCreateCategory(): Promise<void> {
|
|
await this.btnCreateNew.click();
|
|
await this.createNewMenu.getByRole('menuitem', { name: 'Category', exact: true }).click();
|
|
}
|
|
|
|
async logout(): Promise<void> {
|
|
await this.btnUserMenu.click();
|
|
return this.btnLogout.click();
|
|
}
|
|
|
|
btnSidebarToggler(closeSidebar?: boolean): Locator {
|
|
return this.root.getByRole('button', { name: closeSidebar ? 'Close sidebar' : 'Open sidebar' });
|
|
}
|
|
|
|
async openAdminPanel(): Promise<void> {
|
|
await this.btnManageWorkspace.click();
|
|
await this.root.getByRole('menuitem', { name: 'Workspace' }).click();
|
|
await this.root.waitForURL(/\/admin/);
|
|
}
|
|
|
|
async typeSearch(name: string): Promise<void> {
|
|
return this.searchInput.fill(name);
|
|
}
|
|
|
|
async waitForChannel(): Promise<void> {
|
|
await this.root.locator('role=main').waitFor();
|
|
await this.root.locator('role=main >> role=heading[level=1]').waitFor();
|
|
const messageList = this.root.getByRole('main').getByRole('list', { name: 'Message list', exact: true });
|
|
await messageList.waitFor();
|
|
|
|
await expect(messageList).not.toHaveAttribute('aria-busy', 'true');
|
|
}
|
|
|
|
getSearchRoomByName(name: string): Locator {
|
|
return this.searchList.getByRole('option', { name }).filter({ has: this.root.getByText(name, { exact: true }) });
|
|
}
|
|
|
|
getSearchItemBadge(name: string): Locator {
|
|
return this.getSearchRoomByName(name).getByRole('status', { name: 'unread' });
|
|
}
|
|
|
|
async openChat(name: string): Promise<void> {
|
|
await this.typeSearch(name);
|
|
await this.getSearchRoomByName(name).waitFor();
|
|
await this.getSearchRoomByName(name).click();
|
|
await this.waitForChannel();
|
|
}
|
|
|
|
async setDisplayMode(mode: 'Extended' | 'Medium' | 'Condensed'): Promise<void> {
|
|
await this.btnDisplay.click();
|
|
await this.menuDisplay.getByRole('menuitemcheckbox', { name: mode }).click();
|
|
await this.root.keyboard.press('Escape');
|
|
}
|
|
|
|
async createNew(
|
|
type: 'Channel' | 'Team',
|
|
name: string,
|
|
options?: { private?: boolean; encrypted?: boolean; readOnly?: boolean; federated?: boolean; members?: string[] },
|
|
): Promise<void> {
|
|
await this.openCreate(type);
|
|
await this.modals[type].inputName.fill(name);
|
|
|
|
if (options?.private === false) {
|
|
await this.modals[type].checkboxPrivate.click();
|
|
}
|
|
|
|
if (options?.members && options.members.length > 0) {
|
|
await Promise.all(options.members.map((member) => this.modals[type].addMember(member)));
|
|
}
|
|
|
|
if (options && ('encrypted' in options || 'readOnly' in options || 'federated' in options)) {
|
|
await this.modals[type].advancedSettingsAccordion.click();
|
|
}
|
|
if (options?.encrypted) {
|
|
await this.modals[type].checkboxEncrypted.click();
|
|
}
|
|
if (options?.readOnly) {
|
|
await this.modals[type].checkboxReadOnly.click();
|
|
}
|
|
if (options?.federated) {
|
|
await this.modals[type].checkboxFederated.click();
|
|
}
|
|
|
|
await this.modals[type].btnCreate.click();
|
|
}
|
|
|
|
async createNewDM(username: string): Promise<void> {
|
|
await this.openCreate('Direct message');
|
|
await this.modals['Direct message'].inviteUserToDM(username);
|
|
await this.modals['Direct message'].btnCreate.click();
|
|
}
|
|
|
|
async createNewCategory(name: string): Promise<void> {
|
|
await this.openCreate('Category');
|
|
await this.modals.Category.inputName.fill(name);
|
|
await this.modals.Category.create();
|
|
}
|
|
|
|
async createNewDiscussion(parentRoom: string, name: string, message?: string): Promise<void> {
|
|
await this.openCreate('Discussion');
|
|
await this.modals.Discussion.inputParentRoom.click();
|
|
await this.modals.Discussion.inputParentRoom.pressSequentially(parentRoom);
|
|
await this.modals.Discussion.getParentRoomListItem(parentRoom).click();
|
|
await this.modals.Discussion.inputName.fill(name);
|
|
message && (await this.modals.Discussion.inputMessage.fill(message));
|
|
await this.modals.Discussion.btnCreate.click();
|
|
}
|
|
|
|
async createEncryptedChannel(name: string): Promise<void> {
|
|
await this.createNew('Channel', name, { encrypted: true });
|
|
}
|
|
|
|
async changeUserStatus(status: 'online' | 'away' | 'busy' | 'invisible' | 'offline' | string): Promise<void> {
|
|
await this.btnUserMenu.click();
|
|
await this.getUserProfileMenuOption(status).click();
|
|
}
|
|
|
|
async changeUserCustomStatus(text?: string): Promise<void> {
|
|
await this.openEditStatusModal();
|
|
await this.modals.editStatus.changeStatusMessage(text);
|
|
}
|
|
|
|
get editStatusModal(): EditStatusModal {
|
|
return this.modals.editStatus;
|
|
}
|
|
|
|
async openEditStatusModal(): Promise<void> {
|
|
await this.btnUserMenu.click();
|
|
await this.btnCustomStatus.click();
|
|
}
|
|
|
|
async changeUserCustomStatusWithExpiration(options: {
|
|
message?: string;
|
|
statusType?: string;
|
|
duration: string;
|
|
customDate?: string;
|
|
customTime?: string;
|
|
}): Promise<void> {
|
|
await this.openEditStatusModal();
|
|
await this.modals.editStatus.setStatusWithExpiration(options);
|
|
}
|
|
|
|
async switchOmnichannelStatus(status: 'offline' | 'online') {
|
|
const toggleButton = this.btnSwitchOmnichannelStatus;
|
|
await expect(toggleButton).toBeVisible();
|
|
|
|
const expectedTitle = status === 'offline' ? 'Turn on answer chats' : 'Turn off answer chats';
|
|
|
|
const currentStatus = await toggleButton.getAttribute('title');
|
|
if (currentStatus !== expectedTitle) {
|
|
await toggleButton.click();
|
|
}
|
|
|
|
await expect(toggleButton).toHaveAttribute('title', expectedTitle);
|
|
}
|
|
|
|
getUserStatusBadge(status: 'online' | 'away' | 'busy' | 'offline'): Locator {
|
|
return this.btnUserMenu.locator(`svg[class*="${status}"]`);
|
|
}
|
|
}
|