Bugfix FXIOS-26736 [Search] Discard stale suggestions and add append-arrow regression tests#34583
Open
arulagarwal wants to merge 2 commits into
Open
Bugfix FXIOS-26736 [Search] Discard stale suggestions and add append-arrow regression tests#34583arulagarwal wants to merge 2 commits into
arulagarwal wants to merge 2 commits into
Conversation
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📜 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 oldappend(_ 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
UIActionthat 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:
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 siblingloadFirefoxSuggestions()already guards exactly this (searchQuery == tempSearchQuery) — this PR mirrors that guard into the suggest-client callback.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, notCloses, 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