Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions BrowserKit/Tests/WebEngineTests/Mock/MockWKFrameInfo.swift

This file was deleted.

31 changes: 0 additions & 31 deletions BrowserKit/Tests/WebEngineTests/Mock/MockWKSecurityOrigin.swift

This file was deleted.

50 changes: 50 additions & 0 deletions BrowserKit/Tests/WebEngineTests/Utilities/WebKitTestHelpers.swift
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
}
}
34 changes: 23 additions & 11 deletions BrowserKit/Tests/WebEngineTests/WKUIHandlerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 +38 to 55
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "WKUIHandlerTests.swift" -type f

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 146


🏁 Script executed:

cat -n ./BrowserKit/Tests/WebEngineTests/WKUIHandlerTests.swift | head -100

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 4546


Fix expectation fulfillment order (test currently times out).

Line 53 calls wait(for:) before line 54 calls expectation.fulfill(), so the wait will never complete and the test will timeout. Move expectation creation before the closure and add fulfillment inside the decision handler.

Suggested 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()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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()
}
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])
🤖 Prompt for AI Agents
In `@BrowserKit/Tests/WebEngineTests/WKUIHandlerTests.swift` around lines 38 - 55,
The test times out because expectation is created after calling wait and never
fulfilled; move creation of the XCTestExpectation to before invoking
subject.webView, capture it in the decision handler passed to
subject.webView(requestMediaCapturePermissionFor:initiatedByFrame:type:decisionHandler:),
and call expectation.fulfill() inside the decision handler (the closure
currently referenced as decisionHandler) after asserting
XCTAssertEqual(decision, .prompt); this ensures
WebKitTestHelpers.captureFrameAndOrigin(for:) / subject.webView(...) triggers
the closure which then fulfills the expectation.


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
)
Expand All @@ -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
)
Expand Down