snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
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

This commit is contained in:
upstream-mirror
2026-09-16 01:21:02 +05:00
commit 30810eecd7
10161 changed files with 987110 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
import type { Locator, Page } from 'playwright-core';
import { Modal } from './modal';
export class AppsModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Modal Example' }));
}
get textInput(): Locator {
return this.root.locator('[name="modal_input"]');
}
get textInputErrorMessage(): Locator {
return this.root.getByText('Validation failed');
}
get btnSubmit(): Locator {
return this.root.getByRole('button', { name: 'Submit' });
}
async submit(inputText: string) {
await this.textInput.fill(inputText);
await this.btnSubmit.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,63 @@
import type { Locator, Page } from 'playwright-core';
import { Modal } from './modal';
export class ConfirmDeleteModal extends Modal {
constructor(root: Locator) {
super(root);
}
get btnDelete() {
return this.root.getByRole('button', { name: 'Delete' });
}
async confirmDelete() {
await this.btnDelete.click();
await this.waitForDismissal();
}
}
export class ConfirmDeleteRoomModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Delete' }));
}
get btnDelete() {
return this.root.getByRole('button', { name: 'Yes, delete', exact: true });
}
async confirmDelete() {
await this.btnDelete.click();
await this.waitForDismissal();
}
}
export class ConfirmDeleteDepartmentModal extends ConfirmDeleteModal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Delete Department?' }));
}
get inputConfirmDepartmentName() {
return this.root.getByRole('textbox', { name: 'Department name' });
}
async deleteDepartment(departmentName: string) {
await this.inputConfirmDepartmentName.fill(departmentName);
await this.confirmDelete();
}
}
export class ConfirmDeleteTeamModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Delete team', exact: true }));
}
private get btnDelete() {
return this.root.getByRole('button', { name: 'Yes, delete', exact: true });
}
async confirmDelete() {
await this.btnDelete.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,12 @@
import { Modal } from './modal';
export class ConfirmLogoutModal extends Modal {
get btnLogout() {
return this.root.getByRole('button', { name: 'Log out device' });
}
async confirmLogout() {
await this.btnLogout.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,18 @@
import type { Locator } from '@playwright/test';
import { Modal } from './modal';
export class ConfirmRemoveModal extends Modal {
constructor(root: Locator) {
super(root);
}
get btnRemove() {
return this.root.getByRole('button', { name: 'Remove' });
}
async confirmRemove() {
await this.btnRemove.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,129 @@
import type { Locator, Page } from '@playwright/test';
import { Listbox } from '../listbox';
import { Modal } from './modal';
export abstract class CreateNewModal extends Modal {
readonly listbox: Listbox;
constructor(root: Locator, page: Page) {
super(root, page);
this.listbox = new Listbox(page);
}
get inputName(): Locator {
return this.root.getByRole('textbox', { name: 'Name' });
}
get checkboxPrivate(): Locator {
return this.root.locator('label', { hasText: 'Private' });
}
get checkboxEncrypted(): Locator {
return this.root.locator('label', { hasText: 'Encrypted' });
}
get checkboxReadOnly(): Locator {
return this.root.locator('label', { hasText: 'Read-only' });
}
get checkboxFederated(): Locator {
return this.root.locator('label', { hasText: 'Federated' });
}
get btnCreate(): Locator {
return this.root.getByRole('button', { name: 'Create', exact: true });
}
get inputAddMembers(): Locator {
return this.root.getByRole('combobox', { name: 'Members' });
}
async addMember(memberName: string): Promise<void> {
await this.inputAddMembers.click();
await this.inputAddMembers.fill(memberName, { force: true });
await this.listbox.selectOption(memberName);
await this.inputAddMembers.click();
}
async create() {
await this.btnCreate.click();
await this.waitForDismissal();
}
}
export class CreateNewChannelModal extends CreateNewModal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Create channel' }), page);
}
get advancedSettingsAccordion(): Locator {
return this.root.getByRole('button', { name: 'Advanced settings', exact: true });
}
async inviteUserToChannel(username: string) {
await this.inputAddMembers.click();
await this.inputAddMembers.fill(username);
await this.listbox.selectOption(username);
}
}
export class CreateNewDMModal extends CreateNewModal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'New direct message' }), page);
}
get autocompleteUser(): Locator {
return this.root.getByRole('combobox', { name: 'Select one or more people to message', exact: true });
}
async inviteUserToDM(username: string) {
await this.autocompleteUser.click();
await this.autocompleteUser.fill(username);
await this.listbox.selectOption(username);
await this.page?.keyboard.press('Tab');
}
}
export class CreateNewTeamModal extends CreateNewModal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Create team' }), page);
}
get advancedSettingsAccordion(): Locator {
return this.root.getByRole('button', { name: 'Advanced settings', exact: true });
}
}
export class CreateNewDiscussionModal extends CreateNewModal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Create discussion' }), page);
}
get inputParentRoom(): Locator {
return this.root.getByRole('textbox', { name: 'Parent channel or team' });
}
getParentRoomListItem(name: string): Locator {
return this.listbox.getOption(name);
}
get inputMessage(): Locator {
return this.root.getByRole('textbox', { name: 'Message', exact: true });
}
}
export class CreateNewCategoryModal extends CreateNewModal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Create category', exact: true }), page);
}
private get btnCreateAndMove() {
return this.root.getByRole('button', { name: 'Create and move', exact: true });
}
override async create(hasRoom = false) {
await (hasRoom ? this.btnCreateAndMove.click() : this.btnCreate.click());
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,36 @@
import type { Locator, Page } from 'playwright-core';
import { Modal } from './modal';
export class DeleteAccountModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Delete account?' }));
}
get btnDeleteAccount(): Locator {
return this.root.getByRole('button', { name: 'Delete Account' });
}
get btnCancel(): Locator {
return this.root.getByRole('button', { name: 'Cancel' });
}
async confirmDelete({ waitForDismissal = true } = {}): Promise<void> {
await this.btnDeleteAccount.click();
if (waitForDismissal) {
await this.waitForDismissal();
}
}
get deleteAccountDialogMessageWithPassword(): Locator {
return this.root.getByText('Enter your password to delete your account. This cannot be undone.');
}
get inputPassword(): Locator {
return this.root.getByRole('textbox', { name: 'Enter your password to delete your account. This cannot be undone.' });
}
get inputErrorMessage(): Locator {
return this.root.locator('[role="alert"]', { hasText: 'Invalid password' });
}
}

