Skip to content

Conversation

@sandranymark
Copy link
Contributor

@sandranymark sandranymark commented Jun 26, 2025

Proposed changes (including videos or screenshots)

This PR improves the accessibility and UX consistency of the Report Message Modal

Changes made:

  • Updated inline error to follow i18n and WCAG 3.3.1 (Error Identification)
  • Added accessible label–input–error linking via useId() and aria-describedby
  • Added Report_Message key to en.i18n.json
  • Synced text content and structure with the ReportUserModal

Issue(s)

image

Steps to test or reproduce

Before:

image

After:

Skärmbild 2025-06-26 102820

Further comments

WA-52

Summary by CodeRabbit

  • New Features

    • Report modal: clearer labels, descriptions and improved accessibility.
  • Bug Fixes

    • Validation errors surface reliably with clearer, accessible messages during reporting.
  • Refactor

    • Form wiring simplified for consistent state, validation and submission.
  • Tests

    • End-to-end tests updated to use a modal-rooted API and verify success via toast messages.
  • Documentation

    • Localization consolidated: added "Report message" and removed several legacy report-related keys across locales.

@sandranymark sandranymark requested a review from a team as a code owner June 26, 2025 11:49
@changeset-bot
Copy link

changeset-bot bot commented Jun 26, 2025

🦋 Changeset detected

Latest commit: 3528f39

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 42 packages
Name Type
@rocket.chat/i18n Minor
@rocket.chat/meteor Minor
@rocket.chat/mock-providers Patch
@rocket.chat/ui-contexts Major
@rocket.chat/web-ui-registration Major
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/fuselage-ui-kit Major
@rocket.chat/ui-client Major
@rocket.chat/ui-voip Major
@rocket.chat/uikit-playground Patch
@rocket.chat/gazzodown Major
@rocket.chat/livechat Patch
@rocket.chat/ui-avatar Major
@rocket.chat/ui-video-conf Major
@rocket.chat/queue-worker Patch
@rocket.chat/core-typings Minor
@rocket.chat/rest-typings Minor
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/http-router Patch
@rocket.chat/model-typings Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/presence-service Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Jun 26, 2025

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

Copy link
Member

@gabriellsh gabriellsh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is good, just need to fix lint :)

@dougfabris dougfabris added this to the 7.13.0 milestone Nov 10, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Walkthrough

Refactors the report message modal to use react-hook-form Controller, adds i18n and unique IDs, improves accessibility labels/errors; updates E2E page object to a modal-rooted API with toast verification and adapts tests; removes many obsolete report-related translation keys and adds Report_message in English; adds a changeset entry.

Changes

