2 * Copyright (C) 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #import <WebKit/WKFoundation.h>
30 #if PLATFORM(MAC) || PLATFORM(IOS)
32 #import "PlatformUtilities.h"
34 #import "TestProtocol.h"
35 #import "TestWKWebView.h"
36 #import <WebCore/FileSystem.h>
37 #import <WebKit/_WKDownload.h>
38 #import <WebKit/_WKDownloadDelegate.h>
39 #import <WebKit/WKNavigationDelegatePrivate.h>
40 #import <WebKit/WKProcessPoolPrivate.h>
41 #import <WebKit/WKUIDelegatePrivate.h>
42 #import <WebKit/WKWebView.h>
43 #import <WebKit/WKWebViewConfiguration.h>
44 #import <wtf/MainThread.h>
45 #import <wtf/RetainPtr.h>
46 #import <wtf/text/WTFString.h>
49 static unsigned redirectCount = 0;
50 static bool hasReceivedResponse;
51 static NSURL *sourceURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
52 static WKWebView* expectedOriginatingWebView;
53 static bool expectedUserInitiatedState = false;
55 @interface DownloadDelegate : NSObject <_WKDownloadDelegate>
58 @implementation DownloadDelegate {
59 RetainPtr<_WKDownload> _download;
60 String _destinationPath;
61 long long _expectedContentLength;
62 uint64_t _receivedContentLength;
65 - (void)_downloadDidStart:(_WKDownload *)download
67 EXPECT_NULL(_download);
68 EXPECT_NOT_NULL(download);
69 EXPECT_TRUE([[[[download request] URL] path] isEqualToString:[sourceURL path]]);
70 EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
74 - (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
76 hasReceivedResponse = true;
77 EXPECT_EQ(_download, download);
78 EXPECT_TRUE(_expectedContentLength == 0);
79 EXPECT_TRUE(_receivedContentLength == 0);
80 EXPECT_TRUE([[[response URL] path] isEqualToString:[sourceURL path]]);
81 _expectedContentLength = [response expectedContentLength];
84 - (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
86 EXPECT_EQ(_download, download);
87 _receivedContentLength += length;
90 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
91 - (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
94 EXPECT_TRUE(hasReceivedResponse);
95 EXPECT_EQ(_download, download);
97 WebCore::FileSystem::PlatformFileHandle fileHandle;
98 _destinationPath = WebCore::FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
99 EXPECT_TRUE(fileHandle != WebCore::FileSystem::invalidPlatformFileHandle);
100 WebCore::FileSystem::closeFile(fileHandle);
102 *allowOverwrite = YES;
103 return _destinationPath;
106 - (void)_downloadDidFinish:(_WKDownload *)download
108 EXPECT_EQ(_download, download);
109 EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
110 EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
111 EXPECT_TRUE([[NSFileManager defaultManager] contentsEqualAtPath:_destinationPath andPath:[sourceURL path]]);
112 WebCore::FileSystem::deleteFile(_destinationPath);
118 TEST(_WKDownload, DownloadDelegate)
120 RetainPtr<WKProcessPool> processPool = adoptNS([[WKProcessPool alloc] init]);
121 DownloadDelegate *downloadDelegate = [[DownloadDelegate alloc] init];
122 [processPool _setDownloadDelegate:downloadDelegate];
125 EXPECT_EQ(downloadDelegate, [processPool _downloadDelegate]);
128 [downloadDelegate release];
129 EXPECT_NULL([processPool _downloadDelegate]);
132 static void runTest(id <WKNavigationDelegate> navigationDelegate, id <_WKDownloadDelegate> downloadDelegate, NSURL *url)
134 RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
135 [webView setNavigationDelegate:navigationDelegate];
136 [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate];
139 hasReceivedResponse = false;
140 expectedUserInitiatedState = false;
141 [webView loadRequest:[NSURLRequest requestWithURL:url]];
142 TestWebKitAPI::Util::run(&isDone);
145 @interface DownloadNavigationDelegate : NSObject <WKNavigationDelegate>
148 @implementation DownloadNavigationDelegate
149 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
151 decisionHandler(_WKNavigationActionPolicyDownload);
155 TEST(_WKDownload, DownloadRequest)
157 runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[DownloadDelegate alloc] init]).get(), sourceURL);
160 @interface ConvertResponseToDownloadNavigationDelegate : NSObject <WKNavigationDelegate>
163 @implementation ConvertResponseToDownloadNavigationDelegate
164 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
166 decisionHandler(_WKNavigationResponsePolicyBecomeDownload);
170 TEST(_WKDownload, ConvertResponseToDownload)
172 runTest(adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]).get(), adoptNS([[DownloadDelegate alloc] init]).get(), sourceURL);
175 @interface FailingDownloadDelegate : NSObject <_WKDownloadDelegate>
178 @implementation FailingDownloadDelegate
180 - (void)_downloadDidFinish:(_WKDownload *)download
186 - (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
191 - (void)_downloadDidCancel:(_WKDownload *)download
199 TEST(_WKDownload, DownloadMissingResource)
201 runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[FailingDownloadDelegate alloc] init]).get(), [NSURL URLWithString:@"non-existant-scheme://"]);
204 @interface CancelledDownloadDelegate : NSObject <_WKDownloadDelegate>
207 @implementation CancelledDownloadDelegate
209 - (void)_downloadDidStart:(_WKDownload *)download
214 - (void)_downloadDidFinish:(_WKDownload *)download
220 - (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
226 - (void)_downloadDidCancel:(_WKDownload *)download
233 TEST(_WKDownload, CancelDownload)
235 runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[CancelledDownloadDelegate alloc] init]).get(), sourceURL);
238 @interface OriginatingWebViewDownloadDelegate : NSObject <_WKDownloadDelegate>
239 - (instancetype)initWithWebView:(WKWebView *)webView;
242 @implementation OriginatingWebViewDownloadDelegate {
243 RetainPtr<WKWebView> _webView;
246 - (instancetype)initWithWebView:(WKWebView *)webView
248 if (!(self = [super init]))
255 - (void)_downloadDidStart:(_WKDownload *)download
257 EXPECT_EQ([download originatingWebView], _webView);
260 WTF::callOnMainThread([download = retainPtr(download)] {
261 EXPECT_NULL([download originatingWebView]);
268 TEST(_WKDownload, OriginatingWebView)
270 RetainPtr<DownloadNavigationDelegate> navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);
271 RetainPtr<OriginatingWebViewDownloadDelegate> downloadDelegate;
273 RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
274 [webView setNavigationDelegate:navigationDelegate.get()];
275 downloadDelegate = adoptNS([[OriginatingWebViewDownloadDelegate alloc] initWithWebView:webView.get()]);
276 [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
277 [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];
281 TestWebKitAPI::Util::run(&isDone);
284 @interface DownloadRequestOriginalURLDelegate : NSObject <_WKDownloadDelegate>
285 - (instancetype)initWithExpectedOriginalURL:(NSURL *)expectOriginalURL;
288 @implementation DownloadRequestOriginalURLDelegate {
289 NSURL *_expectedOriginalURL;
292 - (instancetype)initWithExpectedOriginalURL:(NSURL *)expectedOriginalURL
294 if (!(self = [super init]))
297 _expectedOriginalURL = expectedOriginalURL;
301 - (void)_downloadDidStart:(_WKDownload *)download
303 if ([_expectedOriginalURL isEqual:sourceURL])
304 EXPECT_TRUE(!download.request.mainDocumentURL);
306 EXPECT_TRUE([_expectedOriginalURL isEqual:download.request.mainDocumentURL]);
312 @interface DownloadRequestOriginalURLNavigationDelegate : NSObject <WKNavigationDelegate>
315 @implementation DownloadRequestOriginalURLNavigationDelegate
316 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
318 if ([navigationAction.request.URL isEqual:sourceURL])
319 decisionHandler(_WKNavigationActionPolicyDownload);
321 decisionHandler(WKNavigationActionPolicyAllow);
325 TEST(_WKDownload, DownloadRequestOriginalURL)
327 NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestOriginalURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
328 runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:originalURL]).get(), originalURL);
331 TEST(_WKDownload, DownloadRequestOriginalURLFrame)
333 NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestOriginalURL2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
334 runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:originalURL]).get(), originalURL);
337 TEST(_WKDownload, DownloadRequestOriginalURLDirectDownload)
339 runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:sourceURL]).get(), sourceURL);
342 TEST(_WKDownload, DownloadRequestOriginalURLDirectDownloadWithLoadedContent)
344 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
345 [webView setNavigationDelegate:[[DownloadRequestOriginalURLNavigationDelegate alloc] init]];
346 [[[webView configuration] processPool] _setDownloadDelegate:[[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:sourceURL]];
348 expectedUserInitiatedState = false;
349 NSURL *contentURL = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
350 // Here is to test if the original URL can be set correctly when the current document
351 // is completely unrelated to the download.
352 [webView loadRequest:[NSURLRequest requestWithURL:contentURL]];
353 [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];
355 TestWebKitAPI::Util::run(&isDone);
358 @interface BlobDownloadDelegate : NSObject <_WKDownloadDelegate>
361 @implementation BlobDownloadDelegate {
362 RetainPtr<_WKDownload> _download;
363 String _destinationPath;
364 long long _expectedContentLength;
365 uint64_t _receivedContentLength;
368 - (void)_downloadDidStart:(_WKDownload *)download
370 EXPECT_NULL(_download);
371 EXPECT_NOT_NULL(download);
372 EXPECT_TRUE([[[[download request] URL] scheme] isEqualToString:@"blob"]);
373 EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
374 _download = download;
377 - (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
379 hasReceivedResponse = true;
380 EXPECT_EQ(_download, download);
381 EXPECT_EQ(_expectedContentLength, 0U);
382 EXPECT_EQ(_receivedContentLength, 0U);
383 EXPECT_TRUE([[[response URL] scheme] isEqualToString:@"blob"]);
384 _expectedContentLength = [response expectedContentLength];
387 - (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
389 EXPECT_EQ(_download, download);
390 _receivedContentLength += length;
393 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
394 - (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
397 EXPECT_TRUE(hasReceivedResponse);
398 EXPECT_EQ(_download, download);
400 WebCore::FileSystem::PlatformFileHandle fileHandle;
401 _destinationPath = WebCore::FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
402 EXPECT_TRUE(fileHandle != WebCore::FileSystem::invalidPlatformFileHandle);
403 WebCore::FileSystem::closeFile(fileHandle);
405 *allowOverwrite = YES;
406 return _destinationPath;
409 - (void)_downloadDidFinish:(_WKDownload *)download
411 EXPECT_EQ(_download, download);
412 EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
413 EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
414 NSString* expectedContent = @"{\"x\":42,\"s\":\"hello, world\"}";
415 NSData* expectedData = [expectedContent dataUsingEncoding:NSUTF8StringEncoding];
416 EXPECT_TRUE([[[NSFileManager defaultManager] contentsAtPath:_destinationPath] isEqualToData:expectedData]);
417 WebCore::FileSystem::deleteFile(_destinationPath);
423 @interface DownloadBlobURLNavigationDelegate : NSObject <WKNavigationDelegate>
426 @implementation DownloadBlobURLNavigationDelegate
427 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
429 if ([navigationAction.request.URL.scheme isEqualToString:@"blob"])
430 decisionHandler(_WKNavigationActionPolicyDownload);
432 decisionHandler(WKNavigationActionPolicyAllow);
436 TEST(_WKDownload, DownloadRequestBlobURL)
438 NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestBlobURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
439 runTest(adoptNS([[DownloadBlobURLNavigationDelegate alloc] init]).get(), adoptNS([[BlobDownloadDelegate alloc] init]).get(), originalURL);
442 @interface RedirectedDownloadDelegate : NSObject <_WKDownloadDelegate>
445 @implementation RedirectedDownloadDelegate {
446 String _destinationPath;
449 - (void)_downloadDidStart:(_WKDownload *)download
451 EXPECT_NOT_NULL(download);
452 EXPECT_EQ(expectedOriginatingWebView, download.originatingWebView);
453 EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
456 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
457 - (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
460 WebCore::FileSystem::PlatformFileHandle fileHandle;
461 _destinationPath = WebCore::FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
462 EXPECT_TRUE(fileHandle != WebCore::FileSystem::invalidPlatformFileHandle);
463 WebCore::FileSystem::closeFile(fileHandle);
464 *allowOverwrite = YES;
465 return _destinationPath;
468 - (void)_download:(_WKDownload *)download didReceiveServerRedirectToURL:(NSURL *)url
471 EXPECT_STREQ("http://redirect/?pass", [url.absoluteString UTF8String]);
473 EXPECT_STREQ("http://pass/", [url.absoluteString UTF8String]);
474 ++redirectCount = true;
477 - (void)_downloadDidFinish:(_WKDownload *)download
479 EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
481 NSArray<NSURL *> *redirectChain = download.redirectChain;
482 EXPECT_EQ(3U, redirectChain.count);
483 if (redirectChain.count > 0)
484 EXPECT_STREQ("http://redirect/?redirect/?pass", [redirectChain[0].absoluteString UTF8String]);
485 if (redirectChain.count > 1)
486 EXPECT_STREQ("http://redirect/?pass", [redirectChain[1].absoluteString UTF8String]);
487 if (redirectChain.count > 2)
488 EXPECT_STREQ("http://pass/", [redirectChain[2].absoluteString UTF8String]);
490 WebCore::FileSystem::deleteFile(_destinationPath);
496 TEST(_WKDownload, RedirectedDownload)
498 [TestProtocol registerWithScheme:@"http"];
503 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
504 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
505 auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
506 [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
508 // Do 2 loads in the same view to make sure the redirect chain is properly cleared between loads.
509 [webView synchronouslyLoadHTMLString:@"<div>First load</div>"];
510 [webView synchronouslyLoadHTMLString:@"<a id='link' href='http://redirect/?redirect/?pass'>test</a>"];
512 expectedOriginatingWebView = webView.get();
513 expectedUserInitiatedState = true;
515 auto navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);
516 [webView setNavigationDelegate:navigationDelegate.get()];
517 [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.getElementById('link').click();"];
520 TestWebKitAPI::Util::run(&isDone);
521 EXPECT_EQ(1U, redirectCount);
523 [TestProtocol unregister];
526 TEST(_WKDownload, RedirectedLoadConvertedToDownload)
528 [TestProtocol registerWithScheme:@"http"];
530 auto navigationDelegate = adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]);
531 auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
533 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
534 [webView setNavigationDelegate:navigationDelegate.get()];
535 [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
537 expectedOriginatingWebView = webView.get();
538 expectedUserInitiatedState = false;
541 hasReceivedResponse = false;
542 [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect/?redirect/?pass"]]];
543 TestWebKitAPI::Util::run(&isDone);
544 EXPECT_EQ(0U, redirectCount);
546 [TestProtocol unregister];
549 TEST(_WKDownload, RedirectedSubframeLoadConvertedToDownload)
551 [TestProtocol registerWithScheme:@"http"];
553 auto navigationDelegate = adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]);
554 auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
556 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
557 [webView setNavigationDelegate:navigationDelegate.get()];
558 [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
560 expectedOriginatingWebView = webView.get();
561 expectedUserInitiatedState = false;
564 hasReceivedResponse = false;
565 [webView loadHTMLString:@"<body><iframe src='http://redirect/?redirect/?pass'></iframe></body>" baseURL:nil];
566 TestWebKitAPI::Util::run(&isDone);
567 EXPECT_EQ(0U, redirectCount);
569 [TestProtocol unregister];
572 static bool downloadHasDecidedDestination;
574 @interface CancelDownloadWhileDecidingDestinationDelegate : NSObject <_WKDownloadDelegate>
577 @implementation CancelDownloadWhileDecidingDestinationDelegate
578 - (void)_downloadDidFinish:(_WKDownload *)download
584 - (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
590 - (void)_downloadDidCancel:(_WKDownload *)download
595 - (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler
598 TestWebKitAPI::Util::run(&isDone);
599 completionHandler(YES, @"/tmp/WebKitAPITest/_WKDownload");
600 downloadHasDecidedDestination = true;
604 TEST(_WKDownload, DownloadCanceledWhileDecidingDestination)
606 [TestProtocol registerWithScheme:@"http"];
608 auto navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);
609 auto downloadDelegate = adoptNS([[CancelDownloadWhileDecidingDestinationDelegate alloc] init]);
611 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
612 [webView setNavigationDelegate:navigationDelegate.get()];
613 [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
616 downloadHasDecidedDestination = false;
617 [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://pass"]]];
619 TestWebKitAPI::Util::run(&downloadHasDecidedDestination);
621 [TestProtocol unregister];