-
Notifications
You must be signed in to change notification settings - Fork 0
Bugfix FXIOS-14456 #31308 ⁃ Fix test failing on XCode 26.2 to enable using this version on Bitrise #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: coderabbit_combined_20260121_augment_sentry_coderabbit_1_base_bugfix_fxios-14456_31308__fix_test_failing_on_xcode_262_to_enable_using_this_version_on_bitrise_pr222
Are you sure you want to change the base?
Bugfix FXIOS-14456 #31308 ⁃ Fix test failing on XCode 26.2 to enable using this version on Bitrise #25
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/ | ||
|
|
||
| import WebKit | ||
| import XCTest | ||
|
|
||
| /// Provides real `WKFrameInfo` and `WKSecurityOrigin` objects for tests. | ||
| /// These types can no longer be created or mocked safely, as WebKit now requires | ||
| /// fully initialized instances. This helper loads a lightweight `WKWebView` | ||
| /// navigation and captures the frame and origin values that WebKit supplies. | ||
| final class WebKitTestHelpers { | ||
| class FakeWKNavigationDelegate: NSObject, WKNavigationDelegate { | ||
| let expect: XCTestExpectation | ||
| var capturedFrame: WKFrameInfo? | ||
| var capturedOrigin: WKSecurityOrigin? | ||
|
|
||
| init(expect: XCTestExpectation) { self.expect = expect } | ||
|
|
||
| func webView(_ webView: WKWebView, | ||
| decidePolicyFor navigationAction: WKNavigationAction, | ||
| decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { | ||
| let frame = navigationAction.targetFrame | ||
| capturedFrame = frame | ||
| capturedOrigin = frame?.securityOrigin | ||
| decisionHandler(.allow) | ||
| expect.fulfill() | ||
| return | ||
| } | ||
| } | ||
|
|
||
| // Loads a URL in a real WKWebView and returns the first valid | ||
| // WKFrameInfo and WKSecurityOrigin from a navigation action. | ||
| static func captureFrameAndOrigin(for url: URL, timeout: TimeInterval = 3.0) -> (WKFrameInfo, WKSecurityOrigin)? { | ||
| let webView = WKWebView(frame: .zero) | ||
| let expect = XCTestExpectation(description: "capture frame & origin") | ||
|
|
||
| let delegate = FakeWKNavigationDelegate(expect: expect) | ||
| webView.navigationDelegate = delegate | ||
|
|
||
| // load a real https URL (use example.com to be safe) | ||
| webView.load(URLRequest(url: url)) | ||
|
|
||
| let waiter = XCTWaiter.wait(for: [expect], timeout: timeout) | ||
| if let frame = delegate.capturedFrame, let origin = delegate.capturedOrigin { | ||
| return (frame, origin) | ||
| } | ||
| return nil | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,32 +35,40 @@ final class WKUIHandlerTests: XCTestCase { | |
| func testRequestMediaCaptureSuccess() { | ||
| let subject = createSubject(isActive: true) | ||
|
|
||
| let expectation = expectation(description: "Wait for the decision handler to be called") | ||
| guard let (frame, origin) = WebKitTestHelpers.captureFrameAndOrigin(for: URL(string: "https://example.com")!) else { | ||
| XCTFail("Could not obtain WKFrameInfo") | ||
| return | ||
| } | ||
|
|
||
| let decisionHandler = { (decision: WKPermissionDecision) in | ||
| XCTAssertEqual(decision, .prompt) | ||
| expectation.fulfill() | ||
| } | ||
|
|
||
| let expectation = expectation(description: "Wait for the decision handler to be called") | ||
| subject.webView(MockWKWebView(), | ||
| requestMediaCapturePermissionFor: MockWKSecurityOrigin.new(nil), | ||
| initiatedByFrame: MockWKFrameInfo(), | ||
| requestMediaCapturePermissionFor: origin, | ||
| initiatedByFrame: frame, | ||
| type: .cameraAndMicrophone, | ||
| decisionHandler: decisionHandler | ||
| ) | ||
| decisionHandler: decisionHandler) | ||
| wait(for: [expectation]) | ||
| expectation.fulfill() | ||
| } | ||
|
Comment on lines
35
to
55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n BrowserKit/Tests/WebEngineTests/WKUIHandlerTests.swift | sed -n '35,60p'Repository: qodo-benchmark/firefox-ios-combined-coderabbit Length of output: 1413 🏁 Script executed: find . -name "WKUIHandlerTests.swift" -type fRepository: qodo-benchmark/firefox-ios-combined-coderabbit Length of output: 146 Fix expectation lifecycle to prevent test timeout. The Fix- let decisionHandler = { (decision: WKPermissionDecision) in
- XCTAssertEqual(decision, .prompt)
- }
-
- let expectation = expectation(description: "Wait for the decision handler to be called")
+ let expectation = expectation(description: "Wait for the decision handler to be called")
+ let decisionHandler = { (decision: WKPermissionDecision) in
+ XCTAssertEqual(decision, .prompt)
+ expectation.fulfill()
+ }
subject.webView(MockWKWebView(),
requestMediaCapturePermissionFor: origin,
initiatedByFrame: frame,
type: .cameraAndMicrophone,
decisionHandler: decisionHandler)
wait(for: [expectation])
- expectation.fulfill()🤖 Prompt for AI Agents |
||
|
|
||
| func testRequestMediaCaptureIsActiveFalse() { | ||
| let subject = createSubject(isActive: false) | ||
| let expectation = expectation(description: "Wait for the decision handler to be called") | ||
| guard let (frame, origin) = WebKitTestHelpers.captureFrameAndOrigin(for: URL(string: "https://example.com")!) else { | ||
| XCTFail("Could not obtain WKFrameInfo") | ||
| return | ||
| } | ||
|
|
||
| let expectation = expectation(description: "Wait for the decision handler to be called") | ||
| let decisionHandler = { (decision: WKPermissionDecision) in | ||
| XCTAssertEqual(decision, .deny) | ||
| expectation.fulfill() | ||
| } | ||
| subject.webView(MockWKWebView(), | ||
| requestMediaCapturePermissionFor: MockWKSecurityOrigin.new(nil), | ||
| initiatedByFrame: MockWKFrameInfo(), | ||
| requestMediaCapturePermissionFor: origin, | ||
| initiatedByFrame: frame, | ||
| type: .cameraAndMicrophone, | ||
| decisionHandler: decisionHandler | ||
| ) | ||
|
|
@@ -70,15 +78,19 @@ final class WKUIHandlerTests: XCTestCase { | |
| func testRequestMediaCaptureDelegateReturnsFalse() { | ||
| sessionDelegate.hasMediaCapturePermission = false | ||
| let subject = createSubject(isActive: true) | ||
| guard let (frame, origin) = WebKitTestHelpers.captureFrameAndOrigin(for: URL(string: "https://example.com")!) else { | ||
| XCTFail("Could not obtain WKFrameInfo") | ||
| return | ||
| } | ||
| let expectation = expectation(description: "Wait for the decision handler to be called") | ||
|
|
||
| let decisionHandler = { (decision: WKPermissionDecision) in | ||
| XCTAssertEqual(decision, .deny) | ||
| expectation.fulfill() | ||
| } | ||
| subject.webView(MockWKWebView(), | ||
| requestMediaCapturePermissionFor: MockWKSecurityOrigin.new(nil), | ||
| initiatedByFrame: MockWKFrameInfo(), | ||
| requestMediaCapturePermissionFor: origin, | ||
| initiatedByFrame: frame, | ||
| type: .cameraAndMicrophone, | ||
| decisionHandler: decisionHandler | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 157
🏁 Script executed:
git ls-files | grep -i webkittesthelpersRepository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 155
🏁 Script executed:
Repository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 230
🏁 Script executed:
Repository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 2187
🏁 Script executed:
rg "FakeWKNavigationDelegate" --type swift -A 5 -B 2Repository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 1813
🏁 Script executed:
rg "captureFrameAndOrigin" --type swift -B 3 -A 3Repository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 3079
🏁 Script executed:
web_search XCTestExpectation fulfill multiple times behaviorRepository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 196
🌐 Web query:
XCTestExpectation fulfill called multiple times fatal error💡 Result:
Cause:
Fixes (choose one):
References:
🏁 Script executed:
web_search example.com HTTP redirects test behaviorRepository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 190
🏁 Script executed:
Repository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 199
🌐 Web query:
WKNavigationDelegate decidePolicyFor called multiple times redirects subframes💡 Result:
Short answer: decidePolicyForNavigationAction can be invoked multiple times because WKWebView reports navigations for the main frame, for subframes/iframes, and again for provisional redirects (and for new-window/targetFrame=nil cases). Check navigationAction.targetFrame?.isMainFrame (or navigationAction.request.mainDocumentURL / navigationAction.sourceFrame) to distinguish main-frame navigations and avoid double-handling, and ensure you call the decisionHandler exactly once per callback.
Notes / tips:
Sources:
🌐 Web query:
example.com HTTP 301 redirect test💡 Result:
Short answer: example.com redirects HTTP -> HTTPS. I confirmed by requesting http://example.com which returned the site served at https://example.com. [1]
To verify yourself, run:
Expected output shows a 301/3xx status and a Location: https://example.com/ header. Use -L to follow the redirect chain. [2]
Sources:
[1] example.com homepage (requested via HTTP/HTTPS).
[2] Guide: using curl to test HTTP->HTTPS redirects.
🏁 Script executed:
rg "https://example.com" BrowserKit/Tests/WebEngineTests/ --type swiftRepository: qodo-benchmark/firefox-ios-combined-coderabbit
Length of output: 1541
Guard against multiple expectation fulfillments from repeated navigation callbacks.
decidePolicyForfires multiple times during real WKWebView navigation (for provisional navigations, redirects, and subframes). Callingexpect.fulfill()unconditionally will cause a fatal error in XCTest. Add a flag to ensure fulfillment happens only once.Proposed fix
class FakeWKNavigationDelegate: NSObject, WKNavigationDelegate { let expect: XCTestExpectation var capturedFrame: WKFrameInfo? var capturedOrigin: WKSecurityOrigin? + private var didFulfill = false init(expect: XCTestExpectation) { self.expect = expect } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: `@escaping` (WKNavigationActionPolicy) -> Void) { + if !didFulfill { + let frame = navigationAction.targetFrame + capturedFrame = frame + capturedOrigin = frame?.securityOrigin + didFulfill = true + expect.fulfill() + } decisionHandler(.allow) - let frame = navigationAction.targetFrame - capturedFrame = frame - capturedOrigin = frame?.securityOrigin - decisionHandler(.allow) - expect.fulfill() - return } }📝 Committable suggestion
🤖 Prompt for AI Agents