Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / download / save_page_browsertest.cc
blobdd43f6c2090b984c11d44a97d82f46d37532bb37
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/file_util.h"
9 #include "base/files/file_path.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/history/download_row.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 "content/public/browser/download_item.h"
36 #include "content/public/browser/download_manager.h"
37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/notification_types.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/test/test_utils.h"
41 #include "content/test/net/url_request_mock_http_job.h"
42 #include "testing/gtest/include/gtest/gtest.h"
44 using content::BrowserContext;
45 using content::BrowserThread;
46 using content::DownloadItem;
47 using content::DownloadManager;
48 using content::URLRequestMockHTTPJob;
49 using content::WebContents;
51 namespace {
53 // Waits for an item record in the downloads database to match |filter|. See
54 // DownloadStoredProperly() below for an example filter.
55 class DownloadPersistedObserver : public DownloadHistory::Observer {
56 public:
57 typedef base::Callback<bool(
58 DownloadItem* item,
59 const history::DownloadRow&)> PersistedFilter;
61 DownloadPersistedObserver(Profile* profile, const PersistedFilter& filter)
62 : profile_(profile),
63 filter_(filter),
64 waiting_(false),
65 persisted_(false) {
66 DownloadServiceFactory::GetForBrowserContext(profile_)->
67 GetDownloadHistory()->AddObserver(this);
70 virtual ~DownloadPersistedObserver() {
71 DownloadService* service = DownloadServiceFactory::GetForBrowserContext(
72 profile_);
73 if (service && service->GetDownloadHistory())
74 service->GetDownloadHistory()->RemoveObserver(this);
77 bool WaitForPersisted() {
78 if (persisted_)
79 return true;
80 waiting_ = true;
81 content::RunMessageLoop();
82 waiting_ = false;
83 return persisted_;
86 virtual void OnDownloadStored(DownloadItem* item,
87 const history::DownloadRow& info) OVERRIDE {
88 persisted_ = persisted_ || filter_.Run(item, info);
89 if (persisted_ && waiting_)
90 base::MessageLoopForUI::current()->Quit();
93 private:
94 Profile* profile_;
95 PersistedFilter filter_;
96 bool waiting_;
97 bool persisted_;
99 DISALLOW_COPY_AND_ASSIGN(DownloadPersistedObserver);
102 // Waits for an item record to be removed from the downloads database.
103 class DownloadRemovedObserver : public DownloadPersistedObserver {
104 public:
105 DownloadRemovedObserver(Profile* profile, int32 download_id)
106 : DownloadPersistedObserver(profile, PersistedFilter()),
107 removed_(false),
108 waiting_(false),
109 download_id_(download_id) {
111 virtual ~DownloadRemovedObserver() {}
113 bool WaitForRemoved() {
114 if (removed_)
115 return true;
116 waiting_ = true;
117 content::RunMessageLoop();
118 waiting_ = false;
119 return removed_;
122 virtual void OnDownloadStored(DownloadItem* item,
123 const history::DownloadRow& info) OVERRIDE {
126 virtual void OnDownloadsRemoved(const DownloadHistory::IdSet& ids) OVERRIDE {
127 removed_ = ids.find(download_id_) != ids.end();
128 if (removed_ && waiting_)
129 base::MessageLoopForUI::current()->Quit();
132 private:
133 bool removed_;
134 bool waiting_;
135 int32 download_id_;
137 DISALLOW_COPY_AND_ASSIGN(DownloadRemovedObserver);
140 bool DownloadStoredProperly(
141 const GURL& expected_url,
142 const base::FilePath& expected_path,
143 int64 num_files,
144 DownloadItem::DownloadState expected_state,
145 DownloadItem* item,
146 const history::DownloadRow& info) {
147 // This function may be called multiple times for a given test. Returning
148 // false doesn't necessarily mean that the test has failed or will fail, it
149 // might just mean that the test hasn't passed yet.
150 if (info.target_path != expected_path) {
151 VLOG(20) << __FUNCTION__ << " " << info.target_path.value()
152 << " != " << expected_path.value();
153 return false;
155 if (info.url_chain.size() != 1u) {
156 VLOG(20) << __FUNCTION__ << " " << info.url_chain.size()
157 << " != 1";
158 return false;
160 if (info.url_chain[0] != expected_url) {
161 VLOG(20) << __FUNCTION__ << " " << info.url_chain[0].spec()
162 << " != " << expected_url.spec();
163 return false;
165 if ((num_files >= 0) && (info.received_bytes != num_files)) {
166 VLOG(20) << __FUNCTION__ << " " << num_files
167 << " != " << info.received_bytes;
168 return false;
170 if (info.state != expected_state) {
171 VLOG(20) << __FUNCTION__ << " " << info.state
172 << " != " << expected_state;
173 return false;
175 return true;
178 const base::FilePath::CharType kTestDir[] = FILE_PATH_LITERAL("save_page");
180 static const char kAppendedExtension[] =
181 #if defined(OS_WIN)
182 ".htm";
183 #else
184 ".html";
185 #endif
187 // Loosely based on logic in DownloadTestObserver.
188 class DownloadItemCreatedObserver : public DownloadManager::Observer {
189 public:
190 explicit DownloadItemCreatedObserver(DownloadManager* manager)
191 : waiting_(false), manager_(manager) {
192 manager->AddObserver(this);
195 virtual ~DownloadItemCreatedObserver() {
196 if (manager_)
197 manager_->RemoveObserver(this);
200 // Wait for the first download item created after object creation.
201 // Note that this class provides no protection against the download
202 // being destroyed between creation and return of WaitForNewDownloadItem();
203 // the caller must guarantee that in some other fashion.
204 void WaitForDownloadItem(std::vector<DownloadItem*>* items_seen) {
205 if (!manager_) {
206 // The manager went away before we were asked to wait; return
207 // what we have, even if it's null.
208 *items_seen = items_seen_;
209 return;
212 if (items_seen_.empty()) {
213 waiting_ = true;
214 content::RunMessageLoop();
215 waiting_ = false;
218 *items_seen = items_seen_;
219 return;
222 private:
223 // DownloadManager::Observer
224 virtual void OnDownloadCreated(
225 DownloadManager* manager, DownloadItem* item) OVERRIDE {
226 DCHECK_EQ(manager, manager_);
227 items_seen_.push_back(item);
229 if (waiting_)
230 base::MessageLoopForUI::current()->Quit();
233 virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE {
234 manager_->RemoveObserver(this);
235 manager_ = NULL;
236 if (waiting_)
237 base::MessageLoopForUI::current()->Quit();
240 bool waiting_;
241 DownloadManager* manager_;
242 std::vector<DownloadItem*> items_seen_;
244 DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver);
247 class SavePackageFinishedObserver : public content::DownloadManager::Observer {
248 public:
249 SavePackageFinishedObserver(content::DownloadManager* manager,
250 const base::Closure& callback)
251 : download_manager_(manager),
252 callback_(callback) {
253 download_manager_->AddObserver(this);
256 virtual ~SavePackageFinishedObserver() {
257 if (download_manager_)
258 download_manager_->RemoveObserver(this);
261 // DownloadManager::Observer:
262 virtual void OnSavePackageSuccessfullyFinished(
263 content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE {
264 callback_.Run();
266 virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE {
267 download_manager_->RemoveObserver(this);
268 download_manager_ = NULL;
271 private:
272 content::DownloadManager* download_manager_;
273 base::Closure callback_;
275 DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver);
278 class SavePageBrowserTest : public InProcessBrowserTest {
279 public:
280 SavePageBrowserTest() {}
281 virtual ~SavePageBrowserTest();
283 protected:
284 virtual void SetUp() OVERRIDE {
285 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
286 ASSERT_TRUE(save_dir_.CreateUniqueTempDir());
287 InProcessBrowserTest::SetUp();
290 virtual void SetUpOnMainThread() OVERRIDE {
291 browser()->profile()->GetPrefs()->SetFilePath(
292 prefs::kDownloadDefaultDirectory, save_dir_.path());
293 browser()->profile()->GetPrefs()->SetFilePath(
294 prefs::kSaveFileDefaultDirectory, save_dir_.path());
295 BrowserThread::PostTask(
296 BrowserThread::IO, FROM_HERE,
297 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
300 GURL NavigateToMockURL(const std::string& prefix) {
301 GURL url = URLRequestMockHTTPJob::GetMockUrl(
302 base::FilePath(kTestDir).AppendASCII(prefix + ".htm"));
303 ui_test_utils::NavigateToURL(browser(), url);
304 return url;
307 // Returns full paths of destination file and directory.
308 void GetDestinationPaths(const std::string& prefix,
309 base::FilePath* full_file_name,
310 base::FilePath* dir) {
311 *full_file_name = save_dir_.path().AppendASCII(prefix + ".htm");
312 *dir = save_dir_.path().AppendASCII(prefix + "_files");
315 WebContents* GetCurrentTab(Browser* browser) const {
316 WebContents* current_tab =
317 browser->tab_strip_model()->GetActiveWebContents();
318 EXPECT_TRUE(current_tab);
319 return current_tab;
322 // Returns true if and when there was a single download created, and its url
323 // is |expected_url|.
324 bool VerifySavePackageExpectations(
325 Browser* browser,
326 const GURL& expected_url) const {
327 // Generally, there should only be one download item created
328 // in all of these tests. If it's already here, grab it; if not,
329 // wait for it to show up.
330 std::vector<DownloadItem*> items;
331 DownloadManager* manager(
332 BrowserContext::GetDownloadManager(browser->profile()));
333 manager->GetAllDownloads(&items);
334 if (items.size() == 0u) {
335 DownloadItemCreatedObserver(manager).WaitForDownloadItem(&items);
338 EXPECT_EQ(1u, items.size());
339 if (1u != items.size())
340 return false;
341 DownloadItem* download_item(items[0]);
343 return (expected_url == download_item->GetOriginalUrl());
346 // Note on synchronization:
348 // For each Save Page As operation, we create a corresponding shell
349 // DownloadItem to display progress to the user. That DownloadItem goes
350 // through its own state transitions, including being persisted out to the
351 // history database, and the download shelf is not shown until after the
352 // persistence occurs. Save Package completion (and marking the DownloadItem
353 // as completed) occurs asynchronously from persistence. Thus if we want to
354 // examine either UI state or DB state, we need to wait until both the save
355 // package operation is complete and the relevant download item has been
356 // persisted.
358 DownloadManager* GetDownloadManager() const {
359 DownloadManager* download_manager =
360 BrowserContext::GetDownloadManager(browser()->profile());
361 EXPECT_TRUE(download_manager);
362 return download_manager;
365 // Path to directory containing test data.
366 base::FilePath test_dir_;
368 // Temporary directory we will save pages to.
369 base::ScopedTempDir save_dir_;
371 private:
372 DISALLOW_COPY_AND_ASSIGN(SavePageBrowserTest);
375 SavePageBrowserTest::~SavePageBrowserTest() {
378 // Disabled on Windows due to flakiness. http://crbug.com/162323
379 #if defined(OS_WIN)
380 #define MAYBE_SaveHTMLOnly DISABLED_SaveHTMLOnly
381 #else
382 #define MAYBE_SaveHTMLOnly SaveHTMLOnly
383 #endif
384 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnly) {
385 GURL url = NavigateToMockURL("a");
387 base::FilePath full_file_name, dir;
388 GetDestinationPaths("a", &full_file_name, &dir);
389 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
390 &DownloadStoredProperly, url, full_file_name, 1,
391 DownloadItem::COMPLETE));
392 scoped_refptr<content::MessageLoopRunner> loop_runner(
393 new content::MessageLoopRunner);
394 SavePackageFinishedObserver observer(
395 content::BrowserContext::GetDownloadManager(browser()->profile()),
396 loop_runner->QuitClosure());
397 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
398 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
399 loop_runner->Run();
400 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
401 persisted.WaitForPersisted();
402 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
403 EXPECT_TRUE(base::PathExists(full_file_name));
404 EXPECT_FALSE(base::PathExists(dir));
405 EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
406 kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
409 // http://crbug.com/162323
410 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_SaveHTMLOnlyCancel) {
411 GURL url = NavigateToMockURL("a");
412 DownloadManager* manager(GetDownloadManager());
413 std::vector<DownloadItem*> downloads;
414 manager->GetAllDownloads(&downloads);
415 ASSERT_EQ(0u, downloads.size());
417 base::FilePath full_file_name, dir;
418 GetDestinationPaths("a", &full_file_name, &dir);
419 DownloadItemCreatedObserver creation_observer(manager);
420 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
421 &DownloadStoredProperly, url, full_file_name, -1,
422 DownloadItem::CANCELLED));
423 // -1 to disable number of files check; we don't update after cancel, and
424 // we don't know when the single file completed in relationship to
425 // the cancel.
427 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
428 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
429 std::vector<DownloadItem*> items;
430 creation_observer.WaitForDownloadItem(&items);
431 ASSERT_EQ(1UL, items.size());
432 ASSERT_EQ(url.spec(), items[0]->GetOriginalUrl().spec());
433 items[0]->Cancel(true);
434 // TODO(rdsmith): Fix DII::Cancel() to actually cancel the save package.
435 // Currently it's ignored.
437 persisted.WaitForPersisted();
439 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
441 // TODO(benjhayden): Figure out how to safely wait for SavePackage's finished
442 // notification, then expect the contents of the downloaded file.
445 class DelayingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
446 public:
447 explicit DelayingDownloadManagerDelegate(Profile* profile)
448 : ChromeDownloadManagerDelegate(profile) {
450 virtual ~DelayingDownloadManagerDelegate() {}
452 virtual bool ShouldCompleteDownload(
453 content::DownloadItem* item,
454 const base::Closure& user_complete_callback) OVERRIDE {
455 return false;
458 private:
459 DISALLOW_COPY_AND_ASSIGN(DelayingDownloadManagerDelegate);
462 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, 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(
470 delaying_delegate.PassAs<ChromeDownloadManagerDelegate>());
471 DownloadManager* manager(GetDownloadManager());
472 std::vector<DownloadItem*> downloads;
473 manager->GetAllDownloads(&downloads);
474 ASSERT_EQ(0u, downloads.size());
476 base::FilePath full_file_name, dir;
477 GetDestinationPaths("a", &full_file_name, &dir);
478 DownloadItemCreatedObserver creation_observer(manager);
479 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
480 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
481 std::vector<DownloadItem*> items;
482 creation_observer.WaitForDownloadItem(&items);
483 ASSERT_TRUE(items.size() == 1);
485 // Close the tab; does this cancel the download?
486 GetCurrentTab(browser())->Close();
487 EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
489 EXPECT_FALSE(base::PathExists(full_file_name));
490 EXPECT_FALSE(base::PathExists(dir));
493 // Disabled on Windows due to flakiness. http://crbug.com/162323
494 #if defined(OS_WIN)
495 #define MAYBE_SaveViewSourceHTMLOnly DISABLED_SaveViewSourceHTMLOnly
496 #else
497 #define MAYBE_SaveViewSourceHTMLOnly SaveViewSourceHTMLOnly
498 #endif
499 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveViewSourceHTMLOnly) {
500 base::FilePath file_name(FILE_PATH_LITERAL("a.htm"));
501 GURL view_source_url = URLRequestMockHTTPJob::GetMockViewSourceUrl(
502 base::FilePath(kTestDir).Append(file_name));
503 GURL actual_page_url = URLRequestMockHTTPJob::GetMockUrl(
504 base::FilePath(kTestDir).Append(file_name));
505 ui_test_utils::NavigateToURL(browser(), view_source_url);
507 base::FilePath full_file_name, dir;
508 GetDestinationPaths("a", &full_file_name, &dir);
509 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
510 &DownloadStoredProperly, actual_page_url, full_file_name, 1,
511 DownloadItem::COMPLETE));
512 scoped_refptr<content::MessageLoopRunner> loop_runner(
513 new content::MessageLoopRunner);
514 SavePackageFinishedObserver observer(
515 content::BrowserContext::GetDownloadManager(browser()->profile()),
516 loop_runner->QuitClosure());
517 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
518 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
519 loop_runner->Run();
520 ASSERT_TRUE(VerifySavePackageExpectations(browser(), actual_page_url));
521 persisted.WaitForPersisted();
523 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
525 EXPECT_TRUE(base::PathExists(full_file_name));
526 EXPECT_FALSE(base::PathExists(dir));
527 EXPECT_TRUE(base::ContentsEqual(
528 test_dir_.Append(base::FilePath(kTestDir)).Append(file_name),
529 full_file_name));
532 // Disabled on Windows due to flakiness. http://crbug.com/162323
533 #if defined(OS_WIN)
534 #define MAYBE_SaveCompleteHTML DISABLED_SaveCompleteHTML
535 #else
536 #define MAYBE_SaveCompleteHTML SaveCompleteHTML
537 #endif
538 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveCompleteHTML) {
539 GURL url = NavigateToMockURL("b");
541 base::FilePath full_file_name, dir;
542 GetDestinationPaths("b", &full_file_name, &dir);
543 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
544 &DownloadStoredProperly, url, full_file_name, 3,
545 DownloadItem::COMPLETE));
546 scoped_refptr<content::MessageLoopRunner> loop_runner(
547 new content::MessageLoopRunner);
548 SavePackageFinishedObserver observer(
549 content::BrowserContext::GetDownloadManager(browser()->profile()),
550 loop_runner->QuitClosure());
551 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
552 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
553 loop_runner->Run();
554 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
555 persisted.WaitForPersisted();
557 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
559 EXPECT_TRUE(base::PathExists(full_file_name));
560 EXPECT_TRUE(base::PathExists(dir));
561 EXPECT_TRUE(base::TextContentsEqual(
562 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
563 full_file_name));
564 EXPECT_TRUE(base::ContentsEqual(
565 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
566 dir.AppendASCII("1.png")));
567 EXPECT_TRUE(base::ContentsEqual(
568 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
569 dir.AppendASCII("1.css")));
572 // Invoke a save page during the initial navigation.
573 // (Regression test for http://crbug.com/156538).
574 // Disabled on Windows due to flakiness. http://crbug.com/162323
575 #if defined(OS_WIN)
576 #define MAYBE_SaveDuringInitialNavigationIncognito DISABLED_SaveDuringInitialNavigationIncognito
577 #else
578 #define MAYBE_SaveDuringInitialNavigationIncognito SaveDuringInitialNavigationIncognito
579 #endif
580 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
581 MAYBE_SaveDuringInitialNavigationIncognito) {
582 // Open an Incognito window.
583 Browser* incognito = CreateIncognitoBrowser(); // Waits.
584 ASSERT_TRUE(incognito);
586 // Create a download item creation waiter on that window.
587 DownloadItemCreatedObserver creation_observer(
588 BrowserContext::GetDownloadManager(incognito->profile()));
590 // Navigate, unblocking with new tab.
591 GURL url = URLRequestMockHTTPJob::GetMockUrl(
592 base::FilePath(kTestDir).AppendASCII("b.htm"));
593 NavigateToURLWithDisposition(incognito, url, NEW_FOREGROUND_TAB,
594 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
596 // Save the page before completion.
597 base::FilePath full_file_name, dir;
598 GetDestinationPaths("b", &full_file_name, &dir);
599 scoped_refptr<content::MessageLoopRunner> loop_runner(
600 new content::MessageLoopRunner);
601 SavePackageFinishedObserver observer(
602 content::BrowserContext::GetDownloadManager(incognito->profile()),
603 loop_runner->QuitClosure());
604 ASSERT_TRUE(GetCurrentTab(incognito)->SavePage(
605 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
607 loop_runner->Run();
608 ASSERT_TRUE(VerifySavePackageExpectations(incognito, url));
610 // Confirm download shelf is visible.
611 EXPECT_TRUE(incognito->window()->IsDownloadShelfVisible());
613 // We can't check more than this because SavePackage is racing with
614 // the page load. If the page load won the race, then SavePackage
615 // might have completed. If the page load lost the race, then
616 // SavePackage will cancel because there aren't any resources to
617 // save.
620 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, NoSave) {
621 ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL));
622 EXPECT_FALSE(chrome::CanSavePage(browser()));
625 // Disabled on Windows due to flakiness. http://crbug.com/162323
626 #if defined(OS_WIN)
627 #define MAYBE_FileNameFromPageTitle DISABLED_FileNameFromPageTitle
628 #else
629 #define MAYBE_FileNameFromPageTitle FileNameFromPageTitle
630 #endif
631 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_FileNameFromPageTitle) {
632 GURL url = NavigateToMockURL("b");
634 base::FilePath full_file_name = save_dir_.path().AppendASCII(
635 std::string("Test page for saving page feature") + kAppendedExtension);
636 base::FilePath dir = save_dir_.path().AppendASCII(
637 "Test page for saving page feature_files");
638 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
639 &DownloadStoredProperly, url, full_file_name, 3,
640 DownloadItem::COMPLETE));
641 scoped_refptr<content::MessageLoopRunner> loop_runner(
642 new content::MessageLoopRunner);
643 SavePackageFinishedObserver observer(
644 content::BrowserContext::GetDownloadManager(browser()->profile()),
645 loop_runner->QuitClosure());
646 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
647 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
649 loop_runner->Run();
650 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
651 persisted.WaitForPersisted();
653 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
655 EXPECT_TRUE(base::PathExists(full_file_name));
656 EXPECT_TRUE(base::PathExists(dir));
657 EXPECT_TRUE(base::TextContentsEqual(
658 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
659 full_file_name));
660 EXPECT_TRUE(base::ContentsEqual(
661 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
662 dir.AppendASCII("1.png")));
663 EXPECT_TRUE(base::ContentsEqual(
664 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
665 dir.AppendASCII("1.css")));
668 // Disabled on Windows due to flakiness. http://crbug.com/162323
669 #if defined(OS_WIN)
670 #define MAYBE_RemoveFromList DISABLED_RemoveFromList
671 #else
672 #define MAYBE_RemoveFromList RemoveFromList
673 #endif
674 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_RemoveFromList) {
675 GURL url = NavigateToMockURL("a");
677 base::FilePath full_file_name, dir;
678 GetDestinationPaths("a", &full_file_name, &dir);
679 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
680 &DownloadStoredProperly, url, full_file_name, 1,
681 DownloadItem::COMPLETE));
682 scoped_refptr<content::MessageLoopRunner> loop_runner(
683 new content::MessageLoopRunner);
684 SavePackageFinishedObserver observer(
685 content::BrowserContext::GetDownloadManager(browser()->profile()),
686 loop_runner->QuitClosure());
687 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
688 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
690 loop_runner->Run();
691 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
692 persisted.WaitForPersisted();
694 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
696 DownloadManager* manager(GetDownloadManager());
697 std::vector<DownloadItem*> downloads;
698 manager->GetAllDownloads(&downloads);
699 ASSERT_EQ(1UL, downloads.size());
700 DownloadRemovedObserver removed(browser()->profile(), downloads[0]->GetId());
702 EXPECT_EQ(manager->RemoveAllDownloads(), 1);
704 removed.WaitForRemoved();
706 EXPECT_TRUE(base::PathExists(full_file_name));
707 EXPECT_FALSE(base::PathExists(dir));
708 EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
709 kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
712 // This tests that a webpage with the title "test.exe" is saved as
713 // "test.exe.htm".
714 // We probably don't care to handle this on Linux or Mac.
715 #if defined(OS_WIN)
716 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, CleanFilenameFromPageTitle) {
717 const base::FilePath file_name(FILE_PATH_LITERAL("c.htm"));
718 base::FilePath download_dir =
719 DownloadPrefs::FromDownloadManager(GetDownloadManager())->
720 DownloadPath();
721 base::FilePath full_file_name =
722 download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension);
723 base::FilePath dir = download_dir.AppendASCII("test.exe_files");
725 EXPECT_FALSE(base::PathExists(full_file_name));
726 GURL url = URLRequestMockHTTPJob::GetMockUrl(
727 base::FilePath(kTestDir).Append(file_name));
728 ui_test_utils::NavigateToURL(browser(), url);
730 SavePackageFilePicker::SetShouldPromptUser(false);
731 scoped_refptr<content::MessageLoopRunner> loop_runner(
732 new content::MessageLoopRunner);
733 SavePackageFinishedObserver observer(
734 content::BrowserContext::GetDownloadManager(browser()->profile()),
735 loop_runner->QuitClosure());
736 chrome::SavePage(browser());
737 loop_runner->Run();
739 EXPECT_TRUE(base::PathExists(full_file_name));
741 EXPECT_TRUE(file_util::DieFileDie(full_file_name, false));
742 EXPECT_TRUE(file_util::DieFileDie(dir, true));
744 #endif
746 class SavePageAsMHTMLBrowserTest : public SavePageBrowserTest {
747 public:
748 SavePageAsMHTMLBrowserTest() {}
749 virtual ~SavePageAsMHTMLBrowserTest();
750 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
751 command_line->AppendSwitch(switches::kSavePageAsMHTML);
754 private:
755 DISALLOW_COPY_AND_ASSIGN(SavePageAsMHTMLBrowserTest);
758 SavePageAsMHTMLBrowserTest::~SavePageAsMHTMLBrowserTest() {
761 IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
762 static const int64 kFileSizeMin = 2758;
763 GURL url = NavigateToMockURL("b");
764 base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
765 GetDownloadManager())->DownloadPath();
766 base::FilePath full_file_name = download_dir.AppendASCII(std::string(
767 "Test page for saving page feature.mhtml"));
768 SavePackageFilePicker::SetShouldPromptUser(false);
769 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
770 &DownloadStoredProperly, url, full_file_name, -1,
771 DownloadItem::COMPLETE));
772 scoped_refptr<content::MessageLoopRunner> loop_runner(
773 new content::MessageLoopRunner);
774 SavePackageFinishedObserver observer(
775 content::BrowserContext::GetDownloadManager(browser()->profile()),
776 loop_runner->QuitClosure());
777 chrome::SavePage(browser());
778 loop_runner->Run();
779 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
780 persisted.WaitForPersisted();
782 ASSERT_TRUE(base::PathExists(full_file_name));
783 int64 actual_file_size = -1;
784 EXPECT_TRUE(base::GetFileSize(full_file_name, &actual_file_size));
785 EXPECT_LE(kFileSizeMin, actual_file_size);
788 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SavePageBrowserTest_NonMHTML) {
789 SavePackageFilePicker::SetShouldPromptUser(false);
790 GURL url("data:text/plain,foo");
791 ui_test_utils::NavigateToURL(browser(), url);
792 scoped_refptr<content::MessageLoopRunner> loop_runner(
793 new content::MessageLoopRunner);
794 SavePackageFinishedObserver observer(
795 content::BrowserContext::GetDownloadManager(browser()->profile()),
796 loop_runner->QuitClosure());
797 chrome::SavePage(browser());
798 loop_runner->Run();
799 base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
800 GetDownloadManager())->DownloadPath();
801 base::FilePath filename = download_dir.AppendASCII("dataurl.txt");
802 ASSERT_TRUE(base::PathExists(filename));
803 std::string contents;
804 EXPECT_TRUE(base::ReadFileToString(filename, &contents));
805 EXPECT_EQ("foo", contents);
808 } // namespace