1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/bind_helpers.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/path_service.h"
12 #include "base/prefs/pref_member.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/test/test_file_util.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #include "chrome/browser/download/chrome_download_manager_delegate.h"
17 #include "chrome/browser/download/download_history.h"
18 #include "chrome/browser/download/download_prefs.h"
19 #include "chrome/browser/download/download_service.h"
20 #include "chrome/browser/download/download_service_factory.h"
21 #include "chrome/browser/download/save_package_file_picker.h"
22 #include "chrome/browser/net/url_request_mock_util.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_window.h"
27 #include "chrome/browser/ui/tabs/tab_strip_model.h"
28 #include "chrome/common/chrome_paths.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/test/base/in_process_browser_test.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "components/history/core/browser/download_constants.h"
35 #include "components/history/core/browser/download_row.h"
36 #include "content/public/browser/download_item.h"
37 #include "content/public/browser/download_manager.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/notification_types.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/common/url_constants.h"
42 #include "content/public/test/test_utils.h"
43 #include "net/test/url_request/url_request_mock_http_job.h"
44 #include "testing/gtest/include/gtest/gtest.h"
46 using content::BrowserContext
;
47 using content::BrowserThread
;
48 using content::DownloadItem
;
49 using content::DownloadManager
;
50 using content::WebContents
;
51 using net::URLRequestMockHTTPJob
;
55 // Waits for an item record in the downloads database to match |filter|. See
56 // DownloadStoredProperly() below for an example filter.
57 class DownloadPersistedObserver
: public DownloadHistory::Observer
{
59 typedef base::Callback
<bool(
61 const history::DownloadRow
&)> PersistedFilter
;
63 DownloadPersistedObserver(Profile
* profile
, const PersistedFilter
& filter
)
68 DownloadServiceFactory::GetForBrowserContext(profile_
)->
69 GetDownloadHistory()->AddObserver(this);
72 ~DownloadPersistedObserver() override
{
73 DownloadService
* service
= DownloadServiceFactory::GetForBrowserContext(
75 if (service
&& service
->GetDownloadHistory())
76 service
->GetDownloadHistory()->RemoveObserver(this);
79 bool WaitForPersisted() {
83 content::RunMessageLoop();
88 void OnDownloadStored(DownloadItem
* item
,
89 const history::DownloadRow
& info
) override
{
90 persisted_
= persisted_
|| filter_
.Run(item
, info
);
91 if (persisted_
&& waiting_
)
92 base::MessageLoopForUI::current()->Quit();
97 PersistedFilter filter_
;
101 DISALLOW_COPY_AND_ASSIGN(DownloadPersistedObserver
);
104 // Waits for an item record to be removed from the downloads database.
105 class DownloadRemovedObserver
: public DownloadPersistedObserver
{
107 DownloadRemovedObserver(Profile
* profile
, int32 download_id
)
108 : DownloadPersistedObserver(profile
, PersistedFilter()),
111 download_id_(download_id
) {
113 ~DownloadRemovedObserver() override
{}
115 bool WaitForRemoved() {
119 content::RunMessageLoop();
124 void OnDownloadStored(DownloadItem
* item
,
125 const history::DownloadRow
& info
) override
{}
127 void OnDownloadsRemoved(const DownloadHistory::IdSet
& ids
) override
{
128 removed_
= ids
.find(download_id_
) != ids
.end();
129 if (removed_
&& waiting_
)
130 base::MessageLoopForUI::current()->Quit();
138 DISALLOW_COPY_AND_ASSIGN(DownloadRemovedObserver
);
141 bool DownloadStoredProperly(
142 const GURL
& expected_url
,
143 const base::FilePath
& expected_path
,
145 history::DownloadState expected_state
,
147 const history::DownloadRow
& info
) {
148 // This function may be called multiple times for a given test. Returning
149 // false doesn't necessarily mean that the test has failed or will fail, it
150 // might just mean that the test hasn't passed yet.
151 if (info
.target_path
!= expected_path
) {
152 DVLOG(20) << __FUNCTION__
<< " " << info
.target_path
.value()
153 << " != " << expected_path
.value();
156 if (info
.url_chain
.size() != 1u) {
157 DVLOG(20) << __FUNCTION__
<< " " << info
.url_chain
.size()
161 if (info
.url_chain
[0] != expected_url
) {
162 DVLOG(20) << __FUNCTION__
<< " " << info
.url_chain
[0].spec()
163 << " != " << expected_url
.spec();
166 if ((num_files
>= 0) && (info
.received_bytes
!= num_files
)) {
167 DVLOG(20) << __FUNCTION__
<< " " << num_files
168 << " != " << info
.received_bytes
;
171 if (info
.state
!= expected_state
) {
172 DVLOG(20) << __FUNCTION__
<< " " << info
.state
173 << " != " << expected_state
;
179 const base::FilePath::CharType kTestDir
[] = FILE_PATH_LITERAL("save_page");
181 static const char kAppendedExtension
[] = ".html";
183 // Loosely based on logic in DownloadTestObserver.
184 class DownloadItemCreatedObserver
: public DownloadManager::Observer
{
186 explicit DownloadItemCreatedObserver(DownloadManager
* manager
)
187 : waiting_(false), manager_(manager
) {
188 manager
->AddObserver(this);
191 ~DownloadItemCreatedObserver() override
{
193 manager_
->RemoveObserver(this);
196 // Wait for the first download item created after object creation.
197 // Note that this class provides no protection against the download
198 // being destroyed between creation and return of WaitForNewDownloadItem();
199 // the caller must guarantee that in some other fashion.
200 void WaitForDownloadItem(std::vector
<DownloadItem
*>* items_seen
) {
202 // The manager went away before we were asked to wait; return
203 // what we have, even if it's null.
204 *items_seen
= items_seen_
;
208 if (items_seen_
.empty()) {
210 content::RunMessageLoop();
214 *items_seen
= items_seen_
;
219 // DownloadManager::Observer
220 void OnDownloadCreated(DownloadManager
* manager
,
221 DownloadItem
* item
) override
{
222 DCHECK_EQ(manager
, manager_
);
223 items_seen_
.push_back(item
);
226 base::MessageLoopForUI::current()->Quit();
229 void ManagerGoingDown(DownloadManager
* manager
) override
{
230 manager_
->RemoveObserver(this);
233 base::MessageLoopForUI::current()->Quit();
237 DownloadManager
* manager_
;
238 std::vector
<DownloadItem
*> items_seen_
;
240 DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver
);
243 class SavePackageFinishedObserver
: public content::DownloadManager::Observer
{
245 SavePackageFinishedObserver(content::DownloadManager
* manager
,
246 const base::Closure
& callback
)
247 : download_manager_(manager
),
248 callback_(callback
) {
249 download_manager_
->AddObserver(this);
252 ~SavePackageFinishedObserver() override
{
253 if (download_manager_
)
254 download_manager_
->RemoveObserver(this);
257 // DownloadManager::Observer:
258 void OnSavePackageSuccessfullyFinished(content::DownloadManager
* manager
,
259 content::DownloadItem
* item
) override
{
262 void ManagerGoingDown(content::DownloadManager
* manager
) override
{
263 download_manager_
->RemoveObserver(this);
264 download_manager_
= NULL
;
268 content::DownloadManager
* download_manager_
;
269 base::Closure callback_
;
271 DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver
);
274 class SavePageBrowserTest
: public InProcessBrowserTest
{
276 SavePageBrowserTest() {}
277 ~SavePageBrowserTest() override
;
280 void SetUp() override
{
281 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_dir_
));
282 ASSERT_TRUE(save_dir_
.CreateUniqueTempDir());
283 InProcessBrowserTest::SetUp();
286 void SetUpOnMainThread() override
{
287 browser()->profile()->GetPrefs()->SetFilePath(
288 prefs::kDownloadDefaultDirectory
, save_dir_
.path());
289 browser()->profile()->GetPrefs()->SetFilePath(
290 prefs::kSaveFileDefaultDirectory
, save_dir_
.path());
291 BrowserThread::PostTask(
292 BrowserThread::IO
, FROM_HERE
,
293 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
296 GURL
NavigateToMockURL(const std::string
& prefix
) {
297 GURL url
= URLRequestMockHTTPJob::GetMockUrl(
298 base::FilePath(kTestDir
).AppendASCII(prefix
+ ".htm"));
299 ui_test_utils::NavigateToURL(browser(), url
);
303 // Returns full paths of destination file and directory.
304 void GetDestinationPaths(const std::string
& prefix
,
305 base::FilePath
* full_file_name
,
306 base::FilePath
* dir
) {
307 *full_file_name
= save_dir_
.path().AppendASCII(prefix
+ ".htm");
308 *dir
= save_dir_
.path().AppendASCII(prefix
+ "_files");
311 WebContents
* GetCurrentTab(Browser
* browser
) const {
312 WebContents
* current_tab
=
313 browser
->tab_strip_model()->GetActiveWebContents();
314 EXPECT_TRUE(current_tab
);
318 // Returns true if and when there was a single download created, and its url
319 // is |expected_url|.
320 bool VerifySavePackageExpectations(
322 const GURL
& expected_url
) const {
323 // Generally, there should only be one download item created
324 // in all of these tests. If it's already here, grab it; if not,
325 // wait for it to show up.
326 std::vector
<DownloadItem
*> items
;
327 DownloadManager
* manager(
328 BrowserContext::GetDownloadManager(browser
->profile()));
329 manager
->GetAllDownloads(&items
);
330 if (items
.size() == 0u) {
331 DownloadItemCreatedObserver(manager
).WaitForDownloadItem(&items
);
334 EXPECT_EQ(1u, items
.size());
335 if (1u != items
.size())
337 DownloadItem
* download_item(items
[0]);
339 return (expected_url
== download_item
->GetOriginalUrl());
342 // Note on synchronization:
344 // For each Save Page As operation, we create a corresponding shell
345 // DownloadItem to display progress to the user. That DownloadItem goes
346 // through its own state transitions, including being persisted out to the
347 // history database, and the download shelf is not shown until after the
348 // persistence occurs. Save Package completion (and marking the DownloadItem
349 // as completed) occurs asynchronously from persistence. Thus if we want to
350 // examine either UI state or DB state, we need to wait until both the save
351 // package operation is complete and the relevant download item has been
354 DownloadManager
* GetDownloadManager() const {
355 DownloadManager
* download_manager
=
356 BrowserContext::GetDownloadManager(browser()->profile());
357 EXPECT_TRUE(download_manager
);
358 return download_manager
;
361 // Path to directory containing test data.
362 base::FilePath test_dir_
;
364 // Temporary directory we will save pages to.
365 base::ScopedTempDir save_dir_
;
368 DISALLOW_COPY_AND_ASSIGN(SavePageBrowserTest
);
371 SavePageBrowserTest::~SavePageBrowserTest() {
374 // Disabled on Windows due to flakiness. http://crbug.com/162323
376 #define MAYBE_SaveHTMLOnly DISABLED_SaveHTMLOnly
378 #define MAYBE_SaveHTMLOnly SaveHTMLOnly
380 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, MAYBE_SaveHTMLOnly
) {
381 GURL url
= NavigateToMockURL("a");
383 base::FilePath full_file_name
, dir
;
384 GetDestinationPaths("a", &full_file_name
, &dir
);
385 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
386 &DownloadStoredProperly
, url
, full_file_name
, 1,
387 history::DownloadState::COMPLETE
));
388 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
389 new content::MessageLoopRunner
);
390 SavePackageFinishedObserver
observer(
391 content::BrowserContext::GetDownloadManager(browser()->profile()),
392 loop_runner
->QuitClosure());
393 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name
, dir
,
394 content::SAVE_PAGE_TYPE_AS_ONLY_HTML
));
396 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url
));
397 persisted
.WaitForPersisted();
398 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
399 EXPECT_TRUE(base::PathExists(full_file_name
));
400 EXPECT_FALSE(base::PathExists(dir
));
401 EXPECT_TRUE(base::ContentsEqual(test_dir_
.Append(base::FilePath(
402 kTestDir
)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name
));
405 // http://crbug.com/162323
406 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, DISABLED_SaveHTMLOnlyCancel
) {
407 GURL url
= NavigateToMockURL("a");
408 DownloadManager
* manager(GetDownloadManager());
409 std::vector
<DownloadItem
*> downloads
;
410 manager
->GetAllDownloads(&downloads
);
411 ASSERT_EQ(0u, downloads
.size());
413 base::FilePath full_file_name
, dir
;
414 GetDestinationPaths("a", &full_file_name
, &dir
);
415 DownloadItemCreatedObserver
creation_observer(manager
);
416 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
417 &DownloadStoredProperly
, url
, full_file_name
, -1,
418 history::DownloadState::CANCELLED
));
419 // -1 to disable number of files check; we don't update after cancel, and
420 // we don't know when the single file completed in relationship to
423 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name
, dir
,
424 content::SAVE_PAGE_TYPE_AS_ONLY_HTML
));
425 std::vector
<DownloadItem
*> items
;
426 creation_observer
.WaitForDownloadItem(&items
);
427 ASSERT_EQ(1UL, items
.size());
428 ASSERT_EQ(url
.spec(), items
[0]->GetOriginalUrl().spec());
429 items
[0]->Cancel(true);
430 // TODO(rdsmith): Fix DII::Cancel() to actually cancel the save package.
431 // Currently it's ignored.
433 persisted
.WaitForPersisted();
435 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
437 // TODO(benjhayden): Figure out how to safely wait for SavePackage's finished
438 // notification, then expect the contents of the downloaded file.
441 class DelayingDownloadManagerDelegate
: public ChromeDownloadManagerDelegate
{
443 explicit DelayingDownloadManagerDelegate(Profile
* profile
)
444 : ChromeDownloadManagerDelegate(profile
) {
446 ~DelayingDownloadManagerDelegate() override
{}
448 bool ShouldCompleteDownload(
449 content::DownloadItem
* item
,
450 const base::Closure
& user_complete_callback
) override
{
455 DISALLOW_COPY_AND_ASSIGN(DelayingDownloadManagerDelegate
);
458 // Disabled on Windows due to flakiness. http://crbug.com/162323
460 #define MAYBE_SaveHTMLOnlyTabDestroy DISABLED_SaveHTMLOnlyTabDestroy
462 #define MAYBE_SaveHTMLOnlyTabDestroy SaveHTMLOnlyTabDestroy
464 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, MAYBE_SaveHTMLOnlyTabDestroy
) {
465 GURL url
= NavigateToMockURL("a");
466 scoped_ptr
<DelayingDownloadManagerDelegate
> delaying_delegate(
467 new DelayingDownloadManagerDelegate(browser()->profile()));
468 delaying_delegate
->GetDownloadIdReceiverCallback().Run(
469 content::DownloadItem::kInvalidId
+ 1);
470 DownloadServiceFactory::GetForBrowserContext(browser()->profile())
471 ->SetDownloadManagerDelegateForTesting(delaying_delegate
.Pass());
472 DownloadManager
* manager(GetDownloadManager());
473 std::vector
<DownloadItem
*> downloads
;
474 manager
->GetAllDownloads(&downloads
);
475 ASSERT_EQ(0u, downloads
.size());
477 base::FilePath full_file_name
, dir
;
478 GetDestinationPaths("a", &full_file_name
, &dir
);
479 DownloadItemCreatedObserver
creation_observer(manager
);
480 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name
, dir
,
481 content::SAVE_PAGE_TYPE_AS_ONLY_HTML
));
482 std::vector
<DownloadItem
*> items
;
483 creation_observer
.WaitForDownloadItem(&items
);
484 ASSERT_TRUE(items
.size() == 1);
486 // Close the tab; does this cancel the download?
487 GetCurrentTab(browser())->Close();
488 EXPECT_EQ(DownloadItem::CANCELLED
, items
[0]->GetState());
490 EXPECT_FALSE(base::PathExists(full_file_name
));
491 EXPECT_FALSE(base::PathExists(dir
));
494 // Disabled on Windows due to flakiness. http://crbug.com/162323
496 #define MAYBE_SaveViewSourceHTMLOnly DISABLED_SaveViewSourceHTMLOnly
498 #define MAYBE_SaveViewSourceHTMLOnly SaveViewSourceHTMLOnly
500 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, MAYBE_SaveViewSourceHTMLOnly
) {
501 base::FilePath
file_name(FILE_PATH_LITERAL("a.htm"));
502 GURL mock_url
= URLRequestMockHTTPJob::GetMockUrl(
503 base::FilePath(kTestDir
).Append(file_name
));
504 GURL view_source_url
=
505 GURL(content::kViewSourceScheme
+ std::string(":") + mock_url
.spec());
506 GURL actual_page_url
= URLRequestMockHTTPJob::GetMockUrl(
507 base::FilePath(kTestDir
).Append(file_name
));
508 ui_test_utils::NavigateToURL(browser(), view_source_url
);
510 base::FilePath full_file_name
, dir
;
511 GetDestinationPaths("a", &full_file_name
, &dir
);
512 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
513 &DownloadStoredProperly
, actual_page_url
, full_file_name
, 1,
514 history::DownloadState::COMPLETE
));
515 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
516 new content::MessageLoopRunner
);
517 SavePackageFinishedObserver
observer(
518 content::BrowserContext::GetDownloadManager(browser()->profile()),
519 loop_runner
->QuitClosure());
520 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name
, dir
,
521 content::SAVE_PAGE_TYPE_AS_ONLY_HTML
));
523 ASSERT_TRUE(VerifySavePackageExpectations(browser(), actual_page_url
));
524 persisted
.WaitForPersisted();
526 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
528 EXPECT_TRUE(base::PathExists(full_file_name
));
529 EXPECT_FALSE(base::PathExists(dir
));
530 EXPECT_TRUE(base::ContentsEqual(
531 test_dir_
.Append(base::FilePath(kTestDir
)).Append(file_name
),
535 // Disabled on Windows due to flakiness. http://crbug.com/162323
537 #define MAYBE_SaveCompleteHTML DISABLED_SaveCompleteHTML
539 #define MAYBE_SaveCompleteHTML SaveCompleteHTML
541 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, MAYBE_SaveCompleteHTML
) {
542 GURL url
= NavigateToMockURL("b");
544 base::FilePath full_file_name
, dir
;
545 GetDestinationPaths("b", &full_file_name
, &dir
);
546 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
547 &DownloadStoredProperly
, url
, full_file_name
, 3,
548 history::DownloadState::COMPLETE
));
549 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
550 new content::MessageLoopRunner
);
551 SavePackageFinishedObserver
observer(
552 content::BrowserContext::GetDownloadManager(browser()->profile()),
553 loop_runner
->QuitClosure());
554 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
555 full_file_name
, dir
, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML
));
557 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url
));
558 persisted
.WaitForPersisted();
560 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
562 EXPECT_TRUE(base::PathExists(full_file_name
));
563 EXPECT_TRUE(base::PathExists(dir
));
564 EXPECT_TRUE(base::TextContentsEqual(
565 test_dir_
.Append(base::FilePath(kTestDir
)).AppendASCII("b.saved1.htm"),
567 EXPECT_TRUE(base::ContentsEqual(
568 test_dir_
.Append(base::FilePath(kTestDir
)).AppendASCII("1.png"),
569 dir
.AppendASCII("1.png")));
570 EXPECT_TRUE(base::ContentsEqual(
571 test_dir_
.Append(base::FilePath(kTestDir
)).AppendASCII("1.css"),
572 dir
.AppendASCII("1.css")));
575 // Invoke a save page during the initial navigation.
576 // (Regression test for http://crbug.com/156538).
577 // Disabled on Windows due to flakiness. http://crbug.com/162323
579 #define MAYBE_SaveDuringInitialNavigationIncognito DISABLED_SaveDuringInitialNavigationIncognito
581 #define MAYBE_SaveDuringInitialNavigationIncognito SaveDuringInitialNavigationIncognito
583 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
,
584 MAYBE_SaveDuringInitialNavigationIncognito
) {
585 // Open an Incognito window.
586 Browser
* incognito
= CreateIncognitoBrowser(); // Waits.
587 ASSERT_TRUE(incognito
);
589 // Create a download item creation waiter on that window.
590 DownloadItemCreatedObserver
creation_observer(
591 BrowserContext::GetDownloadManager(incognito
->profile()));
593 // Navigate, unblocking with new tab.
594 GURL url
= URLRequestMockHTTPJob::GetMockUrl(
595 base::FilePath(kTestDir
).AppendASCII("b.htm"));
596 NavigateToURLWithDisposition(incognito
, url
, NEW_FOREGROUND_TAB
,
597 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB
);
599 // Save the page before completion.
600 base::FilePath full_file_name
, dir
;
601 GetDestinationPaths("b", &full_file_name
, &dir
);
602 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
603 new content::MessageLoopRunner
);
604 SavePackageFinishedObserver
observer(
605 content::BrowserContext::GetDownloadManager(incognito
->profile()),
606 loop_runner
->QuitClosure());
607 ASSERT_TRUE(GetCurrentTab(incognito
)->SavePage(
608 full_file_name
, dir
, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML
));
611 ASSERT_TRUE(VerifySavePackageExpectations(incognito
, url
));
613 // Confirm download shelf is visible.
614 EXPECT_TRUE(incognito
->window()->IsDownloadShelfVisible());
616 // We can't check more than this because SavePackage is racing with
617 // the page load. If the page load won the race, then SavePackage
618 // might have completed. If the page load lost the race, then
619 // SavePackage will cancel because there aren't any resources to
623 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, NoSave
) {
624 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL
));
625 EXPECT_FALSE(chrome::CanSavePage(browser()));
628 // Disabled on Windows due to flakiness. http://crbug.com/162323
630 #define MAYBE_FileNameFromPageTitle DISABLED_FileNameFromPageTitle
632 #define MAYBE_FileNameFromPageTitle FileNameFromPageTitle
634 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, MAYBE_FileNameFromPageTitle
) {
635 GURL url
= NavigateToMockURL("b");
637 base::FilePath full_file_name
= save_dir_
.path().AppendASCII(
638 std::string("Test page for saving page feature") + kAppendedExtension
);
639 base::FilePath dir
= save_dir_
.path().AppendASCII(
640 "Test page for saving page feature_files");
641 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
642 &DownloadStoredProperly
, url
, full_file_name
, 3,
643 history::DownloadState::COMPLETE
));
644 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
645 new content::MessageLoopRunner
);
646 SavePackageFinishedObserver
observer(
647 content::BrowserContext::GetDownloadManager(browser()->profile()),
648 loop_runner
->QuitClosure());
649 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
650 full_file_name
, dir
, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML
));
653 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url
));
654 persisted
.WaitForPersisted();
656 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
658 EXPECT_TRUE(base::PathExists(full_file_name
));
659 EXPECT_TRUE(base::PathExists(dir
));
660 EXPECT_TRUE(base::TextContentsEqual(
661 test_dir_
.Append(base::FilePath(kTestDir
)).AppendASCII("b.saved2.htm"),
663 EXPECT_TRUE(base::ContentsEqual(
664 test_dir_
.Append(base::FilePath(kTestDir
)).AppendASCII("1.png"),
665 dir
.AppendASCII("1.png")));
666 EXPECT_TRUE(base::ContentsEqual(
667 test_dir_
.Append(base::FilePath(kTestDir
)).AppendASCII("1.css"),
668 dir
.AppendASCII("1.css")));
671 // Disabled on Windows due to flakiness. http://crbug.com/162323
673 #define MAYBE_RemoveFromList DISABLED_RemoveFromList
675 #define MAYBE_RemoveFromList RemoveFromList
677 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, MAYBE_RemoveFromList
) {
678 GURL url
= NavigateToMockURL("a");
680 base::FilePath full_file_name
, dir
;
681 GetDestinationPaths("a", &full_file_name
, &dir
);
682 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
683 &DownloadStoredProperly
, url
, full_file_name
, 1,
684 history::DownloadState::COMPLETE
));
685 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
686 new content::MessageLoopRunner
);
687 SavePackageFinishedObserver
observer(
688 content::BrowserContext::GetDownloadManager(browser()->profile()),
689 loop_runner
->QuitClosure());
690 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name
, dir
,
691 content::SAVE_PAGE_TYPE_AS_ONLY_HTML
));
694 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url
));
695 persisted
.WaitForPersisted();
697 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
699 DownloadManager
* manager(GetDownloadManager());
700 std::vector
<DownloadItem
*> downloads
;
701 manager
->GetAllDownloads(&downloads
);
702 ASSERT_EQ(1UL, downloads
.size());
703 DownloadRemovedObserver
removed(browser()->profile(), downloads
[0]->GetId());
705 EXPECT_EQ(manager
->RemoveAllDownloads(), 1);
707 removed
.WaitForRemoved();
709 EXPECT_TRUE(base::PathExists(full_file_name
));
710 EXPECT_FALSE(base::PathExists(dir
));
711 EXPECT_TRUE(base::ContentsEqual(test_dir_
.Append(base::FilePath(
712 kTestDir
)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name
));
715 // This tests that a webpage with the title "test.exe" is saved as
717 // We probably don't care to handle this on Linux or Mac.
719 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, CleanFilenameFromPageTitle
) {
720 const base::FilePath
file_name(FILE_PATH_LITERAL("c.htm"));
721 base::FilePath download_dir
=
722 DownloadPrefs::FromDownloadManager(GetDownloadManager())->
724 base::FilePath full_file_name
=
725 download_dir
.AppendASCII(std::string("test.exe") + kAppendedExtension
);
726 base::FilePath dir
= download_dir
.AppendASCII("test.exe_files");
728 EXPECT_FALSE(base::PathExists(full_file_name
));
729 GURL url
= URLRequestMockHTTPJob::GetMockUrl(
730 base::FilePath(kTestDir
).Append(file_name
));
731 ui_test_utils::NavigateToURL(browser(), url
);
733 SavePackageFilePicker::SetShouldPromptUser(false);
734 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
735 new content::MessageLoopRunner
);
736 SavePackageFinishedObserver
observer(
737 content::BrowserContext::GetDownloadManager(browser()->profile()),
738 loop_runner
->QuitClosure());
739 chrome::SavePage(browser());
742 EXPECT_TRUE(base::PathExists(full_file_name
));
744 EXPECT_TRUE(base::DieFileDie(full_file_name
, false));
745 EXPECT_TRUE(base::DieFileDie(dir
, true));
749 class SavePageAsMHTMLBrowserTest
: public SavePageBrowserTest
{
751 SavePageAsMHTMLBrowserTest() {}
752 ~SavePageAsMHTMLBrowserTest() override
;
753 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
754 command_line
->AppendSwitch(switches::kSavePageAsMHTML
);
758 DISALLOW_COPY_AND_ASSIGN(SavePageAsMHTMLBrowserTest
);
761 SavePageAsMHTMLBrowserTest::~SavePageAsMHTMLBrowserTest() {
764 IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest
, SavePageAsMHTML
) {
765 static const int64 kFileSizeMin
= 2758;
766 GURL url
= NavigateToMockURL("b");
767 base::FilePath download_dir
= DownloadPrefs::FromDownloadManager(
768 GetDownloadManager())->DownloadPath();
769 base::FilePath full_file_name
= download_dir
.AppendASCII(std::string(
770 "Test page for saving page feature.mhtml"));
771 SavePackageFilePicker::SetShouldPromptUser(false);
772 DownloadPersistedObserver
persisted(browser()->profile(), base::Bind(
773 &DownloadStoredProperly
, url
, full_file_name
, -1,
774 history::DownloadState::COMPLETE
));
775 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
776 new content::MessageLoopRunner
);
777 SavePackageFinishedObserver
observer(
778 content::BrowserContext::GetDownloadManager(browser()->profile()),
779 loop_runner
->QuitClosure());
780 chrome::SavePage(browser());
782 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url
));
783 persisted
.WaitForPersisted();
785 ASSERT_TRUE(base::PathExists(full_file_name
));
786 int64 actual_file_size
= -1;
787 EXPECT_TRUE(base::GetFileSize(full_file_name
, &actual_file_size
));
788 EXPECT_LE(kFileSizeMin
, actual_file_size
);
791 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest
, SavePageBrowserTest_NonMHTML
) {
792 SavePackageFilePicker::SetShouldPromptUser(false);
793 GURL
url("data:text/plain,foo");
794 ui_test_utils::NavigateToURL(browser(), url
);
795 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
796 new content::MessageLoopRunner
);
797 SavePackageFinishedObserver
observer(
798 content::BrowserContext::GetDownloadManager(browser()->profile()),
799 loop_runner
->QuitClosure());
800 chrome::SavePage(browser());
802 base::FilePath download_dir
= DownloadPrefs::FromDownloadManager(
803 GetDownloadManager())->DownloadPath();
804 base::FilePath filename
= download_dir
.AppendASCII("dataurl.txt");
805 ASSERT_TRUE(base::PathExists(filename
));
806 std::string contents
;
807 EXPECT_TRUE(base::ReadFileToString(filename
, &contents
));
808 EXPECT_EQ("foo", contents
);