Skip to content

Commit 6bc120b

Browse files
teamehTieme van Veenstephencelis
authored
Fix #440 Webview loading without delegate (option 2) (#443)
* Fix #440 - Improve WKWebView navigation delegate * Fix #440 - Replace WKWebView navigation delegate by observing wkWebView.isLoading Co-authored-by: Tieme van Veen <[email protected]> Co-authored-by: Stephen Celis <[email protected]>
1 parent 012fd98 commit 6bc120b

8 files changed

+82
-20
lines changed

Sources/SnapshotTesting/Common/View.swift

+8-20
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,6 @@ extension View {
753753
#if os(iOS) || os(macOS)
754754
if let wkWebView = self as? WKWebView {
755755
return Async<Image> { callback in
756-
let delegate = NavigationDelegate()
757756
let work = {
758757
if #available(iOS 11.0, macOS 10.13, *) {
759758
inWindow {
@@ -762,7 +761,6 @@ extension View {
762761
return
763762
}
764763
wkWebView.takeSnapshot(with: nil) { image, _ in
765-
_ = delegate
766764
callback(image!)
767765
}
768766
}
@@ -776,8 +774,14 @@ extension View {
776774
}
777775

778776
if wkWebView.isLoading {
779-
delegate.didFinish = work
780-
wkWebView.navigationDelegate = delegate
777+
var subscription: NSKeyValueObservation?
778+
subscription = wkWebView.observe(\.isLoading, options: [.initial, .new]) { (webview, change) in
779+
subscription?.invalidate()
780+
subscription = nil
781+
if change.newValue == false {
782+
work()
783+
}
784+
}
781785
} else {
782786
work()
783787
}
@@ -796,22 +800,6 @@ extension View {
796800
#endif
797801
}
798802

799-
#if os(iOS) || os(macOS)
800-
private final class NavigationDelegate: NSObject, WKNavigationDelegate {
801-
var didFinish: () -> Void
802-
803-
init(didFinish: @escaping () -> Void = {}) {
804-
self.didFinish = didFinish
805-
}
806-
807-
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
808-
webView.evaluateJavaScript("document.readyState") { _, _ in
809-
self.didFinish()
810-
}
811-
}
812-
}
813-
#endif
814-
815803
#if os(iOS) || os(tvOS)
816804
extension UIApplication {
817805
static var sharedIfAvailable: UIApplication? {

Tests/SnapshotTestingTests/SnapshotTestingTests.swift

+74
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,80 @@ final class SnapshotTestingTests: XCTestCase {
10611061
#endif
10621062
}
10631063

1064+
#if os(iOS) || os(macOS)
1065+
final class ManipulatingWKWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
1066+
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
1067+
webView.evaluateJavaScript("document.body.children[0].classList.remove(\"hero\")") // Change layout
1068+
}
1069+
}
1070+
func testWebViewWithManipulatingNavigationDelegate() throws {
1071+
let manipulatingWKWebViewNavigationDelegate = ManipulatingWKWebViewNavigationDelegate()
1072+
let webView = WKWebView()
1073+
webView.navigationDelegate = manipulatingWKWebViewNavigationDelegate
1074+
1075+
let fixtureUrl = URL(fileURLWithPath: String(#file), isDirectory: false)
1076+
.deletingLastPathComponent()
1077+
.appendingPathComponent("__Fixtures__/pointfree.html")
1078+
let html = try String(contentsOf: fixtureUrl)
1079+
webView.loadHTMLString(html, baseURL: nil)
1080+
if !ProcessInfo.processInfo.environment.keys.contains("GITHUB_WORKFLOW") {
1081+
assertSnapshot(
1082+
matching: webView,
1083+
as: .image(size: .init(width: 800, height: 600)),
1084+
named: platform
1085+
)
1086+
}
1087+
_ = manipulatingWKWebViewNavigationDelegate
1088+
}
1089+
1090+
#if os(iOS) || os(macOS)
1091+
func testWebViewWithRealUrl() throws {
1092+
let manipulatingWKWebViewNavigationDelegate = ManipulatingWKWebViewNavigationDelegate()
1093+
let webView = WKWebView()
1094+
webView.navigationDelegate = manipulatingWKWebViewNavigationDelegate
1095+
1096+
webView.load(URLRequest(url: URL(string: "https://www.pointfree.co")!))
1097+
if !ProcessInfo.processInfo.environment.keys.contains("GITHUB_WORKFLOW") {
1098+
assertSnapshot(
1099+
matching: webView,
1100+
as: .image(size: .init(width: 800, height: 600)),
1101+
named: platform
1102+
)
1103+
}
1104+
_ = manipulatingWKWebViewNavigationDelegate
1105+
}
1106+
#endif
1107+
1108+
final class CancellingWKWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
1109+
func webView(
1110+
_ webView: WKWebView,
1111+
decidePolicyFor navigationAction: WKNavigationAction,
1112+
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
1113+
) {
1114+
decisionHandler(.cancel)
1115+
}
1116+
}
1117+
func testWebViewWithCancellingNavigationDelegate() throws {
1118+
let cancellingWKWebViewNavigationDelegate = CancellingWKWebViewNavigationDelegate()
1119+
let webView = WKWebView()
1120+
webView.navigationDelegate = cancellingWKWebViewNavigationDelegate
1121+
1122+
let fixtureUrl = URL(fileURLWithPath: String(#file), isDirectory: false)
1123+
.deletingLastPathComponent()
1124+
.appendingPathComponent("__Fixtures__/pointfree.html")
1125+
let html = try String(contentsOf: fixtureUrl)
1126+
webView.loadHTMLString(html, baseURL: nil)
1127+
if !ProcessInfo.processInfo.environment.keys.contains("GITHUB_WORKFLOW") {
1128+
assertSnapshot(
1129+
matching: webView,
1130+
as: .image(size: .init(width: 800, height: 600)),
1131+
named: platform
1132+
)
1133+
}
1134+
_ = cancellingWKWebViewNavigationDelegate
1135+
}
1136+
#endif
1137+
10641138
@available(iOS 13.0, *)
10651139
func testSwiftUIView_iOS() {
10661140
#if os(iOS)
Loading

0 commit comments

Comments
 (0)