View File

@@ -0,0 +1,18 @@
import type { Page } from '@playwright/test';
import { Modal } from './modal';
export class DeleteCategoryModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Delete category', exact: true }), page);
}
private get btnDelete() {
return this.root.getByRole('button', { name: 'Delete', exact: true });
}
async delete() {
await this.btnDelete.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,23 @@
import type { Page } from 'playwright-core';
import { Modal } from './modal';
import { ToastMessages } from '../toast-messages';
export class DisableRoomEncryptionModal extends Modal {
private readonly toastMessages: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Disable encryption' }));
this.toastMessages = new ToastMessages(page);
}
private get disableButton() {
return this.root.getByRole('button', { name: 'Disable encryption' });
}
async disable() {
await this.disableButton.click();
await this.waitForDismissal();
await this.toastMessages.dismissToast('success');
}
}

View File

@@ -0,0 +1,97 @@
import type { Page } from 'playwright-core';
import { Modal } from './modal';
import { ToastMessages } from '../toast-messages';
export class EditStatusModal extends Modal {
readonly toastMessages: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Set your status' }), page);
this.toastMessages = new ToastMessages(page);
}
private get statusMessageInput() {
return this.root.getByRole('textbox', { name: 'Status' });
}
private get statusTypeButton() {
return this.root.getByRole('button', { name: 'User status menu' });
}
private get durationSelect() {
return this.root.getByLabel('Clear status after');
}
get customDateInput() {
return this.root.getByLabel('Expiration date');
}
get customTimeInput() {
return this.root.getByLabel('Expiration time');
}
get btnSubmit() {
return this.root.getByRole('button', { name: 'Save' });
}
get durationError() {
return this.root.getByRole('alert').filter({ hasText: 'Expiration must be in the future' });
}
get durationMissingError() {
return this.root.getByRole('alert').filter({ hasText: 'Choose date and time' });
}
async selectStatusType(status: string): Promise<void> {
await this.statusTypeButton.click();
await this.page!.getByRole('option', { name: status }).click();
}
async setStatusMessage(message: string): Promise<void> {
await this.statusMessageInput.fill(message);
}
async selectDuration(duration: string): Promise<void> {
await this.durationSelect.click();
await this.page!.getByRole('option', { name: new RegExp(duration) }).click();
}
async changeStatusMessage(statusMessage?: string): Promise<void> {
if (statusMessage !== undefined) {
await this.setStatusMessage(statusMessage);
}
await this.save();
await this.toastMessages.dismissToast();
}
async setStatusWithExpiration({
message,
statusType,
duration,
customDate,
customTime,
}: {
message?: string;
statusType?: string;
duration: string;
customDate?: string;
customTime?: string;
}): Promise<void> {
if (statusType) {
await this.selectStatusType(statusType);
}
if (message !== undefined) {
await this.setStatusMessage(message);
}
await this.selectDuration(duration);
if (customDate) {
await this.customDateInput.fill(customDate);
}
if (customTime) {
await this.customTimeInput.fill(customTime);
}
await this.save();
await this.toastMessages.dismissToast();
}
}

