8b15e31f47d9da70817e3679e1e05869f9d483dd
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / DecidePolicyForNavigationAction.mm
1 /*
2  * Copyright (C) 2014-2017 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 #include "config.h"
27
28 #if PLATFORM(MAC)
29
30 #import "PlatformUtilities.h"
31 #import "TestProtocol.h"
32 #import <WebKit/WKNavigationActionPrivate.h>
33 #import <wtf/RetainPtr.h>
34 #import <wtf/mac/AppKitCompatibilityDeclarations.h>
35
36 #if WK_API_ENABLED
37
38 static bool createdWebView;
39 static bool decidedPolicy;
40 static bool finishedNavigation;
41 static RetainPtr<WKNavigationAction> action;
42 static RetainPtr<WKWebView> newWebView;
43
44 static NSString *firstURL = @"data:text/html,First";
45 static NSString *secondURL = @"data:text/html,Second";
46
47 @interface DecidePolicyForNavigationActionController : NSObject <WKNavigationDelegate, WKUIDelegate>
48 @end
49
50 @implementation DecidePolicyForNavigationActionController
51
52 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
53 {
54     decisionHandler(webView == newWebView.get() ? WKNavigationActionPolicyCancel : WKNavigationActionPolicyAllow);
55
56     action = navigationAction;
57     decidedPolicy = true;
58 }
59
60 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
61 {
62     finishedNavigation = true;
63 }
64
65 - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
66 {
67     action = navigationAction;
68     newWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
69
70     createdWebView = true;
71     return newWebView.get();
72 }
73
74 @end
75
76 TEST(WebKit, DecidePolicyForNavigationActionReload)
77 {
78     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
79
80     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
81     [[window contentView] addSubview:webView.get()];
82
83     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
84     [webView setNavigationDelegate:controller.get()];
85     [webView setUIDelegate:controller.get()];
86
87     finishedNavigation = false;
88     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
89     TestWebKitAPI::Util::run(&finishedNavigation);
90
91     decidedPolicy = false;
92     [webView reload];
93     TestWebKitAPI::Util::run(&decidedPolicy);
94
95     EXPECT_EQ(WKNavigationTypeReload, [action navigationType]);
96     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
97     EXPECT_EQ(nil, [action sourceFrame]);
98     EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
99     EXPECT_WK_STREQ(firstURL, [[[[action targetFrame] request] URL] absoluteString]);
100     EXPECT_EQ(webView.get(), [[action targetFrame] webView]);
101
102     newWebView = nullptr;
103     action = nullptr;
104 }
105
106 TEST(WebKit, DecidePolicyForNavigationActionReloadFromOrigin)
107 {
108     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
109
110     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
111     [[window contentView] addSubview:webView.get()];
112
113     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
114     [webView setNavigationDelegate:controller.get()];
115     [webView setUIDelegate:controller.get()];
116
117     finishedNavigation = false;
118     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
119     TestWebKitAPI::Util::run(&finishedNavigation);
120
121     decidedPolicy = false;
122     [webView reloadFromOrigin];
123     TestWebKitAPI::Util::run(&decidedPolicy);
124
125     EXPECT_EQ(WKNavigationTypeReload, [action navigationType]);
126     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
127     EXPECT_EQ(nil, [action sourceFrame]);
128     EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
129     EXPECT_WK_STREQ(firstURL, [[[[action targetFrame] request] URL] absoluteString]);
130     EXPECT_EQ(webView.get(), [[action targetFrame] webView]);
131
132     newWebView = nullptr;
133     action = nullptr;
134 }
135
136 TEST(WebKit, DecidePolicyForNavigationActionGoBack)
137 {
138     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
139
140     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
141     [[window contentView] addSubview:webView.get()];
142
143     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
144     [webView setNavigationDelegate:controller.get()];
145     [webView setUIDelegate:controller.get()];
146
147     finishedNavigation = false;
148     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
149     TestWebKitAPI::Util::run(&finishedNavigation);
150
151     finishedNavigation = false;
152     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]];
153     TestWebKitAPI::Util::run(&finishedNavigation);
154
155     decidedPolicy = false;
156     [webView goBack];
157     TestWebKitAPI::Util::run(&decidedPolicy);
158
159     EXPECT_EQ(WKNavigationTypeBackForward, [action navigationType]);
160     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
161     EXPECT_EQ(nil, [action sourceFrame]);
162     EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
163     EXPECT_WK_STREQ(secondURL, [[[[action targetFrame] request] URL] absoluteString]);
164     EXPECT_EQ(webView.get(), [[action targetFrame] webView]);
165
166     newWebView = nullptr;
167     action = nullptr;
168 }
169
170 TEST(WebKit, DecidePolicyForNavigationActionGoForward)
171 {
172     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
173
174     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
175     [[window contentView] addSubview:webView.get()];
176
177     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
178     [webView setNavigationDelegate:controller.get()];
179     [webView setUIDelegate:controller.get()];
180
181     finishedNavigation = false;
182     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
183     TestWebKitAPI::Util::run(&finishedNavigation);
184
185     finishedNavigation = false;
186     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]];
187     TestWebKitAPI::Util::run(&finishedNavigation);
188
189     finishedNavigation = false;
190     [webView goBack];
191     TestWebKitAPI::Util::run(&finishedNavigation);
192
193     decidedPolicy = false;
194     [webView goForward];
195     TestWebKitAPI::Util::run(&decidedPolicy);
196
197     EXPECT_EQ(WKNavigationTypeBackForward, [action navigationType]);
198     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
199     EXPECT_EQ(nil, [action sourceFrame]);
200     EXPECT_WK_STREQ(secondURL, [[[action request] URL] absoluteString]);
201     EXPECT_WK_STREQ(firstURL, [[[[action targetFrame] request] URL] absoluteString]);
202     EXPECT_EQ(webView.get(), [[action targetFrame] webView]);
203
204     newWebView = nullptr;
205     action = nullptr;
206 }
207
208 TEST(WebKit, DecidePolicyForNavigationActionOpenNewWindowAndDeallocSourceWebView)
209 {
210     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
211
212     @autoreleasepool {
213         auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
214
215         auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
216         [[window contentView] addSubview:webView.get()];
217
218         [webView setNavigationDelegate:controller.get()];
219         [webView setUIDelegate:controller.get()];
220
221         createdWebView = false;
222         [webView loadHTMLString:@"<script>window.open('http://webkit.org/destination.html')</script>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
223         TestWebKitAPI::Util::run(&createdWebView);
224     }
225
226     decidedPolicy = false;
227     [newWebView setNavigationDelegate:controller.get()];
228     TestWebKitAPI::Util::run(&decidedPolicy);
229
230     EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
231     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
232     EXPECT_EQ(nil, [[action sourceFrame] webView]);
233     EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
234
235     newWebView = nullptr;
236     action = nullptr;
237 }
238
239 TEST(WebKit, DecidePolicyForNavigationActionForTargetedHyperlink)
240 {
241     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
242
243     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
244     [[window contentView] addSubview:webView.get()];
245
246     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
247     [webView setNavigationDelegate:controller.get()];
248     [webView setUIDelegate:controller.get()];
249
250     finishedNavigation = false;
251     [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"https://webkit.org/destination2.html\" target=\"B\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
252     TestWebKitAPI::Util::run(&finishedNavigation);
253
254     createdWebView = false;
255     [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination1.html\", \"B\")" completionHandler:nil];
256     TestWebKitAPI::Util::run(&createdWebView);
257
258     EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
259     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
260     EXPECT_EQ(nil, [action targetFrame]);
261     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
262     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
263     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
264
265     // Wait for newWebView to ask to load its initial document.
266     decidedPolicy = false;
267     [newWebView setNavigationDelegate:controller.get()];
268     TestWebKitAPI::Util::run(&decidedPolicy);
269
270     decidedPolicy = false;
271     [newWebView setNavigationDelegate:controller.get()];
272     NSPoint clickPoint = NSMakePoint(100, 100);
273     [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
274     [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
275     TestWebKitAPI::Util::run(&decidedPolicy);
276
277     EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
278     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
279     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
280     EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
281     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
282     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
283
284     newWebView = nullptr;
285     action = nullptr;
286 }
287
288 TEST(WebKit, DecidePolicyForNavigationActionForTargetedWindowOpen)
289 {
290     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
291
292     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
293     [[window contentView] addSubview:webView.get()];
294
295     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
296     [webView setNavigationDelegate:controller.get()];
297     [webView setUIDelegate:controller.get()];
298
299     finishedNavigation = false;
300     [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"javascript:window.open('https://webkit.org/destination2.html', 'B')\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
301     TestWebKitAPI::Util::run(&finishedNavigation);
302
303     createdWebView = false;
304     [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination1.html\", \"B\")" completionHandler:nil];
305     TestWebKitAPI::Util::run(&createdWebView);
306
307     EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
308     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
309     EXPECT_EQ(nil, [action targetFrame]);
310     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
311     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
312     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
313
314     // Wait for newWebView to ask to load its initial document.
315     decidedPolicy = false;
316     [newWebView setNavigationDelegate:controller.get()];
317     TestWebKitAPI::Util::run(&decidedPolicy);
318
319     decidedPolicy = false;
320     [newWebView setNavigationDelegate:controller.get()];
321     NSPoint clickPoint = NSMakePoint(100, 100);
322     [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
323     [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
324     TestWebKitAPI::Util::run(&decidedPolicy);
325
326     EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
327     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
328     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
329     EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
330     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
331     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
332
333     newWebView = nullptr;
334     action = nullptr;
335 }
336
337 TEST(WebKit, DecidePolicyForNavigationActionForTargetedFormSubmission)
338 {
339     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
340
341     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
342     [[window contentView] addSubview:webView.get()];
343
344     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
345     [webView setNavigationDelegate:controller.get()];
346     [webView setUIDelegate:controller.get()];
347
348     finishedNavigation = false;
349     [webView loadHTMLString:@"<form action=\"https://webkit.org/destination1.html\" target=\"B\"><input type=\"submit\" name=\"submit\" value=\"Submit\" style=\"-webkit-appearance: none; height: 100%; width: 100%\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
350     TestWebKitAPI::Util::run(&finishedNavigation);
351
352     createdWebView = false;
353     [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination2.html\", \"B\")" completionHandler:nil];
354     TestWebKitAPI::Util::run(&createdWebView);
355
356     EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
357     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
358     EXPECT_EQ(nil, [action targetFrame]);
359     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
360     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
361     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
362
363     // Wait for newWebView to ask to load its initial document.
364     decidedPolicy = false;
365     [newWebView setNavigationDelegate:controller.get()];
366     TestWebKitAPI::Util::run(&decidedPolicy);
367
368     decidedPolicy = false;
369     NSPoint clickPoint = NSMakePoint(100, 100);
370     [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
371     [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
372     TestWebKitAPI::Util::run(&decidedPolicy);
373
374     EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
375     EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
376     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
377     EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
378     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
379     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
380
381     newWebView = nullptr;
382     action = nullptr;
383 }
384
385 TEST(WebKit, DecidePolicyForNavigationActionForHyperlinkThatRedirects)
386 {
387     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
388
389     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
390     [[window contentView] addSubview:webView.get()];
391
392     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
393     [webView setNavigationDelegate:controller.get()];
394     [webView setUIDelegate:controller.get()];
395
396     [TestProtocol registerWithScheme:@"http"];
397     finishedNavigation = false;
398     [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"http://redirect/?result\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
399     TestWebKitAPI::Util::run(&finishedNavigation);
400
401     decidedPolicy = false;
402     [newWebView setNavigationDelegate:controller.get()];
403     NSPoint clickPoint = NSMakePoint(100, 100);
404     [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
405     [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
406     TestWebKitAPI::Util::run(&decidedPolicy);
407
408     EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
409     EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
410     EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
411     EXPECT_WK_STREQ("http://redirect/?result", [[[action request] URL] absoluteString]);
412     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
413     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
414     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
415     EXPECT_FALSE([action _isRedirect]);
416
417     // Wait to decide policy for redirect.
418     decidedPolicy = false;
419     TestWebKitAPI::Util::run(&decidedPolicy);
420
421     EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
422     EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
423     EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
424     EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
425     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
426     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
427     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
428     EXPECT_TRUE([action _isRedirect]);
429
430     [TestProtocol unregister];
431     newWebView = nullptr;
432     action = nullptr;
433 }
434
435 TEST(WebKit, DecidePolicyForNavigationActionForPOSTFormSubmissionThatRedirectsToGET)
436 {
437     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
438
439     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
440     [[window contentView] addSubview:webView.get()];
441
442     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
443     [webView setNavigationDelegate:controller.get()];
444     [webView setUIDelegate:controller.get()];
445
446     finishedNavigation = false;
447     [webView loadHTMLString:@"<form action=\"http://redirect/?result\" method=\"POST\"><input type=\"submit\" name=\"submitButton\" value=\"Submit\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
448     TestWebKitAPI::Util::run(&finishedNavigation);
449
450     [TestProtocol registerWithScheme:@"http"];
451     decidedPolicy = false;
452     [webView evaluateJavaScript:@"document.forms[0].submit()" completionHandler:nil];
453     TestWebKitAPI::Util::run(&decidedPolicy);
454
455     EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
456     EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
457     EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
458     EXPECT_WK_STREQ("http://redirect/?result", [[[action request] URL] absoluteString]);
459     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
460     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
461     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
462     EXPECT_FALSE([action _isRedirect]);
463
464     // Wait to decide policy for redirect.
465     decidedPolicy = false;
466     TestWebKitAPI::Util::run(&decidedPolicy);
467
468     EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
469     EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
470     EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
471     EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
472     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
473     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
474     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
475     EXPECT_TRUE([action _isRedirect]);
476
477     [TestProtocol unregister];
478     newWebView = nullptr;
479     action = nullptr;
480 }
481
482 TEST(WebKit, DecidePolicyForNavigationActionForPOSTFormSubmissionThatRedirectsToPOST)
483 {
484     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
485
486     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
487     [[window contentView] addSubview:webView.get()];
488
489     auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
490     [webView setNavigationDelegate:controller.get()];
491     [webView setUIDelegate:controller.get()];
492
493     finishedNavigation = false;
494     [webView loadHTMLString:@"<form action=\"http://307-redirect/?result\" method=\"POST\"><input type=\"submit\" name=\"submitButton\" value=\"Submit\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
495     TestWebKitAPI::Util::run(&finishedNavigation);
496
497     [TestProtocol registerWithScheme:@"http"];
498     decidedPolicy = false;
499     [webView evaluateJavaScript:@"document.forms[0].submit()" completionHandler:nil];
500     TestWebKitAPI::Util::run(&decidedPolicy);
501
502     EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
503     EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
504     EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
505     EXPECT_WK_STREQ("http://307-redirect/?result", [[[action request] URL] absoluteString]);
506     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
507     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
508     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
509     EXPECT_FALSE([action _isRedirect]);
510
511     // Wait to decide policy for redirect.
512     decidedPolicy = false;
513     TestWebKitAPI::Util::run(&decidedPolicy);
514
515     EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
516     EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
517     EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
518     EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
519     EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
520     EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
521     EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
522     EXPECT_TRUE([action _isRedirect]);
523
524     [TestProtocol unregister];
525     newWebView = nullptr;
526     action = nullptr;
527 }
528
529 static size_t calls;
530 static bool done;
531
532 @interface DecidePolicyForNavigationActionFragmentDelegate : NSObject <WKNavigationDelegate>
533 @end
534
535 @implementation DecidePolicyForNavigationActionFragmentDelegate
536
537 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
538 {
539     decisionHandler(WKNavigationActionPolicyAllow);
540     const char* url = navigationAction.request.URL.absoluteString.UTF8String;
541     switch (calls++) {
542     case 0:
543         EXPECT_STREQ(url, "http://webkit.org/");
544         return;
545     case 1:
546         EXPECT_STREQ(url, "http://webkit.org/#fragment");
547         done = true;
548         return;
549     }
550     ASSERT_NOT_REACHED();
551 }
552
553 @end
554
555 TEST(WebKit, DecidePolicyForNavigationActionFragment)
556 {
557     auto webView = adoptNS([[WKWebView alloc] init]);
558     auto delegate = adoptNS([[DecidePolicyForNavigationActionFragmentDelegate alloc] init]);
559     [webView setNavigationDelegate:delegate.get()];
560     [webView loadHTMLString:@"<script>window.location.href='#fragment';</script>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
561     TestWebKitAPI::Util::run(&done);
562 }
563
564 #endif
565
566 #endif