Cohort / File(s) Change Summary
ReportMessageModal UI Refactor
apps/meteor/client/views/room/modals/ReportMessageModal/ReportMessageModal.tsx
Adds useTranslation and useId; switches description input from register-based to Controller with defaultValues and validation; inserts FieldLabel and FieldDescription tied via id; updates error rendering to role="alert"; updates modal text keys to use Report_message / Report.
E2E Modal Page Object
apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
Makes ReportMessageModal extend Modal, uses a dialog-root locator, adds ToastMessages as toastMessage, converts many public getters to private, and exposes action methods submitReport(description?: string) and cancelReport() that encapsulate validation and success flows.
E2E Tests
apps/meteor/tests/e2e/report-message.spec.ts
Replaces granular modal element interactions with the new modal API (submitReport, cancelReport), removing low-level clicks and some visibility assertions; adapts flows to optional description/validation behavior.
Locale changes (bulk)
packages/i18n/src/locales/* (many files)
Removes obsolete report-related keys across most locales (commonly Report_exclamation_mark, Report_this_message_question_mark, Why_do_you_want_to_report_question_mark, You_need_to_write_something); adds Report_message in packages/i18n/src/locales/en.i18n.json.
Changeset
.changeset/thirty-donuts-visit.md
Adds a changeset updating @rocket.chat/i18n and @rocket.chat/meteor (minor), noting improved inline error in report message modal for WCAG compliance.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Modal as ReportMessageModal
  participant Form as react-hook-form (Controller)
  participant API as Report API
  participant Toast as ToastMessages

  rect rgb(248,249,250)
    User->>Modal: Open modal
    User->>Modal: Type description
    User->>Modal: Click "Report"
  end

  rect rgb(230,247,255)
    Modal->>Form: handleSubmit -> Controller supplies description
    Form->>API: POST /reports (payload)
    API-->>Form: 200 OK
    Form-->>Modal: submit handler resolves
    Modal->>Toast: show success toast
    Toast-->>User: success visible
    Modal->>User: dismiss dialog
  end

  alt Validation error (empty description)
    Modal->>Form: handleSubmit -> validation fails
    Form-->>Modal: returns errors
    Modal->>User: show FieldError (role="alert")
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus:
    • react-hook-form Controller wiring, defaultValues and validation messaging in ReportMessageModal.tsx
    • ARIA attributes and id relationships between FieldLabel/FieldDescription and the textarea
    • E2E submitReport/cancelReport flows: modal-root locator, dismissal waits, and toast timing
    • Verify no remaining references to removed translation keys across the codebase and tests

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • gabriellsh
  • ggazzo

Poem

🐇
I hopped into a modal bright,
Gave labels voice and errors light.
Tests now wait for toasts that cheer —
Old keys hopped out, the path is clear. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main focus: improving WCAG 3.3.1 inline error compliance in the report message modal, which aligns with the core changes made to the component's accessibility and error handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e924679 and 1d583f3.

📒 Files selected for processing (1)
  • .changeset/thirty-donuts-visit.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: aleksandernsilva
Repo: RocketChat/Rocket.Chat PR: 36974
File: apps/meteor/client/components/Omnichannel/OutboundMessage/components/OutboundMessageWizard/forms/MessageForm/MessageForm.tsx:124-129
Timestamp: 2025-09-18T17:32:33.969Z
Learning: The ARIA mismatch issue in MessageForm's template field (where FieldError id used templateId instead of messageFormId) was addressed in PR #36972 through refactoring the template field into a separate TemplateField component, which uses consistent templateFieldId for both aria-describedby and FieldError id.
📚 Learning: 2025-09-18T17:32:33.969Z
Learnt from: aleksandernsilva
Repo: RocketChat/Rocket.Chat PR: 36974
File: apps/meteor/client/components/Omnichannel/OutboundMessage/components/OutboundMessageWizard/forms/MessageForm/MessageForm.tsx:124-129
Timestamp: 2025-09-18T17:32:33.969Z
Learning: The ARIA mismatch issue in MessageForm's template field (where FieldError id used templateId instead of messageFormId) was addressed in PR #36972 through refactoring the template field into a separate TemplateField component, which uses consistent templateFieldId for both aria-describedby and FieldError id.

Applied to files:

  • .changeset/thirty-donuts-visit.md
🔇 Additional comments (1)
.changeset/thirty-donuts-visit.md (1)

1-6: Changeset entry looks good. The packages, version bump type, and description accurately reflect the PR changes.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 511a59e and b05ebdc.

📒 Files selected for processing (62)
  • apps/meteor/client/views/room/modals/ReportMessageModal/ReportMessageModal.tsx (3 hunks)
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1 hunks)
  • apps/meteor/tests/e2e/report-message.spec.ts (3 hunks)
  • packages/i18n/src/locales/af.i18n.json (0 hunks)
  • packages/i18n/src/locales/ar.i18n.json (0 hunks)
  • packages/i18n/src/locales/az.i18n.json (0 hunks)
  • packages/i18n/src/locales/be-BY.i18n.json (0 hunks)
  • packages/i18n/src/locales/bg.i18n.json (0 hunks)
  • packages/i18n/src/locales/bs.i18n.json (0 hunks)
  • packages/i18n/src/locales/ca.i18n.json (0 hunks)
  • packages/i18n/src/locales/cs.i18n.json (0 hunks)
  • packages/i18n/src/locales/cy.i18n.json (0 hunks)
  • packages/i18n/src/locales/da.i18n.json (0 hunks)
  • packages/i18n/src/locales/de-AT.i18n.json (0 hunks)
  • packages/i18n/src/locales/de-IN.i18n.json (0 hunks)
  • packages/i18n/src/locales/de.i18n.json (0 hunks)
  • packages/i18n/src/locales/el.i18n.json (0 hunks)
  • packages/i18n/src/locales/en.i18n.json (1 hunks)
  • packages/i18n/src/locales/eo.i18n.json (0 hunks)
  • packages/i18n/src/locales/es.i18n.json (0 hunks)
  • packages/i18n/src/locales/fa.i18n.json (0 hunks)
  • packages/i18n/src/locales/fi.i18n.json (0 hunks)
  • packages/i18n/src/locales/fr.i18n.json (0 hunks)
  • packages/i18n/src/locales/gl.i18n.json (0 hunks)
  • packages/i18n/src/locales/he.i18n.json (0 hunks)
  • packages/i18n/src/locales/hi-IN.i18n.json (0 hunks)
  • packages/i18n/src/locales/hr.i18n.json (0 hunks)
  • packages/i18n/src/locales/hu.i18n.json (0 hunks)
  • packages/i18n/src/locales/id.i18n.json (0 hunks)
  • packages/i18n/src/locales/it.i18n.json (0 hunks)
  • packages/i18n/src/locales/ja.i18n.json (0 hunks)
  • packages/i18n/src/locales/ka-GE.i18n.json (0 hunks)
  • packages/i18n/src/locales/km.i18n.json (0 hunks)
  • packages/i18n/src/locales/ko.i18n.json (0 hunks)
  • packages/i18n/src/locales/ku.i18n.json (0 hunks)
  • packages/i18n/src/locales/lo.i18n.json (0 hunks)
  • packages/i18n/src/locales/lt.i18n.json (0 hunks)
  • packages/i18n/src/locales/lv.i18n.json (0 hunks)
  • packages/i18n/src/locales/mn.i18n.json (0 hunks)
  • packages/i18n/src/locales/ms-MY.i18n.json (0 hunks)
  • packages/i18n/src/locales/nb.i18n.json (0 hunks)
  • packages/i18n/src/locales/nl.i18n.json (0 hunks)
  • packages/i18n/src/locales/nn.i18n.json (0 hunks)
  • packages/i18n/src/locales/pl.i18n.json (0 hunks)
  • packages/i18n/src/locales/pt-BR.i18n.json (0 hunks)
  • packages/i18n/src/locales/pt.i18n.json (0 hunks)
  • packages/i18n/src/locales/ro.i18n.json (0 hunks)
  • packages/i18n/src/locales/ru.i18n.json (0 hunks)
  • packages/i18n/src/locales/sk-SK.i18n.json (0 hunks)
  • packages/i18n/src/locales/sl-SI.i18n.json (0 hunks)
  • packages/i18n/src/locales/sq.i18n.json (0 hunks)
  • packages/i18n/src/locales/sr.i18n.json (0 hunks)
  • packages/i18n/src/locales/sv.i18n.json (0 hunks)
  • packages/i18n/src/locales/ta-IN.i18n.json (0 hunks)
  • packages/i18n/src/locales/th-TH.i18n.json (0 hunks)
  • packages/i18n/src/locales/tr.i18n.json (0 hunks)
  • packages/i18n/src/locales/ug.i18n.json (0 hunks)
  • packages/i18n/src/locales/uk.i18n.json (0 hunks)
  • packages/i18n/src/locales/vi-VN.i18n.json (0 hunks)
  • packages/i18n/src/locales/zh-HK.i18n.json (0 hunks)
  • packages/i18n/src/locales/zh-TW.i18n.json (0 hunks)
  • packages/i18n/src/locales/zh.i18n.json (0 hunks)
💤 Files with no reviewable changes (58)
  • packages/i18n/src/locales/de-AT.i18n.json
  • packages/i18n/src/locales/el.i18n.json
  • packages/i18n/src/locales/be-BY.i18n.json
  • packages/i18n/src/locales/th-TH.i18n.json
  • packages/i18n/src/locales/tr.i18n.json
  • packages/i18n/src/locales/sq.i18n.json
  • packages/i18n/src/locales/zh-HK.i18n.json
  • packages/i18n/src/locales/ro.i18n.json
  • packages/i18n/src/locales/uk.i18n.json
  • packages/i18n/src/locales/ka-GE.i18n.json
  • packages/i18n/src/locales/zh-TW.i18n.json
  • packages/i18n/src/locales/he.i18n.json
  • packages/i18n/src/locales/mn.i18n.json
  • packages/i18n/src/locales/gl.i18n.json
  • packages/i18n/src/locales/bs.i18n.json
  • packages/i18n/src/locales/cy.i18n.json
  • packages/i18n/src/locales/da.i18n.json
  • packages/i18n/src/locales/af.i18n.json
  • packages/i18n/src/locales/id.i18n.json
  • packages/i18n/src/locales/sr.i18n.json
  • packages/i18n/src/locales/pt.i18n.json
  • packages/i18n/src/locales/eo.i18n.json
  • packages/i18n/src/locales/ca.i18n.json
  • packages/i18n/src/locales/sl-SI.i18n.json
  • packages/i18n/src/locales/hi-IN.i18n.json
  • packages/i18n/src/locales/km.i18n.json
  • packages/i18n/src/locales/ta-IN.i18n.json
  • packages/i18n/src/locales/vi-VN.i18n.json
  • packages/i18n/src/locales/fi.i18n.json
  • packages/i18n/src/locales/lv.i18n.json
  • packages/i18n/src/locales/ug.i18n.json
  • packages/i18n/src/locales/nl.i18n.json
  • packages/i18n/src/locales/bg.i18n.json
  • packages/i18n/src/locales/ms-MY.i18n.json
  • packages/i18n/src/locales/lt.i18n.json
  • packages/i18n/src/locales/ar.i18n.json
  • packages/i18n/src/locales/az.i18n.json
  • packages/i18n/src/locales/cs.i18n.json
  • packages/i18n/src/locales/fr.i18n.json
  • packages/i18n/src/locales/de-IN.i18n.json
  • packages/i18n/src/locales/sv.i18n.json
  • packages/i18n/src/locales/es.i18n.json
  • packages/i18n/src/locales/hu.i18n.json
  • packages/i18n/src/locales/hr.i18n.json
  • packages/i18n/src/locales/zh.i18n.json
  • packages/i18n/src/locales/ku.i18n.json
  • packages/i18n/src/locales/fa.i18n.json
  • packages/i18n/src/locales/ru.i18n.json
  • packages/i18n/src/locales/ja.i18n.json
  • packages/i18n/src/locales/it.i18n.json
  • packages/i18n/src/locales/pl.i18n.json
  • packages/i18n/src/locales/ko.i18n.json
  • packages/i18n/src/locales/nn.i18n.json
  • packages/i18n/src/locales/sk-SK.i18n.json
  • packages/i18n/src/locales/nb.i18n.json
  • packages/i18n/src/locales/de.i18n.json
  • packages/i18n/src/locales/pt-BR.i18n.json
  • packages/i18n/src/locales/lo.i18n.json
🧰 Additional context used
📓 Path-based instructions (4)
apps/meteor/tests/e2e/page-objects/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

Utilize and place Page Object implementations under apps/meteor/tests/e2e/page-objects/

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx}: Write concise, technical TypeScript/JavaScript with accurate typing
Follow DRY by extracting reusable logic into helper functions or page objects
Avoid code comments in the implementation

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
apps/meteor/tests/e2e/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

apps/meteor/tests/e2e/**/*.{ts,tsx}: Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle
Store commonly used locators in variables/constants for reuse
Use page.waitFor() with specific conditions and avoid hardcoded timeouts
Implement proper wait strategies for dynamic content
Follow the Page Object Model pattern consistently

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
apps/meteor/tests/e2e/**/*.spec.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

