Skip to content

Commit 7cb3e65

Browse files
teamehTieme van Veenstephencelis
authored andcommitted
Fix pointfreeco#440 Webview loading without delegate (option 2) (pointfreeco#443)
* Fix pointfreeco#440 - Improve WKWebView navigation delegate * Fix pointfreeco#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 4a703c6 commit 7cb3e65

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
@@ -1111,6 +1111,80 @@ final class SnapshotTestingTests: XCTestCase {
11111111
#endif
11121112
}
11131113

1114+
#if os(iOS) || os(macOS)
1115+
final class ManipulatingWKWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
1116+
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
1117+
webView.evaluateJavaScript("document.body.children[0].classList.remove(\"hero\")") // Change layout
1118+
}
1119+
}
1120+
func testWebViewWithManipulatingNavigationDelegate() throws {
1121+
let manipulatingWKWebViewNavigationDelegate = ManipulatingWKWebViewNavigationDelegate()
1122+
let webView = WKWebView()
1123+
webView.navigationDelegate = manipulatingWKWebViewNavigationDelegate
1124+
1125+
let fixtureUrl = URL(fileURLWithPath: String(#file), isDirectory: false)
1126+
.deletingLastPathComponent()
1127+
.appendingPathComponent("__Fixtures__/pointfree.html")
1128+
let html = try String(contentsOf: fixtureUrl)
1129+
webView.loadHTMLString(html, baseURL: nil)
1130+
if !ProcessInfo.processInfo.environment.keys.contains("GITHUB_WORKFLOW") {
1131+
assertSnapshot(
1132+
matching: webView,
1133+
as: .image(size: .init(width: 800, height: 600)),
1134+
named: platform
1135+
)
1136+
}
1137+
_ = manipulatingWKWebViewNavigationDelegate
1138+
}
1139+
1140+
#if os(iOS) || os(macOS)
1141+
func testWebViewWithRealUrl() throws {
1142+
let manipulatingWKWebViewNavigationDelegate = ManipulatingWKWebViewNavigationDelegate()
1143+
let webView = WKWebView()
1144+
webView.navigationDelegate = manipulatingWKWebViewNavigationDelegate
1145+
1146+
webView.load(URLRequest(url: URL(string: "https://www.pointfree.co")!))
1147+
if !ProcessInfo.processInfo.environment.keys.contains("GITHUB_WORKFLOW") {
1148+
assertSnapshot(
1149+
matching: webView,
1150+
as: .image(size: .init(width: 800, height: 600)),
1151+
named: platform
1152+
)
1153+
}
1154+
_ = manipulatingWKWebViewNavigationDelegate
1155+
}
1156+
#endif
1157+
1158+
final class CancellingWKWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
1159+
func webView(
1160+
_ webView: WKWebView,
1161+
decidePolicyFor navigationAction: WKNavigationAction,
1162+
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
1163+
) {
1164+
decisionHandler(.cancel)
1165+
}
1166+
}
1167+
func testWebViewWithCancellingNavigationDelegate() throws {
1168+
let cancellingWKWebViewNavigationDelegate = CancellingWKWebViewNavigationDelegate()
1169+
let webView = WKWebView()
1170+
webView.navigationDelegate = cancellingWKWebViewNavigationDelegate
1171+
1172+
let fixtureUrl = URL(fileURLWithPath: String(#file), isDirectory: false)
1173+
.deletingLastPathComponent()
1174+
.appendingPathComponent("__Fixtures__/pointfree.html")
1175+
let html = try String(contentsOf: fixtureUrl)
1176+
webView.loadHTMLString(html, baseURL: nil)
1177+
if !ProcessInfo.processInfo.environment.keys.contains("GITHUB_WORKFLOW") {
1178+
assertSnapshot(
1179+
matching: webView,
1180+
as: .image(size: .init(width: 800, height: 600)),
1181+
named: platform
1182+
)
1183+
}
1184+
_ = cancellingWKWebViewNavigationDelegate
1185+
}
1186+
#endif
1187+
11141188
@available(iOS 13.0, *)
11151189
func testSwiftUIView_iOS() {
11161190
#if os(iOS)
Loading

0 commit comments

Comments
 (0)