Attribute non-network loads and loads with html strings as automatically app-bound
authorkatherine_cheney@apple.com <katherine_cheney@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 May 2020 01:21:20 +0000 (01:21 +0000)
committerkatherine_cheney@apple.com <katherine_cheney@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 May 2020 01:21:20 +0000 (01:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=211913
<rdar://problem/63157801

Reviewed by Brent Fulgham.

Source/WebKit:

Move logic from WebsiteDataStoreCocoa to WebPageProxy to check for
special app-bound protocols and set m_limitsNavigationToAppBoundDomains
to force these WebViews into app-bound mode.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _isForcedIntoAppBoundMode:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
Testing SPI to see whether m_limitsNavigationsToAppBoundDomains was
set.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::loadData):
Check for html string loads and force WebView into app-bound mode if needed.
No need to worry about setting this variable even if the app hasn't
opted in because setIsNavigatingToAppBoundDomainAndCheckIfPermitted
does an early return before checking this variable if
WKAppBoundDomains does not exist.

(WebKit::shouldTreatURLProtocolAsAppBound):
Adds javascript protocols to this check.

(WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
Check for special protocols here and force WebView into app-bound mode.

(WebKit::WebPageProxy::isForcedIntoAppBoundModeTesting):
* UIProcess/WebPageProxy.h:
* UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
(WebKit::WebsiteDataStore::beginAppBoundDomainCheck):
(WebKit::shouldTreatURLProtocolAsAppBound): Deleted.

Tools:

Adds new tests to check that WebView loads with HTML strings have
proper behavior.

Some tests need to test behavior on app-bound domains on webviews which do not specify
limitsNavigationsToAppBoundDomains. Since local files now do this
automatically, this patch updates those to use actual app-bound
domains from the WKAppBoundDomains list instead to maintain behavior.

Remove limitsNavigationsToAppBoundDomains for local files to make sure
they are forced into this mode automatically.

* TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
(-[InAppBrowserSchemeHandler webView:startURLSchemeTask:]):
(TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261727 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm

index 6d687d1..3654316 100644 (file)
@@ -1,3 +1,41 @@
+2020-05-14  Kate Cheney  <katherine_cheney@apple.com>
+
+        Attribute non-network loads and loads with html strings as automatically app-bound
+        https://bugs.webkit.org/show_bug.cgi?id=211913
+        <rdar://problem/63157801
+
+        Reviewed by Brent Fulgham.
+
+        Move logic from WebsiteDataStoreCocoa to WebPageProxy to check for
+        special app-bound protocols and set m_limitsNavigationToAppBoundDomains
+        to force these WebViews into app-bound mode.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _isForcedIntoAppBoundMode:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        Testing SPI to see whether m_limitsNavigationsToAppBoundDomains was
+        set.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::loadData):
+        Check for html string loads and force WebView into app-bound mode if needed.
+        No need to worry about setting this variable even if the app hasn't
+        opted in because setIsNavigatingToAppBoundDomainAndCheckIfPermitted
+        does an early return before checking this variable if
+        WKAppBoundDomains does not exist.
+
+        (WebKit::shouldTreatURLProtocolAsAppBound):
+        Adds javascript protocols to this check.
+
+        (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
+        Check for special protocols here and force WebView into app-bound mode.
+
+        (WebKit::WebPageProxy::isForcedIntoAppBoundModeTesting):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+        (WebKit::WebsiteDataStore::beginAppBoundDomainCheck):
+        (WebKit::shouldTreatURLProtocolAsAppBound): Deleted.
+
 2020-05-14  Timothy Hatcher  <timothy@apple.com>
 
         Add baseURL version of _WKUserStyleSheet forWKWebView.
index c287e16..4724f26 100644 (file)
@@ -2621,6 +2621,13 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     });
 }
 