apps/meteor/tests/e2e/**/*.spec.ts: All Playwright test files must be located under apps/meteor/tests/e2e/ and use the .spec.ts extension (e.g., login.spec.ts)
Use descriptive test names that clearly communicate expected behavior
Use test.beforeAll() and test.afterAll() for setup and teardown
Use test.step() to organize complex test scenarios
Group related tests in the same file
Utilize Playwright fixtures (test, page, expect) consistently
Prefer web-first assertions (e.g., toBeVisible, toHaveText)
Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements
Maintain test isolation between test cases
Ensure a clean state for each test execution
Ensure tests run reliably in parallel without shared state conflicts

Files:

  • apps/meteor/tests/e2e/report-message.spec.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: aleksandernsilva
Repo: RocketChat/Rocket.Chat PR: 36974
File: apps/meteor/client/components/Omnichannel/OutboundMessage/components/OutboundMessageWizard/forms/MessageForm/MessageForm.tsx:124-129
Timestamp: 2025-09-18T17:32:33.969Z
Learning: The ARIA mismatch issue in MessageForm's template field (where FieldError id used templateId instead of messageFormId) was addressed in PR #36972 through refactoring the template field into a separate TemplateField component, which uses consistent templateFieldId for both aria-describedby and FieldError id.
📚 Learning: 2025-09-18T17:32:33.969Z
Learnt from: aleksandernsilva
Repo: RocketChat/Rocket.Chat PR: 36974
File: apps/meteor/client/components/Omnichannel/OutboundMessage/components/OutboundMessageWizard/forms/MessageForm/MessageForm.tsx:124-129
Timestamp: 2025-09-18T17:32:33.969Z
Learning: The ARIA mismatch issue in MessageForm's template field (where FieldError id used templateId instead of messageFormId) was addressed in PR #36972 through refactoring the template field into a separate TemplateField component, which uses consistent templateFieldId for both aria-describedby and FieldError id.

