Skip to content

Add FXIOS-16181 [WebCompat] Add the Website Issue picker#34535

Open
razvanlitianu wants to merge 6 commits into
mainfrom
rlitianu/fxios-16181-webcompat-issue-picker
Open

Add FXIOS-16181 [WebCompat] Add the Website Issue picker#34535
razvanlitianu wants to merge 6 commits into
mainfrom
rlitianu/fxios-16181-webcompat-issue-picker

Conversation

@razvanlitianu

@razvanlitianu razvanlitianu commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

📜 Tickets

Jira ticket
Github issue

💡 Description

Add the two-level Site Issue picker to the report sheet: a native UIMenu category pull-down and sub-option rows with a checkmark on the selected one.

  • Extend WebCompatReportViewModel.Row with a Kind (plain / categoryMenu / subOption) and Section headers; render via dedicated WebCompatCategoryMenuCell and WebCompatSubOptionCell keyed by stable ids in the diffable data source.
  • Add didSelectCategory/didSelectSubOption sheet delegate intents; the Client maps WebCompatReporterState to the view model and dispatches selectCategory/ selectSubOption.
  • Introduce WebCompatSubOption enum (raw values = Glean reason keys); category/ sub-option display titles map from the staged Strings in the Client.
  • Accessibility: selected/button/header traits, decorative glyphs hidden from VoiceOver, chevron scales with Dynamic Type.

🧪 Testing

  1. Run the Fennec scheme (the report-broken-site flag defaults on in developer builds).
  2. Load any web page, then open the ☰ menu → More → "Report a Website Issue".
  3. Under the "Site Issue" header, tap the "Choose issue type…" pull-down → a menu of the four categories appears. Pick "Site is not usable" → the row now shows the selected category and a second card of its sub-options appears below.
  4. Tap a sub-option → a checkmark moves to it, and Preview enables (it stays disabled until a category is chosen).
  5. Switch to a different category → the sub-options swap and the previous sub-option selection clears. Pick "Other" → no sub-options card (Preview stays enabled).
  6. Accessibility (VoiceOver): the category row is announced as a pop-up button with its selected value; sub-option rows announce "Selected"; the Headings rotor reaches "Site Issue". Dynamic Type: at accessibility sizes the header, pull-down title, rows, and chevron all scale.

To review in isolation: select the WebCompatReporterKit scheme on an iOS 26.5 simulator and open the #Preview ("Site Issue picker") in WebCompatReportSheetPreview.swift — it's interactive (open the pull-down, switch category, tap sub-options). Note the chevron/checkmark render blank in the package preview canvas (app asset catalog only) but appear in Fennec.

🎥 Demos

Before After
Demo

📝 Checklist

  • I filled in the ticket numbers and a description of my work
  • I updated the PR name to follow our PR naming guidelines
  • I ensured unit tests pass and wrote tests for new code
  • If working on UI, I checked and implemented accessibility (Dynamic Text and VoiceOver)
  • If adding telemetry, I read the data stewardship requirements and will request a data review
  • If adding or modifying strings, I read the guidelines and will request a string review from l10n
  • If needed, I updated documentation and added comments to complex code

@mobiletest-ci-bot

mobiletest-ci-bot commented Jul 6, 2026

Copy link
Copy Markdown
Messages
📖 Project coverage: 44.76%

✍️ Strings Updated

Detected changes in Shared/Strings.swift.
To keep strings up to standards, please add a member of the firefox-ios-l10n team as reviewer. 🌍

💪 Quality guardian

3 tests files modified. You're a champion of test coverage! 🚀

🏔️ Summit Climber

This PR is a big climb with 916 lines changed!
Thanks for taking on the heavy lifting 💪.
Reviewers: a quick overview or walkthrough will make the ascent smoother.

💬 Description craftsman

Great PR description! Reviewers salute you 🫡

✅ Code coverage

All new and modified files meet their coverage thresholds.

Client.app: Coverage: 43.55

File Coverage
MainMenuConfigurationUtility.swift 66.17%
WebCompatReportViewController.swift 79.47%
WebCompatIssueCategory.swift 92.86%

WebCompatReporterKit: Coverage: 87.91

File Coverage
WebCompatCategoryMenuCell.swift 84.4%
WebCompatSubOptionCell.swift 57.14%
WebCompatReportSheetViewController.swift 91.63%
WebCompatReportViewModel.swift 100.0%