+- (void)_isForcedIntoAppBoundMode:(void(^)(BOOL))completionHandler
+{
+    _page->isForcedIntoAppBoundModeTesting([completionHandler = makeBlockPtr(completionHandler)] (bool isForcedIntoAppBoundMode) {
+        completionHandler(isForcedIntoAppBoundMode);
+    });
+}
+
 - (void)_serviceWorkersEnabled:(void(^)(BOOL))completionHandler
 {
     auto enabled = [_configuration preferences]->_preferences.get()->serviceWorkersEnabled() || WebCore::RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled();
index eeb2389..8b8368b 100644 (file)
@@ -342,6 +342,7 @@ for this property.
 - (void)_getProcessDisplayNameWithCompletionHandler:(void (^)(NSString *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)_isNavigatingToAppBoundDomain:(void(^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_isForcedIntoAppBoundMode:(void(^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)_grantAccessToPreferenceService WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
index 9e2484b..4ffe7e3 100644 (file)
@@ -1391,6 +1391,9 @@ RefPtr<API::Navigation> WebPageProxy::loadData(const IPC::DataReference& data, c
 {
     RELEASE_LOG_IF_ALLOWED(Loading, "loadData:");
 
+    if (MIMEType == "text/html"_s && !WEB_PAGE_PROXY_ADDITIONS_SETISNAVIGATINGTOAPPBOUNDDOMAIN)
+        m_limitsNavigationsToAppBoundDomains = true;
+
     if (m_isClosed) {
         RELEASE_LOG_IF_ALLOWED(Loading, "loadData: page is closed");
         return nullptr;
@@ -3111,6 +3114,13 @@ private:
     PolicyCheckIdentifier m_identifier;
 };
 
+#if PLATFORM(IOS_FAMILY)
+static bool shouldTreatURLProtocolAsAppBound(const URL& requestURL)
+{
+    return requestURL.protocolIsAbout() || requestURL.protocolIsData() || requestURL.protocolIsBlob() || requestURL.isLocalFile() || requestURL.protocolIsJavaScript();
+}
+#endif
+
 bool WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL& requestURL, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
 {
 #if PLATFORM(IOS_FAMILY)
@@ -3124,6 +3134,10 @@ bool WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMai
         if (m_ignoresAppBoundDomains)
             return true;
         
+        if (shouldTreatURLProtocolAsAppBound(requestURL)) {
+            isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
+            m_limitsNavigationsToAppBoundDomains = true;
+        }
         if (m_limitsNavigationsToAppBoundDomains) {
             if (*isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::No)
                 return false;
@@ -3149,6 +3163,11 @@ void WebPageProxy::isNavigatingToAppBoundDomainTesting(CompletionHandler<void(bo
     completionHandler(m_isNavigatingToAppBoundDomain && (*m_isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::Yes));
 }
 
+void WebPageProxy::isForcedIntoAppBoundModeTesting(CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_limitsNavigationsToAppBoundDomains);
+}
+
 void WebPageProxy::disableServiceWorkerEntitlementInNetworkProcess()
 {
 #if PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)
index f774ae7..e551ae5 100644 (file)
@@ -1747,6 +1747,8 @@ public:
     void setNeedsDOMWindowResizeEvent();
 
     void isNavigatingToAppBoundDomainTesting(CompletionHandler<void(bool)>&&);
+    void isForcedIntoAppBoundModeTesting(CompletionHandler<void(bool)>&&);
+
     Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain() const { return m_isNavigatingToAppBoundDomain; }
 
     void disableServiceWorkerEntitlementInNetworkProcess();
index 1bd5351..d629a6d 100644 (file)
@@ -459,11 +459,6 @@ void WebsiteDataStore::ensureAppBoundDomains(CompletionHandler<void(const HashSe
     });
 }
 
-static bool shouldTreatURLProtocolAsAppBound(const URL& requestURL)
-{
-    return requestURL.protocolIsAbout() || requestURL.protocolIsData() || requestURL.protocolIsBlob() || requestURL.isLocalFile();
-}
-
 void WebsiteDataStore::beginAppBoundDomainCheck(const URL& requestURL, WebFramePolicyListenerProxy& listener)
 {
     ASSERT(RunLoop::isMain());
@@ -476,10 +471,6 @@ void WebsiteDataStore::beginAppBoundDomainCheck(const URL& requestURL, WebFrameP
             listener->didReceiveAppBoundDomainResult(WTF::nullopt);
             return;
         }
-        if (shouldTreatURLProtocolAsAppBound(requestURL)) {
-            listener->didReceiveAppBoundDomainResult(NavigatingToAppBoundDomain::Yes);
-            return;
-        }
         listener->didReceiveAppBoundDomainResult(domains.contains(WebCore::RegistrableDomain(requestURL)) ? NavigatingToAppBoundDomain::Yes : NavigatingToAppBoundDomain::No);
     });
 }
index 3d32d98..3678657 100644 (file)
@@ -1,3 +1,26 @@
+2020-05-14  Kate Cheney  <katherine_cheney@apple.com>
+
+        Attribute non-network loads and loads with html strings as automatically app-bound
+        https://bugs.webkit.org/show_bug.cgi?id=211913
+        <rdar://problem/63157801
+
+        Reviewed by Brent Fulgham.
+
+        Adds new tests to check that WebView loads with HTML strings have
+        proper behavior.
+
+        Some tests need to test behavior on app-bound domains on webviews which do not specify
+        limitsNavigationsToAppBoundDomains. Since local files now do this
+        automatically, this patch updates those to use actual app-bound
+        domains from the WKAppBoundDomains list instead to maintain behavior.
+
+        Remove limitsNavigationsToAppBoundDomains for local files to make sure
+        they are forced into this mode automatically.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+        (-[InAppBrowserSchemeHandler webView:startURLSchemeTask:]):
+        (TEST):
+
 2020-05-14  Jiewen Tan  <jiewen_tan@apple.com>
 
         [WebAuthn] Relaxing signature length requirements for U2fRegister
index 3dd5030..6ef3218 100644 (file)
@@ -102,6 +102,8 @@ static NSString * const userScriptSource = @"window.wkUserScriptInjected = true"
         response = @"<body style='background-color: red;'><iframe src='in-app-browser:///in-app-browser-privacy-test-user-style-sheets'></iframe></body>";
     else if ([task.request.URL.path isEqualToString:@"/in-app-browser-privacy-test-message-handler"])
         response = @"<body style='background-color: green;'></body><script>if (window.webkit.messageHandlers)\nwindow.webkit.messageHandlers.testHandler.postMessage('Failed'); \nelse \n document.body.style.background = 'red';</script>";
+    else if ([task.request.URL.path isEqualToString:@"/app-bound-domain-load"])
+        response = @"<body></body>";
 
     [task didReceiveResponse:[[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:response.length textEncodingName:nil] autorelease]];
     [task didReceiveData:[response dataUsingEncoding:NSUTF8StringEncoding]];
@@ -272,7 +274,6 @@ TEST(InAppBrowserPrivacy, LocalFilesAreAppBound)
 {
     initializeInAppBrowserPrivacyTestSettings();
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
@@ -280,8 +281,8 @@ TEST(InAppBrowserPrivacy, LocalFilesAreAppBound)
     [webView _test_waitForDidFinishNavigation];
 
     isDone = false;
-    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
-        EXPECT_TRUE(isAppBound);
+    [webView _isForcedIntoAppBoundMode:^(BOOL isForcedIntoAppBoundMode) {
+        EXPECT_TRUE(isForcedIntoAppBoundMode);
         cleanUpInAppBrowserPrivacyTestSettings();
         isDone = true;
     }];
@@ -292,15 +293,14 @@ TEST(InAppBrowserPrivacy, DataFilesAreAppBound)
 {
     initializeInAppBrowserPrivacyTestSettings();
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"data:text/html,start"]]];
     [webView _test_waitForDidFinishNavigation];
 
     isDone = false;
-    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
-        EXPECT_TRUE(isAppBound);
+    [webView _isForcedIntoAppBoundMode:^(BOOL isForcedIntoAppBoundMode) {
+        EXPECT_TRUE(isForcedIntoAppBoundMode);
         cleanUpInAppBrowserPrivacyTestSettings();
         isDone = true;
     }];
@@ -311,15 +311,14 @@ TEST(InAppBrowserPrivacy, AboutFilesAreAppBound)
 {
     initializeInAppBrowserPrivacyTestSettings();
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
     [webView _test_waitForDidFinishNavigation];
 
     isDone = false;
-    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
-        EXPECT_TRUE(isAppBound);
+    [webView _isForcedIntoAppBoundMode:^(BOOL isForcedIntoAppBoundMode) {
+        EXPECT_TRUE(isForcedIntoAppBoundMode);
         cleanUpInAppBrowserPrivacyTestSettings();
         isDone = true;
     }];
@@ -894,7 +893,7 @@ TEST(InAppBrowserPrivacy, NavigateAwayFromAppBoundDomainWithAppBoundFlagFails)
     [webView setNavigationDelegate:delegate.get()];
     
     // Navigate to an app-bound domain and expect a successful load.
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser://apple.com/app-bound-domain-load"]];
     [webView loadRequest:request];
     [delegate waitForDidFinishNavigation];
     
@@ -924,7 +923,7 @@ TEST(InAppBrowserPrivacy, AppBoundDomainWithoutFlagTreatedAsNonAppBound)
     [webView setNavigationDelegate:delegate.get()];
     
     // Navigate to an app-bound domain and expect a successful load.
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser://apple.com/app-bound-domain-load"]];
     [webView loadRequest:request];
     [delegate waitForDidFinishNavigation];
 
@@ -953,7 +952,7 @@ TEST(InAppBrowserPrivacy, WebViewWithoutAppBoundFlagCanFreelyNavigate)
     [webView setNavigationDelegate:delegate.get()];
     
     // Navigate to an app-bound domain and expect a successful load.
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser://apple.com/app-bound-domain-load"]];
     [webView loadRequest:request];
     [delegate waitForDidFinishNavigation];
 
@@ -965,7 +964,7 @@ TEST(InAppBrowserPrivacy, WebViewWithoutAppBoundFlagCanFreelyNavigate)
     TestWebKitAPI::Util::run(&isDone);
 
     // Navigate to an non app-bound domain and expect a successful load.
-    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser://in-app-browser-privacy-test-user-style-sheets"]];
     [webView loadRequest:request];
     [delegate waitForDidFinishNavigation];
     
@@ -1002,7 +1001,7 @@ TEST(InAppBrowserPrivacy, WebViewCannotUpdateAppBoundFlagOnceSet)
     [webView setNavigationDelegate:delegate.get()];
     
     // Navigate to an app-bound domain and expect a successful load.
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser://apple.com/app-bound-domain-load"]];
     [webView loadRequest:request];
     [delegate waitForDidFinishNavigation];
 
@@ -1073,6 +1072,82 @@ TEST(InAppBrowserPrivacy, WebViewCategory)
     cleanUpInAppBrowserPrivacyTestSettings();
 }
 
+TEST(InAppBrowserPrivacy, LoadFromHTMLStringsSucceedsIfAppBound)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+
+    NSString *HTML = @"<html><head></head><body><img src='in-app-browser:///in-app-browser-privacy-test-user-style-sheets/'></img></body></html>";
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    [webView loadHTMLString:HTML baseURL:[NSURL URLWithString:@"in-app-browser://apple.com/"]];
+    [delegate waitForDidFinishNavigation];
+
+    cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, LoadFromHTMLStringNoBaseURLIsAppBound)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+
+    NSString *HTML = @"<html><head></head><body><img src='in-app-browser:///in-app-browser-privacy-test-user-style-sheets/'></img></body></html>";
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    [webView loadHTMLString:HTML baseURL:nil];
+    [delegate waitForDidFinishNavigation];
+
+    isDone = false;
+    [webView _isForcedIntoAppBoundMode:^(BOOL isForcedIntoAppBoundMode) {
+        EXPECT_TRUE(isForcedIntoAppBoundMode);
+        cleanUpInAppBrowserPrivacyTestSettings();
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+}
+
+TEST(InAppBrowserPrivacy, LoadFromHTMLStringsFailsIfNotAppBound)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+
+    NSString *HTML = @"<html><head></head><body><img src='in-app-browser:///in-app-browser-privacy-test-user-style-sheets/'></img></body></html>";
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    [webView loadHTMLString:HTML baseURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-agent-script"]];
+    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
+
+    isDone = false;
+    [webView _isForcedIntoAppBoundMode:^(BOOL isForcedIntoAppBoundMode) {
+        EXPECT_TRUE(isForcedIntoAppBoundMode);
+        cleanUpInAppBrowserPrivacyTestSettings();
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+}
+
 #endif // USE(APPLE_INTERNAL_SDK)
 
 #endif // PLATFORM(IOS_FAMILY)