Process Swap on Navigation causes many webpages to hang due to attempted process...
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / DuplicateCompletionHandlerCalls.mm
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import <WebKit/WebKit.h>
28
29 #if WK_API_ENABLED
30
31 #import "PlatformUtilities.h"
32 #import "Utilities.h"
33 #import <WebKit/WKUIDelegatePrivate.h>
34 #import <WebKit/WKWebViewPrivate.h>
35 #import <WebKit/_WKInputDelegate.h>
36 #import <wtf/RetainPtr.h>
37
38 using namespace TestWebKitAPI;
39
40 static bool testFinished;
41
42 @interface DuplicateCompletionHandlerCallsDelegate : NSObject <WKNavigationDelegate, WKUIDelegate, _WKInputDelegate>
43 @end
44
45 @implementation DuplicateCompletionHandlerCallsDelegate
46
47 static void expectException(void (^completionHandler)())
48 {
49     bool exceptionThrown = false;
50     @try {
51         completionHandler();
52     } @catch (NSException *exception) {
53         EXPECT_WK_STREQ(NSInternalInconsistencyException, exception.name);
54         exceptionThrown = true;
55     }
56     EXPECT_TRUE(exceptionThrown);
57 }
58
59 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
60 {
61     decisionHandler(WKNavigationActionPolicyAllow);
62
63     expectException(^ {
64         decisionHandler(WKNavigationActionPolicyAllow);
65     });
66 }
67
68 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
69 {
70     decisionHandler(WKNavigationResponsePolicyAllow);
71
72     expectException(^ {
73         decisionHandler(WKNavigationResponsePolicyAllow);
74     });
75 }
76
77 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
78 {
79     completionHandler();
80
81     expectException(^ {
82         completionHandler();
83     });
84 }
85
86 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
87 {
88     completionHandler(YES);
89
90     expectException(^ {
91         completionHandler(YES);
92     });
93 }
94
95 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
96 {
97     completionHandler(nil);
98
99     expectException(^ {
100         completionHandler(nil);
101     });
102 }
103
104 - (void)_webView:(WKWebView *)webView decideDatabaseQuotaForSecurityOrigin:(WKSecurityOrigin *)securityOrigin currentQuota:(unsigned long long)currentQuota currentOriginUsage:(unsigned long long)currentOriginUsage currentDatabaseUsage:(unsigned long long)currentUsage expectedUsage:(unsigned long long)expectedUsage decisionHandler:(void (^)(unsigned long long newQuota))decisionHandler
105 {
106     decisionHandler(expectedUsage);
107
108     expectException(^ {
109         decisionHandler(expectedUsage);
110     });
111 }
112
113 - (void)_webView:(WKWebView *)webView willSubmitFormValues:(NSDictionary *)values userObject:(NSObject<NSSecureCoding> *)userObject submissionHandler:(void (^)())submissionHandler
114 {
115     submissionHandler();
116
117     expectException(^ {
118         submissionHandler();
119     });
120
121     testFinished = true;
122 }
123
124 @end
125
126 TEST(WebKit, DuplicateCompletionHandlerCalls)
127 {
128     auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]);
129     auto delegate = adoptNS([[DuplicateCompletionHandlerCallsDelegate alloc] init]);
130     [webView setNavigationDelegate:delegate.get()];
131     [webView setUIDelegate:delegate.get()];
132     [webView _setInputDelegate:delegate.get()];
133     [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"duplicate-completion-handler-calls" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
134
135     Util::run(&testFinished);
136 }
137
138 #endif // WK_API_ENABLED