Generated by 🚫 Danger Swift against e637bbe

@razvanlitianu razvanlitianu force-pushed the rlitianu/fxios-16181-webcompat-issue-picker branch from b68cbbe to 10bc19a Compare July 7, 2026 06:33
@razvanlitianu razvanlitianu marked this pull request as ready for review July 7, 2026 08:24
@razvanlitianu razvanlitianu requested a review from a team as a code owner July 7, 2026 08:24
@razvanlitianu razvanlitianu requested review from Cramsden and Copilot July 7, 2026 08:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a two-level “Site Issue” picker to the WebCompat “Report a Website Issue” sheet, implemented as a category pull-down (UIMenu) plus optional sub-option rows with checkmarks, and wires the selection intents back into the Client’s Redux state.

Changes:

  • Extended WebCompatReportViewModel with section headers and row kinds (plain, categoryMenu, subOption) and updated the sheet to render them via typed cells and stable diffable IDs.
  • Added Client-side category/sub-option enums and mapping from WebCompatReporterState → view model sections, plus delegate intents to dispatch selectCategory/selectSubOption.
  • Added new localized strings and expanded unit tests for the new picker behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
firefox-ios/Shared/Strings.swift Adds localized strings for the “Site Issue” section title and category placeholder.
firefox-ios/firefox-ios-tests/Tests/ClientTests/WebCompatReporter/WebCompatReporterStateTests.swift Updates tests to validate sub-option IDs via the new WebCompatSubOption enum.
firefox-ios/firefox-ios-tests/Tests/ClientTests/MainMenu/WebCompatReportViewControllerTests.swift Adds/updates tests for section construction and hosting the ReporterKit sheet controller.
firefox-ios/Client/Frontend/WebCompatReporter/Redux/WebCompatIssueCategory.swift Replaces string sub-option IDs with typed WebCompatSubOption and introduces the enum.
firefox-ios/Client/Frontend/Browser/WebCompat/WebCompatReportViewController.swift Builds picker sections from Redux state and forwards selection intents to Redux actions.
BrowserKit/Tests/WebCompatReporterKitTests/WebCompatReportSheetViewControllerTests.swift Adds tests for sub-option selection delegate callbacks and typed cell dequeuing.
BrowserKit/Sources/WebCompatReporterKit/WebCompatReportViewModel.swift Extends the view model with section titles, row kinds, and menu options for rendering.
BrowserKit/Sources/WebCompatReporterKit/WebCompatReportSheetViewController.swift Implements header rendering, stable-id diffable data source, selection handling, and theme-driven reconfiguration.
BrowserKit/Sources/WebCompatReporterKit/WebCompatReporterUX.swift Adds a chevron sizing constant used by the category menu cell.
BrowserKit/Sources/WebCompatReporterKit/Preview/WebCompatReportSheetPreview.swift Updates preview to an interactive host that simulates store updates for the picker.
BrowserKit/Sources/WebCompatReporterKit/Cells/WebCompatSubOptionCell.swift New cell for sub-option rows with checkmark + accessibility traits.
BrowserKit/Sources/WebCompatReporterKit/Cells/WebCompatCategoryMenuCell.swift New cell implementing the full-width category pull-down button + dynamic type chevron sizing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 248 to 252
self.theme = theme
view.backgroundColor = theme.colors.layer1
collectionView.backgroundColor = theme.colors.layer1
collectionView.setCollectionViewLayout(makeLayout(backgroundColor: theme.colors.layer1), animated: false)
navigationController?.navigationBar.tintColor = theme.colors.actionPrimary

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. Moved self.theme = theme above the guard isViewLoaded so it short-circuits before any view/collectionView access. viewDidLoad calls applyTheme itself, so an early call just stores the theme and the colors apply once the view loads.

