Confirm <a download> satisfies specification criteria
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 1 Apr 2016 21:10:41 +0000 (21:10 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 1 Apr 2016 21:10:41 +0000 (21:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156057

Reviewed by Andy Estes.

Source/WebKit2:

* WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.cpp:
(WKBundleNavigationActionGetHasDownloadAttribute): Added.
* WebProcess/InjectedBundle/API/c/WKBundleNavigationActionPrivate.h:
* WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp:
(WebKit::InjectedBundleNavigationAction::InjectedBundleNavigationAction):
* WebProcess/InjectedBundle/InjectedBundleNavigationAction.h:
(WebKit::InjectedBundleNavigationAction::hasDownloadAttribute): Added.

Tools:

Revise WebKitTestRunner:
(1) Provide a download client delegate.
(2) Teach WKTR to wait to finish a test until a download finishes.
(3) Allow WKTR to notify the current TestRunner that it can finish.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessageToPage): Update to recognize a new
message "NotifyDownloadDone".
* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::InjectedBundlePage::decidePolicyForNavigationAction): Handle 'download'
attribute case.
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::waitUntilDownload): Added.
* WebKitTestRunner/InjectedBundle/TestRunner.h:
(WTR::TestRunner::shouldFinishAfterDownload): Added.
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::createWebViewWithOptions): Set up the download client.
(WTR::TestController::downloadDidStart): Added.
(WTR::TestController::decideDestinationWithSuggestedFilename): Added.
(WTR::TestController::downloadDidFinish): Added.
(WTR::TestController::downloadDidFail): Added.
(WTR::TestController::downloadDidCancel): Added.
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::notifyDownloadDone): Added.
* WebKitTestRunner/TestInvocation.h:

LayoutTests:

Import <a download> tests from the Blink project.

Based on a Blink change (patch by <asanka@chromium.org>):
<https://src.chromium.org/viewvc/blink?revision=172767&view=revision>

* TestExpectations: Mark two expected failures with the new tests.
* fast/dom/HTMLAnchorElement/anchor-download-expected.txt: Updated for
expected output (blob URL currently not working).
* fast/dom/HTMLAnchorElement/anchor-nodownload-set-expected.txt: Ditto.
* http/tests/security/anchor-download-allow-blob-expected.txt: Added.
* http/tests/security/anchor-download-allow-blob.html: Added.
* http/tests/security/anchor-download-allow-data-expected.txt: Added.
* http/tests/security/anchor-download-allow-data.html: Added.
* http/tests/security/anchor-download-allow-sameorigin-expected.txt: Added.
* http/tests/security/anchor-download-allow-sameorigin.html: Added.
* http/tests/security/anchor-download-block-crossorigin-expected.txt: Added.
* http/tests/security/anchor-download-block-crossorigin.html: Added.
* http/tests/security/resources/attachment.php: Added.
* platform/ios-simulator-wk1/TestExpectations: Disable download tests until WK1 support
is implemented.
* platform/ios-simulator-wk2/TestExpectations: Disable download tests until
NETWORK_SESSION support exists.
* platform/mac/TestExpectations: Reactivate the HTMLAnchorElement tests.
* platform/mac-wk1/TestExpectations: Disable download tests until WK1 support
is implemented.

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