Applied to files:

  • apps/meteor/client/views/room/modals/ReportMessageModal/ReportMessageModal.tsx
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize and place Page Object implementations under apps/meteor/tests/e2e/page-objects/

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Follow the Page Object Model pattern consistently

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use descriptive test names that clearly communicate expected behavior

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (e.g., toBeVisible, toHaveText)

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (test, page, expect) consistently

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use test.step() to organize complex test scenarios

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Write concise, technical TypeScript/JavaScript with accurate typing

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Avoid code comments in the implementation

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
🧬 Code graph analysis (2)
apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1)
apps/meteor/tests/e2e/page-objects/fragments/toast-messages.ts (1)
  • ToastMessages (5-29)
apps/meteor/tests/e2e/report-message.spec.ts (1)
apps/meteor/tests/e2e/page-objects/home-channel.ts (1)
  • HomeChannel (6-120)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
🔇 Additional comments (12)
apps/meteor/tests/e2e/report-message.spec.ts (3)

82-82: LGTM! Empty validation test properly uses new API.

The test correctly calls submitReport() without arguments to verify empty description validation.


99-99: LGTM! Cancel flow properly abstracted.

The test correctly uses the new cancelReport() method to test the cancellation flow.


114-120: LGTM! Successful report submission test updated correctly.