View File

@@ -0,0 +1,23 @@
import type { Page } from 'playwright-core';
import { Modal } from './modal';
import { ToastMessages } from '../toast-messages';
export class EnableRoomEncryptionModal extends Modal {
private readonly toastMessages: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Enable encryption' }));
this.toastMessages = new ToastMessages(page);
}
private get enableButton() {
return this.root.getByRole('button', { name: 'Enable encryption' });
}
async enable() {
await this.enableButton.click();
await this.waitForDismissal();
await this.toastMessages.dismissToast('success');
}
}

View File

@@ -0,0 +1,32 @@
import type { Page } from '@playwright/test';
import { Modal } from './modal';
export class EnterE2EEPasswordModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Enter E2EE password' }));
}
private get passwordInput() {
return this.root.getByPlaceholder('Please enter your E2EE password');
}
private get forgotPasswordLink() {
return this.root.getByRole('link', { name: 'Forgot E2EE password?' });
}
private get enterE2EEPasswordButton() {
return this.root.getByRole('button', { name: 'Enable encryption' });
}
async enterPassword(password: string) {
await this.passwordInput.fill(password);
await this.enterE2EEPasswordButton.click();
await this.waitForDismissal();
}
async forgotPassword() {
await this.forgotPasswordLink.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,27 @@
import type { Page } from 'playwright-core';
import { Modal } from './modal';
import { ToastMessages } from '../toast-messages';
export class EnterPasswordModal extends Modal {
readonly toastMessages: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Please enter your password' }));
this.toastMessages = new ToastMessages(page);
}
private get inputPassword() {
return this.root.getByRole('textbox', { name: 'For your security, you must enter your current password to continue' });
}
private get btnVerify() {
return this.root.getByRole('button', { name: 'Verify' });
}
async enterPassword(password: string): Promise<void> {
await this.inputPassword.fill(password);
await this.btnVerify.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,58 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
export class FileUploadModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'File Upload' }));
}
private get inputFileName() {
return this.root.getByRole('textbox', { name: 'File name' });
}
private get updateButton() {
return this.root.getByRole('button', { name: 'Update' });
}
setName(fileName: string) {
return this.inputFileName.fill(fileName);
}
async update() {
await this.updateButton.click();
await this.waitForDismissal();
}
}
export class FileUploadWarningModal extends Modal {
constructor(root: Locator) {
super(root);
}
get btnOk() {
return this.root.getByRole('button', { name: 'Ok' });
}
get btnSendAnyway() {
return this.root.getByRole('button', { name: 'Send anyway' });
}
getContent(text: string) {
return this.root.getByText(text);
}
private get btnCancel() {
return this.root.getByRole('button', { name: 'Cancel' });
}
async cancel() {
await this.btnCancel.click();
await this.waitForDismissal();
}
async confirmSend() {
await this.btnSendAnyway.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,26 @@
export * from './apps-modal';
export * from './confirm-delete-modal';
export * from './confirm-logout-modal';
export * from './confirm-remove-modal';
export * from './create-new-modal';
export * from './manage-category-modal';
export * from './delete-account-modal';
export * from './delete-category-modal';
export * from './disable-room-encryption-modal';
export * from './edit-status-modal';
export * from './enable-room-encryption-modal';
export * from './enter-e2ee-password-modal';
export * from './enter-password-modal';
export * from './file-upload-modal';
export * from './omnichannel-close-chat-modal';
export * from './omnichannel-on-hold-modal';
export * from './omnichannel-transfer-chat-modal';
export * from './omnichannel-confirm-remove-chat';
export * from './omnichannel-contact-review-modal';
export * from './omnichannel-delete-contact-modal';
export * from './omnichannel-reset-priorities-modal';
export * from './omnichannel-return-to-queue-modal';
export * from './report-message-modal';
export * from './reset-e2ee-password-modal';
export * from './save-e2ee-password-modal';
export * from './upsell-modal';

View File

@@ -0,0 +1,18 @@
import type { Page } from '@playwright/test';
import { Modal } from './modal';
export class ManageCategoryModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Manage category', exact: true }), page);
}
private get inputName() {
return this.root.getByRole('textbox', { name: 'Name', exact: true });
}
async rename(newName: string): Promise<void> {
await this.inputName.fill(newName);
await this.save();
}
}