Comment on lines 204 to +208
for section in viewModel.sections {
snapshot.appendSections([section])
snapshot.appendItems(section.rows, toSection: section)
sectionsByID[section.id] = section
snapshot.appendSections([section.id])
for row in section.rows { rowsByID[row.id] = row }
snapshot.appendItems(section.rows.map { $0.id }, toSection: section.id)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Leaving this one out. The ids are set entirely by the Client mapping (fixed section ids plus unique category and sub-option row ids), so duplicates can't arise here. And NSDiffableDataSourceSnapshot already traps on duplicate item identifiers, so a dup would fail loudly rather than mis-render silently. Happy to add asserts if you'd rather have the contract spelled out.

Comment on lines +7 to +8
/// Issue categories for the "Report a Website Issue" form. Raw values are Glean
/// `broken-site-report` reason keys, not display copy.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch, the comment was wrong. The category cases have no explicit raw values, so they're camelCase identifiers, not Glean reason keys. The reason keys are the snake_case WebCompatSubOption.rawValues. Reworded the doc to call the category a grouping and moved the Glean-key note onto WebCompatSubOption.

@razvanlitianu razvanlitianu force-pushed the rlitianu/fxios-16181-webcompat-issue-picker branch from 10bc19a to acfa203 Compare July 7, 2026 09:21
@Cramsden

Cramsden commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

It looks like some of the added test files are missing some test coverage. Can we add some?

@razvanlitianu razvanlitianu requested review from a team as code owners July 8, 2026 06:28
@razvanlitianu razvanlitianu requested review from AaronMT and ahal July 8, 2026 06:28
@razvanlitianu

Copy link
Copy Markdown
Collaborator Author

Thanks for the review @Cramsden. The coverage is there; the gate just wasn't seeing it. WebCompatReporterKit is covered by WebCompatReporterKitTests (locally: WebCompatReportViewModel 100%, WebCompatReportSheetViewController 91.6%, WebCompatCategoryMenuCell 84%, WebCompatSubOptionCell 54%).

The issue is that the coverage gate builds coverage.json from a single Fennec UnitTest .xcresult, which doesn't reliably include the package test bundle. As a result, those files were reported as 0% covered and only picked up incidental coverage from the Client target.

I confirmed this by temporarily running the package tests in the Danger step and merging their coverage. With that change, the gate passed and WebCompatReporterKit reported 87.65% coverage (against 2f2ba94). Since that's a CI infrastructure issue rather than something this PR should solve, I reverted the experiment.

@razvanlitianu razvanlitianu force-pushed the rlitianu/fxios-16181-webcompat-issue-picker branch from 2f2ba94 to acfa203 Compare July 8, 2026 06:54
@razvanlitianu

Copy link
Copy Markdown
Collaborator Author

Flagging this for infra before I take you off the reviewers. Nothing to review in this PR, I just wanted the context on record.

This PR tripped the code-coverage gate with the WebCompatReporterKit files reported at 0%, even though they're well covered by WebCompatReporterKitTests. The gate generates coverage.json from a single Fennec UnitTest .xcresult (the "Run Danger" step in bitrise.yml), and that result doesn't reliably include the BrowserKit package test bundles. It appears to be a combination of test sharding and the Fennec build not consistently building the package test targets, so package files fall back to incidental Client-side coverage and end up reporting 0% (or much lower than their actual coverage).

I validated a potential fix by temporarily running the package tests in the Danger step and merging their coverage into coverage.json. With that change, the gate passed and WebCompatReporterKit reported 87.65% coverage (against 2f2ba94). I reverted the experiment because it's a package-specific workaround rather than a proper solution, and filed [ticket] to address it in CI by either merging coverage from all package test bundles or ensuring the coverage .xcresult spans every bundle. In the meantime, I'm using ignore-code-coverage here, similar to #34499.

@razvanlitianu razvanlitianu added the ignore-code-coverage Use this label with a comment and tag the unit tests owners label Jul 8, 2026
@razvanlitianu razvanlitianu removed request for a team, AaronMT and ahal July 8, 2026 06:55
@mergify

mergify Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

This pull request has conflicts when rebasing. Could you fix it @razvanlitianu? 🙏

Add the two-level Site Issue picker to the report sheet: a native UIMenu
category pull-down and sub-option rows with a checkmark on the selected one.

- Extend WebCompatReportViewModel.Row with a Kind (plain / categoryMenu /
  subOption) and Section headers; render via dedicated WebCompatCategoryMenuCell
  and WebCompatSubOptionCell keyed by stable ids in the diffable data source.
- Add didSelectCategory/didSelectSubOption sheet delegate intents; the Client
  maps WebCompatReporterState to the view model and dispatches selectCategory/
  selectSubOption.
- Introduce WebCompatSubOption enum (raw values = Glean reason keys); category/
  sub-option display titles map from the staged Strings in the Client.
- Accessibility: selected/button/header traits, decorative glyphs hidden from
  VoiceOver, chevron scales with Dynamic Type.
Experiment for FXIOS-16181 to confirm the coverage gate can see the
WebCompatReporterKit test bundle. Runs WebCompatReporterKitTests in the
Danger step and merges its coverage into coverage.json. To be reverted.
Reverts 2f2ba94. Kept the experiment commit above as a reference for
infra: running WebCompatReporterKitTests in the Danger step and merging
their coverage into coverage.json flipped the code-coverage gate green
(WebCompatReporterKit 87.65%). The real fix belongs at the CI level, not
in this feature PR, so it's reverted here.
@razvanlitianu razvanlitianu force-pushed the rlitianu/fxios-16181-webcompat-issue-picker branch from d92e972 to d60f399 Compare July 8, 2026 09:08

nonisolated func handleNotifications(_ notification: Notification) {
guard notification.name == UIContentSizeCategory.didChangeNotification else { return }
DispatchQueue.main.async { [self] in

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we use ensureMainThread here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, switched to ensureMainThread.

/// Keeps the chevron and the button's reserved trailing space in step with
/// the current Dynamic Type size.
private func applyScaledMetrics() {
let size = scaledChevronSize

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: do we need a new variable here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, inlined scaledChevronSize so there's no local.


/// Preview host that fakes the store loop: holds the selection and reconfigures
/// the sheet on each intent, so the canvas behaves like the connected screen.
private final class WebCompatPickerPreviewController: UINavigationController, WebCompatReportSheetDelegate {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you elaborate on why we need all of this complicated code to just create the view for preview?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fair, that was left over from making the picker tappable in the canvas. Simplified it to two plain #Previews (placeholder and a selected category with sub-options) using small section builders, no state host.

- Use ensureMainThread instead of DispatchQueue.main.async in the cell's
  content-size handler.
- Mutate menuButton.configuration in place instead of a temp copy.
- Replace the interactive preview host with two static #Preview states.
@razvanlitianu razvanlitianu force-pushed the rlitianu/fxios-16181-webcompat-issue-picker branch from 424929f to f1108a7 Compare July 8, 2026 17:07
@razvanlitianu razvanlitianu requested a review from Cramsden July 8, 2026 17:08
@lmarceau

lmarceau commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

ignore-code-coverage shouldn't be added on this PR IMO. WebCompatReporterKit wasn't properly setup for unit tests code coverage. Was steps in How to create a BrowserKit package followed? This covers how to make sure the code coverage is actually gathered proplery whenever adding a new package.

Comment thread firefox-ios/Shared/Strings.swift Outdated
@Cramsden

Cramsden commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
Simulator Screenshot - iPhone 17 - 2026-07-08 at 11 19 30 These dark mode colors feel a little off.. Is there a figma for these changes?

@razvanlitianu razvanlitianu removed the ignore-code-coverage Use this label with a comment and tag the unit tests owners label Jul 8, 2026
@razvanlitianu

Copy link
Copy Markdown
Collaborator Author

Simulator Screenshot - iPhone 17 - 2026-07-08 at 11 19 30 These dark mode colors feel a little off.. Is there a figma for these changes?

Good catch. The cells were falling back to the system grouped background instead of the theme's card color, which made them look out of place in dark mode.

I've switched them to .listGroupedCell() with theme.colors.layer5 (matching the Translations cells), so they now use the standard theme tokens: layer1 for the sheet background, layer5 for the cards, and textPrimary/textSecondary for text. This keeps them aligned with the app's dark theme.

…version

- Give the picker cells .listGroupedCell() + theme.colors.layer5 so cards use
  the theme card color in dark mode (matches the Translations cells).
- Set up WebCompatReporterKit for code coverage per the BrowserKit package
  guide: add CodeCoverageTargets/Testables to its scheme and wire it into
  Fennec.xcscheme (build-for-testing, code coverage, test plan).
- Bump the staged IssueSection strings to .v154 for the current train.
@razvanlitianu razvanlitianu force-pushed the rlitianu/fxios-16181-webcompat-issue-picker branch from 439f99f to e637bbe Compare July 8, 2026 17:39
@razvanlitianu razvanlitianu requested a review from lmarceau July 8, 2026 17:44
@lmarceau

lmarceau commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

I'll let Carson do the review of this PR, I only commented for the small Strings comment and the unit tests code coverage stuff. Those are fixed so all good on my end 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants