Skip to content

Bugfix FXIOS-26736 [Search] Discard stale suggestions and add append-arrow regression tests#34583

Open
arulagarwal wants to merge 2 commits into
mozilla-mobile:mainfrom
arulagarwal:fix-26736-search-autocomplete
Open

Bugfix FXIOS-26736 [Search] Discard stale suggestions and add append-arrow regression tests#34583
arulagarwal wants to merge 2 commits into
mozilla-mobile:mainfrom
arulagarwal:fix-26736-search-autocomplete

Conversation

@arulagarwal

Copy link
Copy Markdown

📜 Tickets

Jira ticket: N/A (external contribution, no JIRA access)
Github issue

💡 Description

While investigating #26736 ("wrong or no option is autocompleted in the search bar"), I found that the deterministic bug described in the issue is already gone on main. The old append(_ sender: UIButton) handler resolved the tapped suggestion geometrically from the button's top-left corner (sender.convert(CGPoint(), to: tableView) + indexPathForRow(at:)). That button was a fixed 44×44pt view centered by UIKit inside a self-sizing row; at below-default Dynamic Type sizes the row could be shorter than 44pt, so the button's corner physically overlapped the row above — resolving to the wrong suggestion every time, and to the typed-query row (which has no arrow) or nothing when the first arrow-bearing row was tapped. That's a fully self-consistent explanation for both the "wrong option" and "no option" halves of the report, and for why it wasn't always reproducible (it depends on text size).

That handler was removed incidentally by #29727 (an unrelated Trending Searches refactor), which replaced it with a UIAction that captures each row's own text at cell-configure time — no geometry involved. Neither that PR nor any other commit references #26736.

Two things were still worth fixing in the same area, which is what this PR does:

  1. SearchViewModel.querySuggestClient()'s callback didn't check staleness. It applies a suggest-engine response without verifying the query it answered is still current. cancelPendingRequest() is best-effort, so a slow response for an older query could land after the user kept typing and overwrite fresher suggestions with stale ones. The sibling loadFirefoxSuggestions() already guards exactly this (searchQuery == tempSearchQuery) — this PR mirrors that guard into the suggest-client callback.
  2. The append-arrow "tap row N, get row N's text" contract had no real test. The only test touching it (SearchTest.testSearchSuggestions) asserted the URL bar merely contained the typed prefix — an assertion that passes even on a wrong-row fill. That gap is how the original bug shipped for several releases undetected. This PR adds three unit tests exercising the real cell → button → delegate path, and tightens the XCUITest to assert exact text equality on a specific non-first row instead of a substring check.

Filed as Refs, not Closes, since the originally-reported symptom is already fixed upstream by #29727 — this hardens a related edge case and adds the missing regression coverage.

🎥 Demos

No UI/visual change — this is a logic guard plus test coverage. In place of screenshots, here's real verification on a booted iOS 26.5 simulator:

  • xcodebuild test -only-testing:ClientTests/SearchViewControllerTest — all 5 tests in the class (the 3 new ones + 2 pre-existing, unrelated ones) pass deterministically across 5 consecutive runs.
  • xcodebuild test -testPlan FullFunctionalTestPlan -only-testing:XCUITests/SearchTests/testSearchSuggestions — passes in 68.9s: types a query, waits for live search suggestions, taps a specific non-first row's arrow, and asserts the URL bar holds exactly that row's text.

📝 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) — N/A, no UI changes
  • If adding telemetry, I read the data stewardship requirements and will request a data review — N/A, no telemetry added
  • If adding or modifying strings, I read the guidelines and will request a string review from l10n — N/A, no strings added
  • If needed, I updated documentation and added comments to complex code

querySuggestClient()'s network callback applied suggest-engine results
without checking that the query it answered is still the current one.
cancelPendingRequest() is best-effort, so a slow response for an older
query could land after the user kept typing and overwrite suggestions
for the newer query with stale ones.

loadFirefoxSuggestions() already guards this exact case with
searchQuery == tempSearchQuery. Mirror that guard in the suggest-client
callback so a stale response is dropped instead of applied.

Refs mozilla-mobile#26736
…pping

The search-suggestions append arrow previously had no test that pinned
"tap the arrow on row N, get row N's text" as a contract. The one
XCUITest that exercised it asserted the URL bar merely contained the
typed prefix, which passes even when the wrong row is filled - exactly
how issue mozilla-mobile#26736 shipped undetected for several releases before an
unrelated refactor happened to fix the underlying mechanism.

Add three unit tests in SearchViewControllerTests.swift (with a new
MockSearchViewControllerDelegate) that exercise the append button
through the real cellForRowAt: -> UIAction -> delegate path:
- tapping a suggestion row's arrow fills exactly that row's text
  (plus trailing space) without submitting
- the typed-query row (row 0) has no arrow
- a row reconfigured after a suggestions refresh fills the updated
  text, not a stale capture

Tighten the existing testSearchSuggestions XCUITest to read a specific
non-first row's label before tapping it and assert exact equality
against the resulting URL bar value, instead of the substring check
that couldn't have caught this bug.

Refs mozilla-mobile#26736
@arulagarwal arulagarwal requested review from a team as code owners July 9, 2026 00:18
@arulagarwal arulagarwal requested a review from mdotb-moz July 9, 2026 00:18
arulagarwal added a commit to arulagarwal/github-contribution-log that referenced this pull request Jul 9, 2026
…pened

Fill in Phase II analysis with root-cause findings and git archaeology,
Phase III implementation notes including two real test-harness bugs
found and fixed via actual simulator runs, and Phase IV with the opened
PR (mozilla-mobile/firefox-ios#34583) and the maintainer comment.

Update the parent README's status for contribution 2 from Phase I to
Phase IV.
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.

1 participant