View File

@@ -0,0 +1,39 @@
import type { Locator, Page } from '@playwright/test';
import { expect } from '../../../utils/test';
export abstract class Modal {
constructor(
protected root: Locator,
protected page?: Page,
) {
this.root = root;
this.page = page;
}
waitForDisplay() {
return expect(this.root).toBeVisible();
}
waitForDismissal() {
return expect(this.root).not.toBeVisible();
}
private get btnClose() {
return this.root.getByRole('button', { name: 'Close' });
}
async close() {
await this.btnClose.click();
await this.waitForDismissal();
}
private get btnSave() {
return this.root.getByRole('button', { name: 'Save' });
}
async save() {
await this.btnSave.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,35 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
import { ToastMessages } from '../toast-messages';
export class OmnichannelCloseChatModal extends Modal {
private readonly toastMessages: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Wrap up conversation' }));
this.toastMessages = new ToastMessages(page);
}
private get inputComment(): Locator {
return this.root.locator('input[name="comment"]');
}
private get btnConfirm(): Locator {
return this.root.locator('role=button[name="Confirm"]');
}
private get labelPDF(): Locator {
return this.root.locator('label[for="transcript-pdf"]');
}
async confirm(comment: string, downloadPDF: boolean): Promise<void> {
await this.inputComment.fill(comment);
if (downloadPDF) {
await this.labelPDF.click();
}
await this.btnConfirm.click();
await this.waitForDismissal();
await this.toastMessages.dismissToast('success');
}
}

View File

@@ -0,0 +1,18 @@
import type { Locator, Page } from 'playwright-core';
import { Modal } from './modal';
export class OmnichannelConfirmRemoveChat extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog'));
}
private get btnConfirmRemove(): Locator {
return this.root.getByRole('button', { name: 'Delete' });
}
async confirm() {
await this.btnConfirmRemove.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,27 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
import { expect } from '../../../utils/test';
import { Listbox } from '../listbox';
export class OmnichannelContactReviewModal extends Modal {
readonly listbox: Listbox;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Review contact' }), page);
this.listbox = new Listbox(page);
}
private getFieldByName(name: string): Locator {
return this.root.getByLabel(name, { exact: true });
}
async solveConfirmation(field: string, value: string) {
await this.getFieldByName(field).click();
await this.listbox.selectOption(value);
const responsePromise = this.page?.waitForResponse('**/api/v1/omnichannel/contacts.conflicts');
await this.save();
const responseListener = await responsePromise;
expect(responseListener?.status()).toBe(200);
}
}

View File

@@ -0,0 +1,22 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
export class OmnichannelDeleteContactModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Delete Contact' }));
}
get inputConfirmation(): Locator {
return this.root.getByRole('textbox', { name: 'Confirm Contact Removal' });
}
get btnDelete(): Locator {
return this.root.getByRole('button', { name: 'Delete' });
}
async delete() {
await this.btnDelete.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,18 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
export class OmnichannelOnHoldModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Place chat On-Hold' }));
}
private get btnPlaceChatOnHold(): Locator {
return this.root.getByRole('button', { name: 'Place chat On-Hold' });
}
async confirm(): Promise<void> {
await this.btnPlaceChatOnHold.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,18 @@
import type { Page } from '@playwright/test';
import { Modal } from './modal';
export class OmnichannelResetPrioritiesModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Reset priorities' }));
}
private get btnResetConfirm() {
return this.root.getByRole('button', { name: 'Reset' });
}
async reset() {
await this.btnResetConfirm.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,18 @@
import type { Page } from '@playwright/test';
import { Modal } from './modal';
export class OmnichannelReturnToQueueModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Return back to the Queue' }));
}
private get btnReturnToQueueConfirm() {
return this.root.getByRole('button', { name: 'Confirm' });
}
async confirm() {
await this.btnReturnToQueueConfirm.click();
await this.waitForDismissal();
}
}

