From 36ca7073454995755a6935b0237d8151448fe70e Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Sat, 10 May 2025 01:46:12 +0530 Subject: [PATCH 1/3] Use controlled checkbox component --- .../PruneMessages/PruneMessages.tsx | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/apps/meteor/client/views/room/contextualBar/PruneMessages/PruneMessages.tsx b/apps/meteor/client/views/room/contextualBar/PruneMessages/PruneMessages.tsx index d41737791c6ef..43932c7726c2d 100644 --- a/apps/meteor/client/views/room/contextualBar/PruneMessages/PruneMessages.tsx +++ b/apps/meteor/client/views/room/contextualBar/PruneMessages/PruneMessages.tsx @@ -24,7 +24,7 @@ type PruneMessagesProps = { const PruneMessages = ({ callOutText, validateText, onClickClose, onClickPrune }: PruneMessagesProps): ReactElement => { const { t } = useTranslation(); - const { control, register } = useFormContext(); + const { control } = useFormContext(); const inclusiveCheckboxId = useId(); const pinnedCheckboxId = useId(); @@ -55,31 +55,51 @@ const PruneMessages = ({ callOutText, validateText, onClickClose, onClickPrune } {t('Inclusive')} - + } + /> {t('RetentionPolicy_DoNotPrunePinned')} - + } + /> {t('RetentionPolicy_DoNotPruneDiscussion')} - + } + /> {t('RetentionPolicy_DoNotPruneThreads')} - + } + /> {t('Files_only')} - + } + /> {callOutText && !validateText && {callOutText}} From 8671cc48b0586e17cc96137cc1d79bc1c2ad37ce Mon Sep 17 00:00:00 2001 From: Matheus Cardoso Date: Mon, 12 May 2025 18:00:07 -0300 Subject: [PATCH 2/3] test: should reset form after pruning messages --- .../fragments/home-flextab-pruneMessages.ts | 29 ++++++ .../page-objects/fragments/home-flextab.ts | 8 ++ .../meteor/tests/e2e/page-objects/toastBar.ts | 21 ++++ apps/meteor/tests/e2e/prune-messages.spec.ts | 96 +++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 apps/meteor/tests/e2e/page-objects/fragments/home-flextab-pruneMessages.ts create mode 100644 apps/meteor/tests/e2e/page-objects/toastBar.ts create mode 100644 apps/meteor/tests/e2e/prune-messages.spec.ts diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-pruneMessages.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-pruneMessages.ts new file mode 100644 index 0000000000000..d73896abbf9ba --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-pruneMessages.ts @@ -0,0 +1,29 @@ +import type { Locator, Page } from '@playwright/test'; + +export class HomeFlextabPruneMessages { + private readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + private get form(): Locator { + return this.page.getByRole('dialog', { name: 'Prune Messages' }); + } + + get doNotPrunePinned(): Locator { + return this.form.getByRole('checkbox', { name: 'Do not prune pinned messages', exact: true }); + } + + get filesOnly(): Locator { + return this.form.getByRole('checkbox', { name: 'Only remove the attached files, keep messages', exact: true }); + } + + async prune(): Promise { + await this.form.getByRole('button', { name: 'Prune' }).click(); + return this.page + .getByRole('dialog', { name: 'Are you sure?', exact: true }) + .getByRole('button', { name: 'Yes, prune them!', exact: true }) + .click(); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts index 52dc165e9a43d..1e5c66b4c4e27 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts @@ -5,6 +5,7 @@ import { HomeFlextabExportMessages } from './home-flextab-exportMessages'; import { HomeFlextabMembers } from './home-flextab-members'; import { HomeFlextabNotificationPreferences } from './home-flextab-notificationPreferences'; import { HomeFlextabOtr } from './home-flextab-otr'; +import { HomeFlextabPruneMessages } from './home-flextab-pruneMessages'; import { HomeFlextabRoom } from './home-flextab-room'; export class HomeFlextab { @@ -22,6 +23,8 @@ export class HomeFlextab { readonly exportMessages: HomeFlextabExportMessages; + readonly pruneMessages: HomeFlextabPruneMessages; + constructor(page: Page) { this.page = page; this.members = new HomeFlextabMembers(page); @@ -30,6 +33,7 @@ export class HomeFlextab { this.notificationPreferences = new HomeFlextabNotificationPreferences(page); this.otr = new HomeFlextabOtr(page); this.exportMessages = new HomeFlextabExportMessages(page); + this.pruneMessages = new HomeFlextabPruneMessages(page); } get btnTabMembers(): Locator { @@ -60,6 +64,10 @@ export class HomeFlextab { return this.page.locator('role=menuitem[name="Export messages"]'); } + get btnPruneMessages(): Locator { + return this.page.getByRole('menuitem', { name: 'Prune Messages' }); + } + get btnE2EERoomSetupDisableE2E(): Locator { return this.page.locator('[data-qa-id=ToolBoxAction-key]'); } diff --git a/apps/meteor/tests/e2e/page-objects/toastBar.ts b/apps/meteor/tests/e2e/page-objects/toastBar.ts new file mode 100644 index 0000000000000..d17d4f328606d --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/toastBar.ts @@ -0,0 +1,21 @@ +import type { Locator, Page } from '@playwright/test'; + +export class ToastBar { + private readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + get content(): Locator { + return this.page.locator('.rcx-toastbar'); + } + + get alert(): Locator { + return this.content.getByRole('alert'); + } + + get dismiss(): Locator { + return this.content.getByRole('button', { name: 'Dismiss alert', exact: true }); + } +} diff --git a/apps/meteor/tests/e2e/prune-messages.spec.ts b/apps/meteor/tests/e2e/prune-messages.spec.ts new file mode 100644 index 0000000000000..c84ba26d565f9 --- /dev/null +++ b/apps/meteor/tests/e2e/prune-messages.spec.ts @@ -0,0 +1,96 @@ +import { Users } from './fixtures/userStates'; +import { HomeChannel } from './page-objects/home-channel'; +import { ToastBar } from './page-objects/toastBar'; +import { createTargetChannel, sendTargetChannelMessage } from './utils'; +import { test, expect } from './utils/test'; + +test.use({ storageState: Users.admin.state }); + +test.describe('prune-messages', () => { + let poHomeChannel: HomeChannel; + let poToastBar: ToastBar; + let targetChannel: string; + + test.beforeAll('create target channel', async ({ api }) => { + targetChannel = await createTargetChannel(api, { members: [Users.admin.data.username] }); + }); + + test.afterAll('delete target channel', async ({ api }) => { + expect((await api.post('/channels.delete', { roomName: targetChannel })).status()).toBe(200); + }); + + test.beforeEach(async ({ page }) => { + poToastBar = new ToastBar(page); + poHomeChannel = new HomeChannel(page); + + await page.goto(`/channel/${targetChannel}/clean-history`); + }); + + test( + 'should reset form after pruning messages', + { + tag: '@channel', + annotation: { + type: 'issue', + description: 'https://rocketchat.atlassian.net/browse/CORE-1146', + }, + }, + async ({ api }) => { + const { + content, + tabs: { pruneMessages }, + } = poHomeChannel; + const { alert, dismiss } = poToastBar; + + await content.sendFileMessage('any_file.txt'); + await content.descriptionInput.fill('a message with a file'); + await content.btnModalConfirm.click(); + await expect(content.lastMessageFileName).toHaveText('any_file.txt'); + + await sendTargetChannelMessage(api, targetChannel, { + msg: 'a message without files', + }); + + await sendTargetChannelMessage(api, targetChannel, { + msg: 'a pinned message without files', + pinned: true, + }); + + await test.step('prune files only not pinned', async () => { + await pruneMessages.doNotPrunePinned.check({ force: true }); + await pruneMessages.filesOnly.check({ force: true }); + await pruneMessages.prune(); + await expect(alert).toHaveText('1 message pruned'); + await dismiss.click(); + await expect(pruneMessages.filesOnly, 'Checkbox is reset after success').not.toBeChecked(); + await expect(pruneMessages.doNotPrunePinned, 'Checkbox is reset after success').not.toBeChecked(); + }); + + await test.step('prune files only again', async () => { + await pruneMessages.doNotPrunePinned.check({ force: true }); + await pruneMessages.filesOnly.check({ force: true }); + await pruneMessages.prune(); + await expect(alert).toHaveText('No messages found to prune'); + await dismiss.click(); + await expect(pruneMessages.filesOnly, 'Checkbox retains value after error').toBeChecked(); + await expect(pruneMessages.doNotPrunePinned, 'Checkbox retains value after error').toBeChecked(); + }); + + await test.step('uncheck files only', async () => { + await pruneMessages.filesOnly.uncheck({ force: true }); + await pruneMessages.prune(); + await expect(alert).toHaveText('2 messages pruned'); + await dismiss.click(); + await expect(pruneMessages.filesOnly, 'Checkbox is reset after success').not.toBeChecked(); + }); + + await test.step('uncheck do not prune pinned', async () => { + await pruneMessages.doNotPrunePinned.uncheck({ force: true }); + await pruneMessages.prune(); + await expect(alert).toHaveText('1 message pruned'); + await dismiss.click(); + await expect(content.lastUserMessage).not.toBeVisible(); + }); + }, + ); +}); From a0b9b21f43478396c3720845ecfdd34f78972845 Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Wed, 14 May 2025 18:20:58 +0530 Subject: [PATCH 3/3] add changeset --- .changeset/grumpy-lemons-drum.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/grumpy-lemons-drum.md diff --git a/.changeset/grumpy-lemons-drum.md b/.changeset/grumpy-lemons-drum.md new file mode 100644 index 0000000000000..4cdfe50d4cc7a --- /dev/null +++ b/.changeset/grumpy-lemons-drum.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixes prune messages contextual bar not resetting form after submitting.