The test properly generates a description and passes it to submitReport(reportDescription) to verify successful report submission.

apps/meteor/client/views/room/modals/ReportMessageModal/ReportMessageModal.tsx (7)

3-3: LGTM! Imports updated for accessibility enhancements.

The added imports (FieldLabel, FieldDescription) are necessary for the improved accessibility implementation.


5-9: LGTM! Dependencies updated for form handling and i18n.

The updated imports correctly add useId for stable IDs, Controller for enhanced form control, and useTranslation for i18n integration.


28-38: LGTM! Form setup follows react-hook-form best practices.

The form initialization correctly:

  • Uses useTranslation for i18n
  • Generates a stable unique ID with useId()
  • Includes control for Controller usage
  • Defines defaultValues to prevent uncontrolled component warnings

68-69: LGTM! Proper label and description for accessibility.

The FieldLabel with htmlFor and FieldDescription with a unique ID correctly link the label and description to the input field for screen readers.


71-85: Excellent ARIA implementation for WCAG 3.3.1 compliance.

The Controller implementation includes proper accessibility attributes:

  • aria-required='true' indicates the field is required
  • aria-invalid dynamically reflects validation state
  • aria-describedby links to both description and error (when present)
  • id={reasonForReportId} connects to the label's htmlFor

This properly implements WCAG 3.3.1 (Error Identification) requirements.


87-91: LGTM! Error rendering with proper accessibility.

The error message correctly:

  • Uses role='alert' to announce errors to screen readers
  • Has a unique id that matches the aria-describedby reference
  • Displays the dynamic validation message from errors.description.message

59-61: All translation keys verified and exist in locale files.

The verification is complete. Both Report_message and Report translation keys have been confirmed to exist across the i18n locale files, including the English locale (en.i18n.json). The code changes are properly supported by the translation infrastructure.

packages/i18n/src/locales/en.i18n.json (1)

4374-4376: ****

The code is already correct. The ReportMessageModal.tsx at line 59 correctly references t('Report_message') which matches the key defined in en.i18n.json. No mismatch exists, and old report keys are not referenced anywhere in the codebase, confirming they were successfully removed.

Likely an incorrect or invalid review comment.

apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1)

7-47: Well-structured page object with clean API design.

The refactoring to extend Modal and encapsulate actions in submitReport() and cancelReport() methods follows the Page Object Model pattern effectively. The integration with ToastMessages for verification and the dual-path submitReport (validation vs. full submission) provides a flexible testing API.

@dougfabris dougfabris force-pushed the fix/inline-error-report-message-modal branch from b05ebdc to e924679 Compare November 10, 2025 15:15
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1)

16-16: Past redundant dialog selector issue has been resolved.

These locators now correctly query directly from this.root without the redundant .getByRole('dialog') chain mentioned in the previous review.

Also applies to: 20-20, 24-24

🧹 Nitpick comments (1)
apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1)

36-47: Consider splitting dual-behavior method for clarity.

The submitReport method serves two purposes: validation testing (no args) and successful submission (with description). While functional, this dual behavior may be less intuitive for test authors.

Consider extracting the validation scenario into a separate method:

+async triggerValidation(): Promise<void> {
+	await this.btnSubmitReport.click();
+	await expect(this.alertInputDescription).toBeVisible();
+}
+
 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' });
 }

Then update the test at line 82 in report-message.spec.ts:

-await reportModal.submitReport();
+await reportModal.triggerValidation();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b05ebdc and e924679.

📒 Files selected for processing (2)
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1 hunks)
  • apps/meteor/tests/e2e/report-message.spec.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
apps/meteor/tests/e2e/**/*.spec.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

apps/meteor/tests/e2e/**/*.spec.ts: All Playwright test files must be located under apps/meteor/tests/e2e/ and use the .spec.ts extension (e.g., login.spec.ts)
Use descriptive test names that clearly communicate expected behavior
Use test.beforeAll() and test.afterAll() for setup and teardown
Use test.step() to organize complex test scenarios
Group related tests in the same file
Utilize Playwright fixtures (test, page, expect) consistently
Prefer web-first assertions (e.g., toBeVisible, toHaveText)
Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements
Maintain test isolation between test cases
Ensure a clean state for each test execution
Ensure tests run reliably in parallel without shared state conflicts

Files:

  • apps/meteor/tests/e2e/report-message.spec.ts
apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx}: Write concise, technical TypeScript/JavaScript with accurate typing
Follow DRY by extracting reusable logic into helper functions or page objects
Avoid code comments in the implementation

Files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
apps/meteor/tests/e2e/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