View File

@@ -0,0 +1,41 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
import { Listbox } from '../listbox';
export class OmnichannelTransferChatModal extends Modal {
private readonly listbox: Listbox;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Forward chat' }));
this.listbox = new Listbox(page);
}
get inputComment(): Locator {
return this.root.locator('textarea[name="comment"]');
}
get inputForwardDepartment(): Locator {
return this.root.getByLabel('Forward to department').getByRole('textbox');
}
get inputForwardUser(): Locator {
return this.root.getByLabel('Forward to user').getByRole('textbox');
}
get btnForward(): Locator {
return this.root.locator('role=button[name="Forward"]');
}
async selectDepartment(name: string) {
await this.inputForwardDepartment.click();
await this.inputForwardDepartment.fill(name);
await this.listbox.selectOption(name);
}
async selectUser(name: string, id?: string) {
await this.inputForwardUser.click();
await this.inputForwardUser.fill(name);
await this.listbox.selectOption(id || name);
}
}

View File

@@ -0,0 +1,48 @@
import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
import { expect } from '../../../utils/test';
import { ToastMessages } from '../toast-messages';
export class ReportMessageModal extends Modal {
readonly toastMessage: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Report message' }));
this.toastMessage = new ToastMessages(page);
}
get inputReportDescription(): Locator {
return this.root.getByRole('textbox', { name: 'Report reason' });
}
private get btnSubmitReport(): Locator {
return this.root.getByRole('button', { name: 'Report' });
}
private get btnCancelReport(): Locator {
return this.root.getByRole('button', { name: 'Cancel' });
}
private get alertInputDescription(): Locator {
return this.root.getByRole('alert');
}
async cancelReport(): Promise<void> {
await this.btnCancelReport.click();
await this.waitForDismissal();
}
async submitReport(description?: string): Promise<void> {
if (!description) {
await this.btnSubmitReport.click();
await expect(this.alertInputDescription).toBeVisible();
return;
}
await this.inputReportDescription.fill(description);
await this.btnSubmitReport.click();
await this.waitForDismissal();
await this.toastMessage.waitForDisplay({ type: 'success', message: 'Report has been sent' });
}
}

View File

@@ -0,0 +1,23 @@
import type { Page } from 'playwright-core';
import { Modal } from './modal';
import { LoginPage } from '../../login';
export class ResetE2EEPasswordModal extends Modal {
private readonly login: LoginPage;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Reset E2EE password' }));
this.login = new LoginPage(page);
}
private get resetE2EEPasswordButton() {
return this.root.getByRole('button', { name: 'Reset E2EE password' });
}
async confirmReset() {
await this.resetE2EEPasswordButton.click();
await this.waitForDismissal();
await this.login.waitForIt();
}
}

View File

@@ -0,0 +1,31 @@
import type { Page } from 'playwright-core';
import { Modal } from './modal';
import { ToastMessages } from '../toast-messages';
export class SaveE2EEPasswordModal extends Modal {
private readonly toastMessages: ToastMessages;
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Save your new E2EE password' }));
this.toastMessages = new ToastMessages(page);
}
private get password() {
return this.root.getByLabel('Your E2EE password is:').getByRole('code');
}
private get savedPasswordButton() {
return this.root.getByRole('button', { name: 'I saved my password' });
}
async getPassword() {
return (await this.password.textContent()) ?? '';
}
async confirm() {
await this.savedPasswordButton.click();
await this.waitForDismissal();
await this.toastMessages.dismissToast('success');
}
}

View File

@@ -0,0 +1,15 @@
import type { Page } from '@playwright/test';
import { Modal } from './modal';
export class VoiceCallsUpsellModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Team voice calls' }));
}
}
export class OmnichannelUpsellDepartmentsModal extends Modal {
constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Departments' }));
}
}