32 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/dom/HTMLAnchorElement/anchor-download-expected.txt
LayoutTests/fast/dom/HTMLAnchorElement/anchor-nodownload-set-expected.txt
LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-allow-blob.html [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-allow-data.html [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-allow-sameorigin.html [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/anchor-download-block-crossorigin.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/attachment.php [new file with mode: 0644]
LayoutTests/platform/ios-simulator-wk1/TestExpectations
LayoutTests/platform/ios-simulator-wk2/TestExpectations
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.cpp
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationActionPrivate.h
Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp
Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.h
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestController.h
Tools/WebKitTestRunner/TestInvocation.cpp
Tools/WebKitTestRunner/TestInvocation.h

index fec4c61..c1f4388 100644 (file)
@@ -1,3 +1,36 @@
+2016-04-01  Brent Fulgham  <bfulgham@apple.com>
+
+        Confirm <a download> satisfies specification criteria
+        https://bugs.webkit.org/show_bug.cgi?id=156057
+
+        Reviewed by Andy Estes.
+
+        Import <a download> tests from the Blink project.
+
+        Based on a Blink change (patch by <asanka@chromium.org>):
+        <https://src.chromium.org/viewvc/blink?revision=172767&view=revision>
+
+        * TestExpectations: Mark two expected failures with the new tests.
+        * fast/dom/HTMLAnchorElement/anchor-download-expected.txt: Updated for
+        expected output (blob URL currently not working).
+        * fast/dom/HTMLAnchorElement/anchor-nodownload-set-expected.txt: Ditto.
+        * http/tests/security/anchor-download-allow-blob-expected.txt: Added.
+        * http/tests/security/anchor-download-allow-blob.html: Added.
+        * http/tests/security/anchor-download-allow-data-expected.txt: Added.
+        * http/tests/security/anchor-download-allow-data.html: Added.
+        * http/tests/security/anchor-download-allow-sameorigin-expected.txt: Added.
+        * http/tests/security/anchor-download-allow-sameorigin.html: Added.
+        * http/tests/security/anchor-download-block-crossorigin-expected.txt: Added.
+        * http/tests/security/anchor-download-block-crossorigin.html: Added.
+        * http/tests/security/resources/attachment.php: Added.
+        * platform/ios-simulator-wk1/TestExpectations: Disable download tests until WK1 support
+        is implemented.
+        * platform/ios-simulator-wk2/TestExpectations: Disable download tests until
+        NETWORK_SESSION support exists.
+        * platform/mac/TestExpectations: Reactivate the HTMLAnchorElement tests.
+        * platform/mac-wk1/TestExpectations: Disable download tests until WK1 support
+        is implemented.
+
 2016-04-01  Ryan Haddad  <ryanhaddad@apple.com>
 
         Rebaseline tests added with r198951
index c34c093..864938f 100644 (file)
@@ -1023,3 +1023,9 @@ fast/scrolling/rtl-scrollbars-listbox-select-left.html [ ImageOnlyFailure ]
 fast/scrolling/rtl-scrollbars-listbox-select-right.html [ ImageOnlyFailure ]
 fast/scrolling/rtl-scrollbars-listbox-simple.html [ ImageOnlyFailure ]
 fast/scrolling/rtl-scrollbars-listbox.html [ ImageOnlyFailure ]
+
+# <a download> does not support Blobs
+webkit.org/b/156099 http/tests/security/anchor-download-allow-blob.html [ Failure ]
+
+# <a download> does not honor cross-origin restrictions
+webkit.org/b/156100 http/tests/security/anchor-download-block-crossorigin.html [ Failure ]
\ No newline at end of file
diff --git a/LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt b/LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt
new file mode 100644 (file)
index 0000000..7f241e4
--- /dev/null
@@ -0,0 +1,4 @@
+Downloading URL with suggested filename "foo.pdf"
+Tests that a suggested filename on a download attribute is allowed if the link is a blob URL.
+
+The suggested filename at the top should be foo.pdf.
diff --git a/LayoutTests/http/tests/security/anchor-download-allow-blob.html b/LayoutTests/http/tests/security/anchor-download-allow-blob.html
new file mode 100644 (file)
index 0000000..c147ce9
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+    if (window.testRunner)
+        testRunner.waitUntilDownloadFinished();
+</script>
+</head>
+<body>
+<p>
+Tests that a suggested filename on a download attribute is allowed if
+<a id="dl" download="foo.pdf">the link</a> is a blob URL.
+<p>The suggested filename at the top should be foo.pdf.</p>
+<div id="console"></div>    
+<script>
+    function click(elmt)
+    {
+        if (!window.eventSender)
+            return;
+
+        eventSender.mouseMoveTo(elmt.offsetLeft + 5, elmt.offsetTop + 5);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+
+    function runTest()
+    {
+        var blob = new Blob(["Hello world!"], {type: "application/octet-stream"});
+        var link = document.getElementById("dl");
+        link.href = window.URL.createObjectURL(blob);
+        click(link);
+    }
+    runTest();
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt b/LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt
new file mode 100644 (file)
index 0000000..955a7f7
--- /dev/null
@@ -0,0 +1,9 @@
+Download started.
+Downloading URL with suggested filename "foo.pdf"
+Download completed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Tests that a suggested filename on a download attribute is allowed if the link is a data URL.
+
+The suggested filename at the top should be foo.pdf.
diff --git a/LayoutTests/http/tests/security/anchor-download-allow-data.html b/LayoutTests/http/tests/security/anchor-download-allow-data.html
new file mode 100644 (file)
index 0000000..0d2435f
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+    if (window.testRunner)
+        testRunner.waitUntilDownloadFinished();
+</script>
+</head>
+<body>
+<p>
+Tests that a suggested filename on a download attribute is allowed if
+<a id="dl" href="data:application/octet-stream,Hello" download="foo.pdf">the link</a> is a data URL.
+<p>The suggested filename at the top should be foo.pdf.</p>
+<script>
+    function click(elmt)
+    {
+        if (!window.eventSender)
+            return;
+
+        eventSender.mouseMoveTo(elmt.offsetLeft + 5, elmt.offsetTop + 5);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+
+    function runTest()
+    {
+        var link = document.getElementById("dl");
+        click(link);
+    }
+    runTest();
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt b/LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt
new file mode 100644 (file)
index 0000000..ff2667b
--- /dev/null
@@ -0,0 +1,6 @@
+Download started.
+Downloading URL with suggested filename "foo.pdf"
+Download completed.
+Tests that a suggested filename on a download attribute is allowed if the link is in the same origin.
+
+The suggested filename at the top should be foo.pdf.
diff --git a/LayoutTests/http/tests/security/anchor-download-allow-sameorigin.html b/LayoutTests/http/tests/security/anchor-download-allow-sameorigin.html
new file mode 100644 (file)
index 0000000..0d10b04
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+    if (window.testRunner)
+        testRunner.waitUntilDownloadFinished();
+</script>
+</head>
+<body>
+<p>
+Tests that a suggested filename on a download attribute is allowed if
+<a id="dl" href="/security/resources/attachment.php" download="foo.pdf">the link</a> is in the same origin.
+<p>
+The suggested filename at the top should be foo.pdf.
+<script>
+    function click(elmt)
+    {
+        if (!window.eventSender)
+            return;
+
+        eventSender.mouseMoveTo(elmt.offsetLeft + 5, elmt.offsetTop + 5);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+
+    function runTest()
+    {
+        var link = document.getElementById("dl");
+        click(link);
+    }
+    runTest();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt b/LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt
new file mode 100644 (file)
index 0000000..13d60c7
--- /dev/null
@@ -0,0 +1,4 @@
+Downloading URL with suggested filename ""
+Tests that a suggested filename on a download attribute is ignored if the link is cross origin.
+
+The suggested filename at the top should be empty.
diff --git a/LayoutTests/http/tests/security/anchor-download-block-crossorigin.html b/LayoutTests/http/tests/security/anchor-download-block-crossorigin.html
new file mode 100644 (file)
index 0000000..aecdb7d
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+    if (window.testRunner)
+        testRunner.waitUntilDownloadFinished();
+</script>
+</head>
+<body>
+<p>
+Tests that a suggested filename on a download attribute is ignored if 
+<a id="dl" href="http://localhost:8080/security/resources/attachment.php" download="foo.pdf">the link</a> is cross origin.
+<p>
+The suggested filename at the top should be empty.
+<script>
+    function click(elmt)
+    {
+        if (!window.eventSender)
+            return;
+
+        eventSender.mouseMoveTo(elmt.offsetLeft + 5, elmt.offsetTop + 5);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+
+    function runTest()
+    {
+        var link = document.getElementById("dl");
+        click(link);
+    }
+    runTest();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/attachment.php b/LayoutTests/http/tests/security/resources/attachment.php
new file mode 100644 (file)
index 0000000..956c96b
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+header("Content-Disposition: attachment; filename=test file.txt");
+header("Content-Type: text/plain");
+?>
+
+Test file content.
index 1a76686..630e4a9 100644 (file)
@@ -1345,3 +1345,9 @@ imported/blink/editing/undo/crash-redo-with-iframes.html [ Failure Pass ]
 imported/blink/fast/css-grid-layout/stale-grid-layout-2.html [ Failure Pass ]
 
 webkit.org/b/155495 compositing/visible-rect/animated-from-none.html [ Failure ]
+
+# <a download> is not support in WK1 yet.
+webkit.org/b/156069 http/tests/security/anchor-download-allow-blob.html [ Skip ]
+webkit.org/b/156069 http/tests/security/anchor-download-allow-data.html [ Skip ]
+webkit.org/b/156069 http/tests/security/anchor-download-allow-sameorigin.html [ Skip ]
+webkit.org/b/156069 http/tests/security/anchor-download-block-crossorigin.html [ Skip ]
index ebd24ab..03410dc 100644 (file)
@@ -1955,3 +1955,9 @@ webkit.org/b/155737 compositing/repaint/become-overlay-composited-layer.html [ P
 webkit.org/b/155947 [ Debug ] fast/loader/scroll-position-restored-on-back.html [ Pass Failure ]
 
 webkit.org/b/155948 transitions/cancel-transition.html [ Pass Failure ]
+
+# <a download> is not supported with NETWORK_SESSION yet.
+webkit.org/b/156067 http/tests/security/anchor-download-allow-blob.html [ Skip ]
+webkit.org/b/156067 http/tests/security/anchor-download-allow-data.html [ Skip ]
+webkit.org/b/156067 http/tests/security/anchor-download-allow-sameorigin.html [ Skip ]
+webkit.org/b/156067 http/tests/security/anchor-download-block-crossorigin.html [ Skip ]
index 76bae87..15b304a 100644 (file)
@@ -201,3 +201,11 @@ fast/scrolling/scroll-animator-overlay-scrollbars-hovered.html [ Skip ]
 
 # This hit-test test doesn't work on DRT
 webkit.org/b/156084 accessibility/mac/video-tag-hit-test.html [ Skip ]
+
+# <a download> is not support in WK1 yet.
+webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-nodownload-set.html [ Failure ]
+webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-download.html [ Failure ]
+webkit.org/b/156069 http/tests/security/anchor-download-allow-blob.html [ Skip ]
+webkit.org/b/156069 http/tests/security/anchor-download-allow-data.html [ Skip ]
+webkit.org/b/156069 http/tests/security/anchor-download-allow-sameorigin.html [ Skip ]
+webkit.org/b/156069 http/tests/security/anchor-download-block-crossorigin.html [ Skip ]
index 6a12d14..bdb748c 100644 (file)
@@ -260,12 +260,6 @@ storage/storagequota-query-usage.html
 storage/storagequota-request-quota.html
 fast/workers/worker-storagequota-query-usage.html
 
-# Tests that require ENABLE(DOWNLOAD_ATTRIBUTE).
-fast/dom/HTMLAnchorElement/anchor-nodownload.html
-fast/dom/HTMLAnchorElement/anchor-download.html
-fast/dom/HTMLAnchorElement/anchor-nodownload-set.html
-fast/dom/HTMLAnchorElement/anchor-download-unset.html
-
 # HTTP 204 (No Content) should be ignored
 webkit.org/b/60206 http/tests/navigation/response204.html
 
index f6e89ee..a6741bc 100644 (file)
@@ -1,3 +1,18 @@
+2016-04-01  Brent Fulgham  <bfulgham@apple.com>
+
+        Confirm <a download> satisfies specification criteria
+        https://bugs.webkit.org/show_bug.cgi?id=156057
+
+        Reviewed by Andy Estes.
+
+        * WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.cpp:
+        (WKBundleNavigationActionGetHasDownloadAttribute): Added.
+        * WebProcess/InjectedBundle/API/c/WKBundleNavigationActionPrivate.h:
+        * WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp:
+        (WebKit::InjectedBundleNavigationAction::InjectedBundleNavigationAction):
+        * WebProcess/InjectedBundle/InjectedBundleNavigationAction.h:
+        (WebKit::InjectedBundleNavigationAction::hasDownloadAttribute): Added.
+
 2016-04-01  Alex Christensen  <achristensen@webkit.org>
 
         CMake build fix.
index 84392c7..ee89827 100644 (file)
@@ -76,3 +76,8 @@ bool WKBundleNavigationActionGetShouldTryAppLinks(WKBundleNavigationActionRef na
 {
     return toImpl(navigationActionRef)->shouldTryAppLinks();
 }
+
+WKStringRef WKBundleNavigationActionCopyDownloadAttribute(WKBundleNavigationActionRef navigationActionRef)
+{
+    return toCopiedAPI(toImpl(navigationActionRef)->downloadAttribute());
+}
index 4746929..25d1640 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
 
 WK_EXPORT bool WKBundleNavigationActionGetShouldOpenExternalURLs(WKBundleNavigationActionRef);
 WK_EXPORT bool WKBundleNavigationActionGetShouldTryAppLinks(WKBundleNavigationActionRef);
+WK_EXPORT WKStringRef WKBundleNavigationActionCopyDownloadAttribute(WKBundleNavigationActionRef);
 
 #ifdef __cplusplus
 }
index a87b747..390b8f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -91,6 +91,7 @@ InjectedBundleNavigationAction::InjectedBundleNavigationAction(WebFrame* frame,
     : m_navigationType(navigationAction.type())
     , m_modifiers(modifiersForNavigationAction(navigationAction))
     , m_mouseButton(WebMouseEvent::NoButton)
+    , m_downloadAttribute(navigationAction.downloadAttribute())
     , m_shouldOpenExternalURLs(navigationAction.shouldOpenExternalURLsPolicy() == ShouldOpenExternalURLsPolicy::ShouldAllow || navigationAction.shouldOpenExternalURLsPolicy() == ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes)
     , m_shouldTryAppLinks(navigationAction.shouldOpenExternalURLsPolicy() == ShouldOpenExternalURLsPolicy::ShouldAllow)
 {
index fb84e6a..4ec25aa 100644 (file)
@@ -58,6 +58,7 @@ public:
 
     bool shouldOpenExternalURLs() const { return m_shouldOpenExternalURLs; }
     bool shouldTryAppLinks() const { return m_shouldTryAppLinks; }
+    AtomicString downloadAttribute() const { return m_downloadAttribute; }
 
 private:
     InjectedBundleNavigationAction(WebFrame*, const WebCore::NavigationAction&, PassRefPtr<WebCore::FormState>);
@@ -67,6 +68,7 @@ private:
     WebMouseEvent::Button m_mouseButton;
     RefPtr<InjectedBundleHitTestResult> m_hitTestResult;
     RefPtr<InjectedBundleNodeHandle> m_formElement;
+    AtomicString m_downloadAttribute;
     bool m_shouldOpenExternalURLs;
     bool m_shouldTryAppLinks;
 };
index bb5a242..b036779 100644 (file)
@@ -1,3 +1,38 @@
+2016-04-01  Brent Fulgham  <bfulgham@apple.com>
+
+        Confirm <a download> satisfies specification criteria
+        https://bugs.webkit.org/show_bug.cgi?id=156057
+
+        Reviewed by Andy Estes.
+
+        Revise WebKitTestRunner:
+        (1) Provide a download client delegate.
+        (2) Teach WKTR to wait to finish a test until a download finishes.
+        (3) Allow WKTR to notify the current TestRunner that it can finish.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::didReceiveMessageToPage): Update to recognize a new
+        message "NotifyDownloadDone".
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::InjectedBundlePage::decidePolicyForNavigationAction): Handle 'download'
+        attribute case.
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::waitUntilDownload): Added.
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        (WTR::TestRunner::shouldFinishAfterDownload): Added.
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::createWebViewWithOptions): Set up the download client.
+        (WTR::TestController::downloadDidStart): Added.
+        (WTR::TestController::decideDestinationWithSuggestedFilename): Added.
+        (WTR::TestController::downloadDidFinish): Added.
+        (WTR::TestController::downloadDidFail): Added.
+        (WTR::TestController::downloadDidCancel): Added.
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::notifyDownloadDone): Added.
+        * WebKitTestRunner/TestInvocation.h:
+
 2016-04-01  Alex Christensen  <achristensen@webkit.org>
 
         Compile DumpRenderTree with CMake on Mac
index f9b6497..9b899e3 100644 (file)
@@ -29,6 +29,7 @@ interface TestRunner {
     void dumpChildFramesAsText();
     void waitForPolicyDelegate();
     void waitUntilDone();
+    void waitUntilDownloadFinished();
     void notifyDone();
     double preciseTime();
 
index c6aefbb..e634d0b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -236,6 +236,11 @@ void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef m
         return;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "NotifyDownloadDone")) {
+        m_testRunner->notifyDone();
+        return;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "CallUISideScriptCallback")) {
         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
 
index d3a3638..cf134f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1317,8 +1317,11 @@ WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForNavigationAction(WKB
     if (injectedBundle.testRunner()->shouldDecideNavigationPolicyAfterDelay())
         return WKBundlePagePolicyActionPassThrough;
 
-    if (!injectedBundle.testRunner()->isPolicyDelegateEnabled())
-        return WKBundlePagePolicyActionUse;
+    if (!injectedBundle.testRunner()->isPolicyDelegateEnabled()) {
+        WKRetainPtr<WKStringRef> downloadAttributeRef(AdoptWK, WKBundleNavigationActionCopyDownloadAttribute(navigationAction));
+        String downloadAttribute = toWTFString(downloadAttributeRef);
+        return downloadAttribute.isNull() ? WKBundlePagePolicyActionUse : WKBundlePagePolicyActionPassThrough;
+    }
 
     WKRetainPtr<WKURLRef> url = adoptWK(WKURLRequestCopyURL(request));
     WKRetainPtr<WKStringRef> urlScheme = adoptWK(WKURLCopyScheme(url.get()));
index 1a29200..1a0e004 100644 (file)
@@ -141,6 +141,12 @@ void TestRunner::waitForPolicyDelegate()
     waitUntilDone();
 }
 
+void TestRunner::waitUntilDownloadFinished()
+{
+    m_shouldFinishAfterDownload = true;
+    waitUntilDone();
+}
+
 void TestRunner::waitUntilDone()
 {
     m_waitToDump = true;
index 2ee67bb..ad2e728 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -67,6 +67,7 @@ public:
     void dumpAsText(bool dumpPixels);
     void waitForPolicyDelegate();
     void dumpChildFramesAsText() { m_whatToDump = AllFramesText; }
+    void waitUntilDownloadFinished();
     void waitUntilDone();
     void notifyDone();
     double preciseTime();
@@ -195,6 +196,7 @@ public:
     bool waitToDump() const { return m_waitToDump; }
     void waitToDumpWatchdogTimerFired();
     void invalidateWaitToDumpWatchdogTimer();
+    bool shouldFinishAfterDownload() const { return m_shouldFinishAfterDownload; }
 
     bool shouldAllowEditing() const { return m_shouldAllowEditing; }
 
@@ -289,7 +291,7 @@ public:
     void queueNonLoadingScript(JSStringRef script);
 
     bool secureEventInputIsEnabled() const;
-    
+
     JSValueRef failNextNewCodeBlock();
     JSValueRef numberOfDFGCompiles(JSValueRef theFunction);
     JSValueRef neverInlineFunction(JSValueRef theFunction);
@@ -364,6 +366,7 @@ private:
     double m_databaseMaxQuota;
 
     bool m_shouldDecideNavigationPolicyAfterDelay { false };
+    bool m_shouldFinishAfterDownload { false };
 
     bool m_userStyleSheetEnabled;
     WKRetainPtr<WKStringRef> m_userStyleSheetLocation;
index dd75412..af57bf5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2014-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -585,7 +585,22 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
     };
     WKPageSetPageNavigationClient(m_mainWebView->page(), &pageNavigationClient.base);
 
-
+    WKContextDownloadClientV0 downloadClient = {
+        { 0, this },
+        downloadDidStart,
+        0, // didReceiveAuthenticationChallenge
+        0, // didReceiveResponse
+        0, // didReceiveData
+        0, // shouldDecodeSourceDataOfMIMEType
+        decideDestinationWithSuggestedFilename,
+        0, // didCreateDestination
+        downloadDidFinish,
+        downloadDidFail,
+        downloadDidCancel,
+        0 // processDidCrash;
+    };
+    WKContextSetDownloadClient(context(), &downloadClient.base);
+    
     // this should just be done on the page?
     WKPageInjectedBundleClientV0 injectedBundleClient = {
         { 0, this },
@@ -1628,6 +1643,85 @@ void TestController::didReceiveAuthenticationChallenge(WKPageRef page, WKAuthent
     WKAuthenticationDecisionListenerUseCredential(decisionListener, credential.get());
 }
 
+    
+// WKContextDownloadClient
+
+void TestController::downloadDidStart(WKContextRef context, WKDownloadRef download, const void* clientInfo)
+{
+    static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidStart(context, download);
+}
+    
+WKStringRef TestController::decideDestinationWithSuggestedFilename(WKContextRef context, WKDownloadRef download, WKStringRef filename, bool* allowOverwrite, const void* clientInfo)
+{
+    return static_cast<TestController*>(const_cast<void*>(clientInfo))->decideDestinationWithSuggestedFilename(context, download, filename, allowOverwrite);
+}
+
+void TestController::downloadDidFinish(WKContextRef context, WKDownloadRef download, const void* clientInfo)
+{
+    static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidFinish(context, download);
+}
+
+void TestController::downloadDidFail(WKContextRef context, WKDownloadRef download, WKErrorRef error, const void* clientInfo)
+{
+    static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidFail(context, download, error);
+}
+
+void TestController::downloadDidCancel(WKContextRef context, WKDownloadRef download, const void* clientInfo)
+{
+    static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidCancel(context, download);
+}
+
+void TestController::downloadDidStart(WKContextRef context, WKDownloadRef download)
+{
+    m_currentInvocation->outputText("Download started.\n");
+}
+
+WKStringRef TestController::decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool*& allowOverwrite)
+{
+    StringBuilder builder;
+    builder.append("Downloading URL with suggested filename \"");
+    builder.append(toWTFString(filename));
+    builder.append("\"\n");
+
+    m_currentInvocation->outputText(builder.toString());
+
+    return nullptr;
+}
+
+void TestController::downloadDidFinish(WKContextRef, WKDownloadRef)
+{
+    m_currentInvocation->outputText("Download completed.\n");
+    m_currentInvocation->notifyDownloadDone();
+}
+
+void TestController::downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef error)
+{
+    String message = String::format("Download failed.\n");
+    m_currentInvocation->outputText(message);
+    
+    WKRetainPtr<WKStringRef> errorDomain = adoptWK(WKErrorCopyDomain(error));
+    WKRetainPtr<WKStringRef> errorDescription = adoptWK(WKErrorCopyLocalizedDescription(error));
+    int errorCode = WKErrorGetErrorCode(error);
+
+    StringBuilder errorBuilder;
+    errorBuilder.append("Failed: ");
+    errorBuilder.append(toWTFString(errorDomain));
+    errorBuilder.append(", code=");
+    errorBuilder.appendNumber(errorCode);
+    errorBuilder.append(", description=");
+    errorBuilder.append(toWTFString(errorDescription));
+    errorBuilder.append("\n");
+
+    m_currentInvocation->outputText(errorBuilder.toString());
+    m_currentInvocation->notifyDownloadDone();
+}
+
+void TestController::downloadDidCancel(WKContextRef, WKDownloadRef)
+{
+    m_currentInvocation->outputText("Download cancelled.\n");
+    m_currentInvocation->notifyDownloadDone();
+}
+
 void TestController::processDidCrash()
 {
     // This function can be called multiple times when crash logs are being saved on Windows, so
index 303fda1..88e38de 100644 (file)
@@ -203,6 +203,19 @@ private:
     static void didFinishNavigation(WKPageRef, WKNavigationRef, WKTypeRef userData, const void*);
     void didFinishNavigation(WKPageRef, WKNavigationRef);
 
+    
+    // WKContextDownloadClient
+    static void downloadDidStart(WKContextRef, WKDownloadRef, const void*);
+    void downloadDidStart(WKContextRef, WKDownloadRef);
+    static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool* allowOverwrite, const void *clientInfo);
+    WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool*& allowOverwrite);
+    static void downloadDidFinish(WKContextRef, WKDownloadRef, const void*);
+    void downloadDidFinish(WKContextRef, WKDownloadRef);
+    static void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef, const void*);
+    void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef);
+    static void downloadDidCancel(WKContextRef, WKDownloadRef, const void*);
+    void downloadDidCancel(WKContextRef, WKDownloadRef);
+    
     static void processDidCrash(WKPageRef, const void* clientInfo);
     void processDidCrash();
 
index 01ff5da..9094f58 100644 (file)
@@ -762,4 +762,10 @@ void TestInvocation::didRemoveSwipeSnapshot()
     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
 }
 
+void TestInvocation::notifyDownloadDone()
+{
+    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone"));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
 } // namespace WTR
index ac9c8ad..2ad130d 100644 (file)
@@ -65,6 +65,8 @@ public:
     void didEndSwipe();
     void didRemoveSwipeSnapshot();
 
+    void notifyDownloadDone();
+
 private:
     void dumpResults();
     static void dump(const char* textToStdout, const char* textToStderr = 0, bool seenError = false);