apps/meteor/tests/e2e/**/*.{ts,tsx}: Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle
Store commonly used locators in variables/constants for reuse
Use page.waitFor() with specific conditions and avoid hardcoded timeouts
Implement proper wait strategies for dynamic content
Follow the Page Object Model pattern consistently

Files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
apps/meteor/tests/e2e/page-objects/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

Utilize and place Page Object implementations under apps/meteor/tests/e2e/page-objects/

Files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
🧠 Learnings (15)
📓 Common learnings
Learnt from: aleksandernsilva
Repo: RocketChat/Rocket.Chat PR: 36974
File: apps/meteor/client/components/Omnichannel/OutboundMessage/components/OutboundMessageWizard/forms/MessageForm/MessageForm.tsx:124-129
Timestamp: 2025-09-18T17:32:33.969Z
Learning: The ARIA mismatch issue in MessageForm's template field (where FieldError id used templateId instead of messageFormId) was addressed in PR #36972 through refactoring the template field into a separate TemplateField component, which uses consistent templateFieldId for both aria-describedby and FieldError id.
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use descriptive test names that clearly communicate expected behavior

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Write concise, technical TypeScript/JavaScript with accurate typing

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use expect matchers (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (e.g., toBeVisible, toHaveText)

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (test, page, expect) consistently

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Avoid code comments in the implementation

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Avoid using page.locator(); prefer semantic locators like page.getByRole, page.getByLabel, page.getByText, and page.getByTitle

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize and place Page Object implementations under apps/meteor/tests/e2e/page-objects/

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/tests/e2e/report-message.spec.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Follow the Page Object Model pattern consistently

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx,js,jsx} : Follow DRY by extracting reusable logic into helper functions or page objects

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-16T22:08:51.490Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-09-16T22:08:51.490Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,tsx} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
📚 Learning: 2025-09-23T19:22:59.217Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 36987
File: apps/meteor/tests/e2e/page-objects/fragments/room-toolbar.ts:10-20
Timestamp: 2025-09-23T19:22:59.217Z
Learning: In Playwright e2e tests, prefer stable selectors like data-qa-id attributes over localized text in getByRole() or getByText() calls to prevent test failures when UI language changes. Test translations separately by validating actual text content after ensuring UI interactions work with stable selectors.

Applied to files:

  • apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts
🧬 Code graph analysis (2)
apps/meteor/tests/e2e/report-message.spec.ts (1)
apps/meteor/tests/e2e/page-objects/home-channel.ts (1)
  • HomeChannel (6-120)
apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1)
apps/meteor/tests/e2e/page-objects/fragments/toast-messages.ts (1)
  • ToastMessages (5-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: ⚙️ Variables Setup
  • GitHub Check: CodeQL-Build
🔇 Additional comments (4)
apps/meteor/tests/e2e/page-objects/fragments/report-message-modal.ts (1)

7-13: Good refactor to extend Modal and integrate toast verification.

Extending the base Modal class and adding the toastMessage property improves reusability and allows verification of success messages after submission.

apps/meteor/tests/e2e/report-message.spec.ts (3)

82-82: Validation test correctly uses the new modal API.

Calling submitReport() without arguments triggers the validation path in the modal, which clicks submit and verifies the alert is displayed.


99-99: Good use of encapsulated cancelReport method.

The new helper method improves readability and maintainability by hiding the implementation details of canceling the report flow.


114-120: Success scenario properly tests the full report flow.

The test correctly generates a description, passes it to submitReport, and the modal handles filling the input, submitting, waiting for dismissal, and verifying the success toast.

dougfabris
dougfabris previously approved these changes Nov 10, 2025
@dougfabris dougfabris changed the title fix: WCAG 3.3.1 inline error in report message modal feat: WCAG 3.3.1 inline error in report message modal Nov 10, 2025
@dougfabris dougfabris added the stat: QA assured Means it has been tested and approved by a company insider label Nov 11, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Nov 11, 2025
@kodiakhq kodiakhq bot merged commit f771dd3 into RocketChat:develop Nov 11, 2025
82 of 84 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants