Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / download / save_page_browsertest.cc
blob7ac4c5e2a014965ae6127eecb36218a4417a06dc
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.
5 #include "base/bind.h"
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/notification/download_notification_manager.h"
22 #include "chrome/browser/download/save_package_file_picker.h"
23 #include "chrome/browser/net/url_request_mock_util.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_commands.h"
27 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h"
33 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/ui_test_utils.h"
35 #include "components/history/core/browser/download_constants.h"
36 #include "components/history/core/browser/download_row.h"
37 #include "content/public/browser/download_item.h"
38 #include "content/public/browser/download_manager.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/notification_types.h"
41 #include "content/public/browser/web_contents.h"
42 #include "content/public/common/url_constants.h"
43 #include "content/public/test/test_utils.h"
44 #include "net/test/url_request/url_request_mock_http_job.h"
45 #include "testing/gtest/include/gtest/gtest.h"
47 using content::BrowserContext;
48 using content::BrowserThread;
49 using content::DownloadItem;
50 using content::DownloadManager;
51 using content::WebContents;
52 using net::URLRequestMockHTTPJob;
54 namespace {
56 // Waits for an item record in the downloads database to match |filter|. See
57 // DownloadStoredProperly() below for an example filter.
58 class DownloadPersistedObserver : public DownloadHistory::Observer {
59 public:
60 typedef base::Callback<bool(
61 DownloadItem* item,
62 const history::DownloadRow&)> PersistedFilter;
64 DownloadPersistedObserver(Profile* profile, const PersistedFilter& filter)
65 : profile_(profile),
66 filter_(filter),
67 waiting_(false),
68 persisted_(false) {
69 DownloadServiceFactory::GetForBrowserContext(profile_)->
70 GetDownloadHistory()->AddObserver(this);
73 ~DownloadPersistedObserver() override {
74 DownloadService* service = DownloadServiceFactory::GetForBrowserContext(
75 profile_);
76 if (service && service->GetDownloadHistory())
77 service->GetDownloadHistory()->RemoveObserver(this);
80 bool WaitForPersisted() {
81 if (persisted_)
82 return true;
83 waiting_ = true;
84 content::RunMessageLoop();
85 waiting_ = false;
86 return persisted_;
89 void OnDownloadStored(DownloadItem* item,
90 const history::DownloadRow& info) override {
91 persisted_ = persisted_ || filter_.Run(item, info);
92 if (persisted_ && waiting_)
93 base::MessageLoopForUI::current()->Quit();
96 private:
97 Profile* profile_;
98 PersistedFilter filter_;
99 bool waiting_;
100 bool persisted_;
102 DISALLOW_COPY_AND_ASSIGN(DownloadPersistedObserver);
105 // Waits for an item record to be removed from the downloads database.
106 class DownloadRemovedObserver : public DownloadPersistedObserver {
107 public:
108 DownloadRemovedObserver(Profile* profile, int32 download_id)
109 : DownloadPersistedObserver(profile, PersistedFilter()),
110 removed_(false),
111 waiting_(false),
112 download_id_(download_id) {
114 ~DownloadRemovedObserver() override {}
116 bool WaitForRemoved() {
117 if (removed_)
118 return true;
119 waiting_ = true;
120 content::RunMessageLoop();
121 waiting_ = false;
122 return removed_;
125 void OnDownloadStored(DownloadItem* item,
126 const history::DownloadRow& info) override {}
128 void OnDownloadsRemoved(const DownloadHistory::IdSet& ids) override {
129 removed_ = ids.find(download_id_) != ids.end();
130 if (removed_ && waiting_)
131 base::MessageLoopForUI::current()->Quit();
134 private:
135 bool removed_;
136 bool waiting_;
137 int32 download_id_;
139 DISALLOW_COPY_AND_ASSIGN(DownloadRemovedObserver);
142 bool DownloadStoredProperly(
143 const GURL& expected_url,
144 const base::FilePath& expected_path,
145 int64 num_files,
146 history::DownloadState expected_state,
147 DownloadItem* item,
148 const history::DownloadRow& info) {
149 // This function may be called multiple times for a given test. Returning
150 // false doesn't necessarily mean that the test has failed or will fail, it
151 // might just mean that the test hasn't passed yet.
152 if (info.target_path != expected_path) {
153 DVLOG(20) << __FUNCTION__ << " " << info.target_path.value()
154 << " != " << expected_path.value();
155 return false;
157 if (info.url_chain.size() != 1u) {
158 DVLOG(20) << __FUNCTION__ << " " << info.url_chain.size()
159 << " != 1";
160 return false;
162 if (info.url_chain[0] != expected_url) {
163 DVLOG(20) << __FUNCTION__ << " " << info.url_chain[0].spec()
164 << " != " << expected_url.spec();
165 return false;
167 if ((num_files >= 0) && (info.received_bytes != num_files)) {
168 DVLOG(20) << __FUNCTION__ << " " << num_files
169 << " != " << info.received_bytes;
170 return false;
172 if (info.state != expected_state) {
173 DVLOG(20) << __FUNCTION__ << " " << info.state
174 << " != " << expected_state;
175 return false;
177 return true;
180 const base::FilePath::CharType kTestDir[] = FILE_PATH_LITERAL("save_page");
182 static const char kAppendedExtension[] = ".html";
184 // Loosely based on logic in DownloadTestObserver.
185 class DownloadItemCreatedObserver : public DownloadManager::Observer {
186 public:
187 explicit DownloadItemCreatedObserver(DownloadManager* manager)
188 : waiting_(false), manager_(manager) {
189 manager->AddObserver(this);
192 ~DownloadItemCreatedObserver() override {
193 if (manager_)
194 manager_->RemoveObserver(this);
197 // Wait for the first download item created after object creation.
198 // Note that this class provides no protection against the download
199 // being destroyed between creation and return of WaitForNewDownloadItem();
200 // the caller must guarantee that in some other fashion.
201 void WaitForDownloadItem(std::vector<DownloadItem*>* items_seen) {
202 if (!manager_) {
203 // The manager went away before we were asked to wait; return
204 // what we have, even if it's null.
205 *items_seen = items_seen_;
206 return;
209 if (items_seen_.empty()) {
210 waiting_ = true;
211 content::RunMessageLoop();
212 waiting_ = false;
215 *items_seen = items_seen_;
216 return;
219 private:
220 // DownloadManager::Observer
221 void OnDownloadCreated(DownloadManager* manager,
222 DownloadItem* item) override {
223 DCHECK_EQ(manager, manager_);
224 items_seen_.push_back(item);
226 if (waiting_)
227 base::MessageLoopForUI::current()->Quit();
230 void ManagerGoingDown(DownloadManager* manager) override {
231 manager_->RemoveObserver(this);
232 manager_ = NULL;
233 if (waiting_)
234 base::MessageLoopForUI::current()->Quit();
237 bool waiting_;
238 DownloadManager* manager_;
239 std::vector<DownloadItem*> items_seen_;
241 DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver);
244 class SavePackageFinishedObserver : public content::DownloadManager::Observer {
245 public:
246 SavePackageFinishedObserver(content::DownloadManager* manager,
247 const base::Closure& callback)
248 : download_manager_(manager),
249 callback_(callback) {
250 download_manager_->AddObserver(this);
253 ~SavePackageFinishedObserver() override {
254 if (download_manager_)
255 download_manager_->RemoveObserver(this);
258 // DownloadManager::Observer:
259 void OnSavePackageSuccessfullyFinished(content::DownloadManager* manager,
260 content::DownloadItem* item) override {
261 callback_.Run();
263 void ManagerGoingDown(content::DownloadManager* manager) override {
264 download_manager_->RemoveObserver(this);
265 download_manager_ = NULL;
268 private:
269 content::DownloadManager* download_manager_;
270 base::Closure callback_;
272 DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver);
275 class SavePageBrowserTest : public InProcessBrowserTest {
276 public:
277 SavePageBrowserTest() {}
278 ~SavePageBrowserTest() override;
280 protected:
281 void SetUp() override {
282 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
283 ASSERT_TRUE(save_dir_.CreateUniqueTempDir());
284 InProcessBrowserTest::SetUp();
287 void SetUpOnMainThread() override {
288 browser()->profile()->GetPrefs()->SetFilePath(
289 prefs::kDownloadDefaultDirectory, save_dir_.path());
290 browser()->profile()->GetPrefs()->SetFilePath(
291 prefs::kSaveFileDefaultDirectory, save_dir_.path());
292 BrowserThread::PostTask(
293 BrowserThread::IO, FROM_HERE,
294 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
297 GURL NavigateToMockURL(const std::string& prefix) {
298 GURL url = URLRequestMockHTTPJob::GetMockUrl(
299 base::FilePath(kTestDir).AppendASCII(prefix + ".htm"));
300 ui_test_utils::NavigateToURL(browser(), url);
301 return url;
304 // Returns full paths of destination file and directory.
305 void GetDestinationPaths(const std::string& prefix,
306 base::FilePath* full_file_name,
307 base::FilePath* dir) {
308 *full_file_name = save_dir_.path().AppendASCII(prefix + ".htm");
309 *dir = save_dir_.path().AppendASCII(prefix + "_files");
312 WebContents* GetCurrentTab(Browser* browser) const {
313 WebContents* current_tab =
314 browser->tab_strip_model()->GetActiveWebContents();
315 EXPECT_TRUE(current_tab);
316 return current_tab;
319 // Returns true if and when there was a single download created, and its url
320 // is |expected_url|.
321 bool VerifySavePackageExpectations(
322 Browser* browser,
323 const GURL& expected_url) const {
324 // Generally, there should only be one download item created
325 // in all of these tests. If it's already here, grab it; if not,
326 // wait for it to show up.
327 std::vector<DownloadItem*> items;
328 DownloadManager* manager(
329 BrowserContext::GetDownloadManager(browser->profile()));
330 manager->GetAllDownloads(&items);
331 if (items.size() == 0u) {
332 DownloadItemCreatedObserver(manager).WaitForDownloadItem(&items);
335 EXPECT_EQ(1u, items.size());
336 if (1u != items.size())
337 return false;
338 DownloadItem* download_item(items[0]);
340 return (expected_url == download_item->GetOriginalUrl());
343 // Note on synchronization:
345 // For each Save Page As operation, we create a corresponding shell
346 // DownloadItem to display progress to the user. That DownloadItem goes
347 // through its own state transitions, including being persisted out to the
348 // history database, and the download shelf is not shown until after the
349 // persistence occurs. Save Package completion (and marking the DownloadItem
350 // as completed) occurs asynchronously from persistence. Thus if we want to
351 // examine either UI state or DB state, we need to wait until both the save
352 // package operation is complete and the relevant download item has been
353 // persisted.
355 DownloadManager* GetDownloadManager() const {
356 DownloadManager* download_manager =
357 BrowserContext::GetDownloadManager(browser()->profile());
358 EXPECT_TRUE(download_manager);
359 return download_manager;
362 // Path to directory containing test data.
363 base::FilePath test_dir_;
365 // Temporary directory we will save pages to.
366 base::ScopedTempDir save_dir_;
368 private:
369 DISALLOW_COPY_AND_ASSIGN(SavePageBrowserTest);
372 SavePageBrowserTest::~SavePageBrowserTest() {
375 // Disabled on Windows due to flakiness. http://crbug.com/162323
376 #if defined(OS_WIN)
377 #define MAYBE_SaveHTMLOnly DISABLED_SaveHTMLOnly
378 #else
379 #define MAYBE_SaveHTMLOnly SaveHTMLOnly
380 #endif
381 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnly) {
382 GURL url = NavigateToMockURL("a");
384 base::FilePath full_file_name, dir;
385 GetDestinationPaths("a", &full_file_name, &dir);
386 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
387 &DownloadStoredProperly, url, full_file_name, 1,
388 history::DownloadState::COMPLETE));
389 scoped_refptr<content::MessageLoopRunner> loop_runner(
390 new content::MessageLoopRunner);
391 SavePackageFinishedObserver observer(
392 content::BrowserContext::GetDownloadManager(browser()->profile()),
393 loop_runner->QuitClosure());
394 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
395 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
396 loop_runner->Run();
397 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
398 persisted.WaitForPersisted();
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
421 // the cancel.
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 // TODO(benjhayden): Figure out how to safely wait for SavePackage's finished
436 // notification, then expect the contents of the downloaded file.
439 class DelayingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
440 public:
441 explicit DelayingDownloadManagerDelegate(Profile* profile)
442 : ChromeDownloadManagerDelegate(profile) {
444 ~DelayingDownloadManagerDelegate() override {}
446 bool ShouldCompleteDownload(
447 content::DownloadItem* item,
448 const base::Closure& user_complete_callback) override {
449 return false;
452 private:
453 DISALLOW_COPY_AND_ASSIGN(DelayingDownloadManagerDelegate);
456 // Disabled on Windows due to flakiness. http://crbug.com/162323
457 #if defined(OS_WIN)
458 #define MAYBE_SaveHTMLOnlyTabDestroy DISABLED_SaveHTMLOnlyTabDestroy
459 #else
460 #define MAYBE_SaveHTMLOnlyTabDestroy SaveHTMLOnlyTabDestroy
461 #endif
462 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnlyTabDestroy) {
463 GURL url = NavigateToMockURL("a");
464 scoped_ptr<DelayingDownloadManagerDelegate> delaying_delegate(
465 new DelayingDownloadManagerDelegate(browser()->profile()));
466 delaying_delegate->GetDownloadIdReceiverCallback().Run(
467 content::DownloadItem::kInvalidId + 1);
468 DownloadServiceFactory::GetForBrowserContext(browser()->profile())
469 ->SetDownloadManagerDelegateForTesting(delaying_delegate.Pass());
470 DownloadManager* manager(GetDownloadManager());
471 std::vector<DownloadItem*> downloads;
472 manager->GetAllDownloads(&downloads);
473 ASSERT_EQ(0u, downloads.size());
475 base::FilePath full_file_name, dir;
476 GetDestinationPaths("a", &full_file_name, &dir);
477 DownloadItemCreatedObserver creation_observer(manager);
478 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
479 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
480 std::vector<DownloadItem*> items;
481 creation_observer.WaitForDownloadItem(&items);
482 ASSERT_TRUE(items.size() == 1);
484 // Close the tab; does this cancel the download?
485 GetCurrentTab(browser())->Close();
486 EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
488 EXPECT_FALSE(base::PathExists(full_file_name));
489 EXPECT_FALSE(base::PathExists(dir));
492 // Disabled on Windows due to flakiness. http://crbug.com/162323
493 #if defined(OS_WIN)
494 #define MAYBE_SaveViewSourceHTMLOnly DISABLED_SaveViewSourceHTMLOnly
495 #else
496 #define MAYBE_SaveViewSourceHTMLOnly SaveViewSourceHTMLOnly
497 #endif
498 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveViewSourceHTMLOnly) {
499 base::FilePath file_name(FILE_PATH_LITERAL("a.htm"));
500 GURL mock_url = URLRequestMockHTTPJob::GetMockUrl(
501 base::FilePath(kTestDir).Append(file_name));
502 GURL view_source_url =
503 GURL(content::kViewSourceScheme + std::string(":") + mock_url.spec());
504 GURL actual_page_url = URLRequestMockHTTPJob::GetMockUrl(
505 base::FilePath(kTestDir).Append(file_name));
506 ui_test_utils::NavigateToURL(browser(), view_source_url);
508 base::FilePath full_file_name, dir;
509 GetDestinationPaths("a", &full_file_name, &dir);
510 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
511 &DownloadStoredProperly, actual_page_url, full_file_name, 1,
512 history::DownloadState::COMPLETE));
513 scoped_refptr<content::MessageLoopRunner> loop_runner(
514 new content::MessageLoopRunner);
515 SavePackageFinishedObserver observer(
516 content::BrowserContext::GetDownloadManager(browser()->profile()),
517 loop_runner->QuitClosure());
518 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
519 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
520 loop_runner->Run();
521 ASSERT_TRUE(VerifySavePackageExpectations(browser(), actual_page_url));
522 persisted.WaitForPersisted();
524 EXPECT_TRUE(base::PathExists(full_file_name));
525 EXPECT_FALSE(base::PathExists(dir));
526 EXPECT_TRUE(base::ContentsEqual(
527 test_dir_.Append(base::FilePath(kTestDir)).Append(file_name),
528 full_file_name));
531 // Disabled on Windows due to flakiness. http://crbug.com/162323
532 #if defined(OS_WIN)
533 #define MAYBE_SaveCompleteHTML DISABLED_SaveCompleteHTML
534 #else
535 #define MAYBE_SaveCompleteHTML SaveCompleteHTML
536 #endif
537 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveCompleteHTML) {
538 GURL url = NavigateToMockURL("b");
540 base::FilePath full_file_name, dir;
541 GetDestinationPaths("b", &full_file_name, &dir);
542 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
543 &DownloadStoredProperly, url, full_file_name, 3,
544 history::DownloadState::COMPLETE));
545 scoped_refptr<content::MessageLoopRunner> loop_runner(
546 new content::MessageLoopRunner);
547 SavePackageFinishedObserver observer(
548 content::BrowserContext::GetDownloadManager(browser()->profile()),
549 loop_runner->QuitClosure());
550 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
551 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
552 loop_runner->Run();
553 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
554 persisted.WaitForPersisted();
556 EXPECT_TRUE(base::PathExists(full_file_name));
557 EXPECT_TRUE(base::PathExists(dir));
558 EXPECT_TRUE(base::TextContentsEqual(
559 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
560 full_file_name));
561 EXPECT_TRUE(base::ContentsEqual(
562 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
563 dir.AppendASCII("1.png")));
564 EXPECT_TRUE(base::ContentsEqual(
565 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
566 dir.AppendASCII("1.css")));
569 // Invoke a save page during the initial navigation.
570 // (Regression test for http://crbug.com/156538).
571 // Disabled on Windows due to flakiness. http://crbug.com/162323
572 #if defined(OS_WIN)
573 #define MAYBE_SaveDuringInitialNavigationIncognito DISABLED_SaveDuringInitialNavigationIncognito
574 #else
575 #define MAYBE_SaveDuringInitialNavigationIncognito SaveDuringInitialNavigationIncognito
576 #endif
577 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
578 MAYBE_SaveDuringInitialNavigationIncognito) {
579 // Open an Incognito window.
580 Browser* incognito = CreateIncognitoBrowser(); // Waits.
581 ASSERT_TRUE(incognito);
583 // Create a download item creation waiter on that window.
584 DownloadItemCreatedObserver creation_observer(
585 BrowserContext::GetDownloadManager(incognito->profile()));
587 // Navigate, unblocking with new tab.
588 GURL url = URLRequestMockHTTPJob::GetMockUrl(
589 base::FilePath(kTestDir).AppendASCII("b.htm"));
590 NavigateToURLWithDisposition(incognito, url, NEW_FOREGROUND_TAB,
591 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
593 // Save the page before completion.
594 base::FilePath full_file_name, dir;
595 GetDestinationPaths("b", &full_file_name, &dir);
596 scoped_refptr<content::MessageLoopRunner> loop_runner(
597 new content::MessageLoopRunner);
598 SavePackageFinishedObserver observer(
599 content::BrowserContext::GetDownloadManager(incognito->profile()),
600 loop_runner->QuitClosure());
601 ASSERT_TRUE(GetCurrentTab(incognito)->SavePage(
602 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
604 loop_runner->Run();
605 ASSERT_TRUE(VerifySavePackageExpectations(incognito, url));
607 // We can't check more than this because SavePackage is racing with
608 // the page load. If the page load won the race, then SavePackage
609 // might have completed. If the page load lost the race, then
610 // SavePackage will cancel because there aren't any resources to
611 // save.
614 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, NoSave) {
615 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
616 EXPECT_FALSE(chrome::CanSavePage(browser()));
619 // Disabled on Windows due to flakiness. http://crbug.com/162323
620 #if defined(OS_WIN)
621 #define MAYBE_FileNameFromPageTitle DISABLED_FileNameFromPageTitle
622 #else
623 #define MAYBE_FileNameFromPageTitle FileNameFromPageTitle
624 #endif
625 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, FileNameFromPageTitle) {
626 GURL url = NavigateToMockURL("b");
628 base::FilePath full_file_name = save_dir_.path().AppendASCII(
629 std::string("Test page for saving page feature") + kAppendedExtension);
630 base::FilePath dir = save_dir_.path().AppendASCII(
631 "Test page for saving page feature_files");
632 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
633 &DownloadStoredProperly, url, full_file_name, 3,
634 history::DownloadState::COMPLETE));
635 scoped_refptr<content::MessageLoopRunner> loop_runner(
636 new content::MessageLoopRunner);
637 SavePackageFinishedObserver observer(
638 content::BrowserContext::GetDownloadManager(browser()->profile()),
639 loop_runner->QuitClosure());
640 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
641 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
643 loop_runner->Run();
644 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
645 persisted.WaitForPersisted();
647 EXPECT_TRUE(base::PathExists(full_file_name));
648 EXPECT_TRUE(base::PathExists(dir));
649 EXPECT_TRUE(base::TextContentsEqual(
650 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
651 full_file_name));
652 EXPECT_TRUE(base::ContentsEqual(
653 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
654 dir.AppendASCII("1.png")));
655 EXPECT_TRUE(base::ContentsEqual(
656 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
657 dir.AppendASCII("1.css")));
660 // Disabled on Windows due to flakiness. http://crbug.com/162323
661 #if defined(OS_WIN)
662 #define MAYBE_RemoveFromList DISABLED_RemoveFromList
663 #else
664 #define MAYBE_RemoveFromList RemoveFromList
665 #endif
666 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_RemoveFromList) {
667 GURL url = NavigateToMockURL("a");
669 base::FilePath full_file_name, dir;
670 GetDestinationPaths("a", &full_file_name, &dir);
671 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
672 &DownloadStoredProperly, url, full_file_name, 1,
673 history::DownloadState::COMPLETE));
674 scoped_refptr<content::MessageLoopRunner> loop_runner(
675 new content::MessageLoopRunner);
676 SavePackageFinishedObserver observer(
677 content::BrowserContext::GetDownloadManager(browser()->profile()),
678 loop_runner->QuitClosure());
679 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
680 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
682 loop_runner->Run();
683 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
684 persisted.WaitForPersisted();
686 DownloadManager* manager(GetDownloadManager());
687 std::vector<DownloadItem*> downloads;
688 manager->GetAllDownloads(&downloads);
689 ASSERT_EQ(1UL, downloads.size());
690 DownloadRemovedObserver removed(browser()->profile(), downloads[0]->GetId());
692 EXPECT_EQ(manager->RemoveAllDownloads(), 1);
694 removed.WaitForRemoved();
696 EXPECT_TRUE(base::PathExists(full_file_name));
697 EXPECT_FALSE(base::PathExists(dir));
698 EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
699 kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
702 // This tests that a webpage with the title "test.exe" is saved as
703 // "test.exe.htm".
704 // We probably don't care to handle this on Linux or Mac.
705 #if defined(OS_WIN)
706 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, CleanFilenameFromPageTitle) {
707 const base::FilePath file_name(FILE_PATH_LITERAL("c.htm"));
708 base::FilePath download_dir =
709 DownloadPrefs::FromDownloadManager(GetDownloadManager())->
710 DownloadPath();
711 base::FilePath full_file_name =
712 download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension);
713 base::FilePath dir = download_dir.AppendASCII("test.exe_files");
715 EXPECT_FALSE(base::PathExists(full_file_name));
716 GURL url = URLRequestMockHTTPJob::GetMockUrl(
717 base::FilePath(kTestDir).Append(file_name));
718 ui_test_utils::NavigateToURL(browser(), url);
720 SavePackageFilePicker::SetShouldPromptUser(false);
721 scoped_refptr<content::MessageLoopRunner> loop_runner(
722 new content::MessageLoopRunner);
723 SavePackageFinishedObserver observer(
724 content::BrowserContext::GetDownloadManager(browser()->profile()),
725 loop_runner->QuitClosure());
726 chrome::SavePage(browser());
727 loop_runner->Run();
729 EXPECT_TRUE(base::PathExists(full_file_name));
731 EXPECT_TRUE(base::DieFileDie(full_file_name, false));
732 EXPECT_TRUE(base::DieFileDie(dir, true));
734 #endif
736 class SavePageAsMHTMLBrowserTest : public SavePageBrowserTest {
737 public:
738 SavePageAsMHTMLBrowserTest() {}
739 ~SavePageAsMHTMLBrowserTest() override;
740 void SetUpCommandLine(base::CommandLine* command_line) override {
741 command_line->AppendSwitch(switches::kSavePageAsMHTML);
744 private:
745 DISALLOW_COPY_AND_ASSIGN(SavePageAsMHTMLBrowserTest);
748 SavePageAsMHTMLBrowserTest::~SavePageAsMHTMLBrowserTest() {
751 IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
752 static const int64 kFileSizeMin = 2758;
753 GURL url = NavigateToMockURL("b");
754 base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
755 GetDownloadManager())->DownloadPath();
756 base::FilePath full_file_name = download_dir.AppendASCII(std::string(
757 "Test page for saving page feature.mhtml"));
758 SavePackageFilePicker::SetShouldPromptUser(false);
759 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
760 &DownloadStoredProperly, url, full_file_name, -1,
761 history::DownloadState::COMPLETE));
762 scoped_refptr<content::MessageLoopRunner> loop_runner(
763 new content::MessageLoopRunner);
764 SavePackageFinishedObserver observer(
765 content::BrowserContext::GetDownloadManager(browser()->profile()),
766 loop_runner->QuitClosure());
767 chrome::SavePage(browser());
768 loop_runner->Run();
769 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
770 persisted.WaitForPersisted();
772 ASSERT_TRUE(base::PathExists(full_file_name));
773 int64 actual_file_size = -1;
774 EXPECT_TRUE(base::GetFileSize(full_file_name, &actual_file_size));
775 EXPECT_LE(kFileSizeMin, actual_file_size);
778 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SavePageBrowserTest_NonMHTML) {
779 SavePackageFilePicker::SetShouldPromptUser(false);
780 GURL url("data:text/plain,foo");
781 ui_test_utils::NavigateToURL(browser(), url);
782 scoped_refptr<content::MessageLoopRunner> loop_runner(
783 new content::MessageLoopRunner);
784 SavePackageFinishedObserver observer(
785 content::BrowserContext::GetDownloadManager(browser()->profile()),
786 loop_runner->QuitClosure());
787 chrome::SavePage(browser());
788 loop_runner->Run();
789 base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
790 GetDownloadManager())->DownloadPath();
791 base::FilePath filename = download_dir.AppendASCII("dataurl.txt");
792 ASSERT_TRUE(base::PathExists(filename));
793 std::string contents;
794 EXPECT_TRUE(base::ReadFileToString(filename, &contents));
795 EXPECT_EQ("foo", contents);
798 } // namespace