Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / download / save_page_browsertest.cc
blobc092dfe87b6abd13b03fe3b0a778a793f0662519
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/run_loop.h"
15 #include "base/test/test_file_util.h"
16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/download/chrome_download_manager_delegate.h"
18 #include "chrome/browser/download/download_history.h"
19 #include "chrome/browser/download/download_prefs.h"
20 #include "chrome/browser/download/download_service.h"
21 #include "chrome/browser/download/download_service_factory.h"
22 #include "chrome/browser/download/notification/download_notification_manager.h"
23 #include "chrome/browser/download/save_package_file_picker.h"
24 #include "chrome/browser/net/url_request_mock_util.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_commands.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/common/url_constants.h"
34 #include "chrome/test/base/in_process_browser_test.h"
35 #include "chrome/test/base/ui_test_utils.h"
36 #include "components/history/core/browser/download_constants.h"
37 #include "components/history/core/browser/download_row.h"
38 #include "content/public/browser/download_item.h"
39 #include "content/public/browser/download_manager.h"
40 #include "content/public/browser/notification_service.h"
41 #include "content/public/browser/notification_types.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/url_constants.h"
44 #include "content/public/test/browser_test_utils.h"
45 #include "content/public/test/test_utils.h"
46 #include "net/dns/mock_host_resolver.h"
47 #include "net/test/embedded_test_server/embedded_test_server.h"
48 #include "net/test/url_request/url_request_mock_http_job.h"
49 #include "testing/gtest/include/gtest/gtest.h"
51 using content::BrowserContext;
52 using content::BrowserThread;
53 using content::DownloadItem;
54 using content::DownloadManager;
55 using content::WebContents;
56 using net::URLRequestMockHTTPJob;
58 namespace {
60 // Waits for an item record in the downloads database to match |filter|. See
61 // DownloadStoredProperly() below for an example filter.
62 class DownloadPersistedObserver : public DownloadHistory::Observer {
63 public:
64 typedef base::Callback<bool(
65 DownloadItem* item,
66 const history::DownloadRow&)> PersistedFilter;
68 DownloadPersistedObserver(Profile* profile, const PersistedFilter& filter)
69 : profile_(profile),
70 filter_(filter),
71 waiting_(false),
72 persisted_(false) {
73 DownloadServiceFactory::GetForBrowserContext(profile_)->
74 GetDownloadHistory()->AddObserver(this);
77 ~DownloadPersistedObserver() override {
78 DownloadService* service = DownloadServiceFactory::GetForBrowserContext(
79 profile_);
80 if (service && service->GetDownloadHistory())
81 service->GetDownloadHistory()->RemoveObserver(this);
84 bool WaitForPersisted() {
85 if (persisted_)
86 return true;
87 waiting_ = true;
88 content::RunMessageLoop();
89 waiting_ = false;
90 return persisted_;
93 void OnDownloadStored(DownloadItem* item,
94 const history::DownloadRow& info) override {
95 persisted_ = persisted_ || filter_.Run(item, info);
96 if (persisted_ && waiting_)
97 base::MessageLoopForUI::current()->Quit();
100 private:
101 Profile* profile_;
102 PersistedFilter filter_;
103 bool waiting_;
104 bool persisted_;
106 DISALLOW_COPY_AND_ASSIGN(DownloadPersistedObserver);
109 // Waits for an item record to be removed from the downloads database.
110 class DownloadRemovedObserver : public DownloadPersistedObserver {
111 public:
112 DownloadRemovedObserver(Profile* profile, int32 download_id)
113 : DownloadPersistedObserver(profile, PersistedFilter()),
114 removed_(false),
115 waiting_(false),
116 download_id_(download_id) {
118 ~DownloadRemovedObserver() override {}
120 bool WaitForRemoved() {
121 if (removed_)
122 return true;
123 waiting_ = true;
124 content::RunMessageLoop();
125 waiting_ = false;
126 return removed_;
129 void OnDownloadStored(DownloadItem* item,
130 const history::DownloadRow& info) override {}
132 void OnDownloadsRemoved(const DownloadHistory::IdSet& ids) override {
133 removed_ = ids.find(download_id_) != ids.end();
134 if (removed_ && waiting_)
135 base::MessageLoopForUI::current()->Quit();
138 private:
139 bool removed_;
140 bool waiting_;
141 int32 download_id_;
143 DISALLOW_COPY_AND_ASSIGN(DownloadRemovedObserver);
146 bool DownloadStoredProperly(
147 const GURL& expected_url,
148 const base::FilePath& expected_path,
149 int64 num_files,
150 history::DownloadState expected_state,
151 DownloadItem* item,
152 const history::DownloadRow& info) {
153 // This function may be called multiple times for a given test. Returning
154 // false doesn't necessarily mean that the test has failed or will fail, it
155 // might just mean that the test hasn't passed yet.
156 if (info.target_path != expected_path) {
157 DVLOG(20) << __FUNCTION__ << " " << info.target_path.value()
158 << " != " << expected_path.value();
159 return false;
161 if (info.url_chain.size() != 1u) {
162 DVLOG(20) << __FUNCTION__ << " " << info.url_chain.size()
163 << " != 1";
164 return false;
166 if (info.url_chain[0] != expected_url) {
167 DVLOG(20) << __FUNCTION__ << " " << info.url_chain[0].spec()
168 << " != " << expected_url.spec();
169 return false;
171 if ((num_files >= 0) && (info.received_bytes != num_files)) {
172 DVLOG(20) << __FUNCTION__ << " " << num_files
173 << " != " << info.received_bytes;
174 return false;
176 if (info.state != expected_state) {
177 DVLOG(20) << __FUNCTION__ << " " << info.state
178 << " != " << expected_state;
179 return false;
181 return true;
184 const base::FilePath::CharType kTestDir[] = FILE_PATH_LITERAL("save_page");
186 static const char kAppendedExtension[] = ".html";
188 // Loosely based on logic in DownloadTestObserver.
189 class DownloadItemCreatedObserver : public DownloadManager::Observer {
190 public:
191 explicit DownloadItemCreatedObserver(DownloadManager* manager)
192 : waiting_(false), manager_(manager) {
193 manager->AddObserver(this);
196 ~DownloadItemCreatedObserver() override {
197 if (manager_)
198 manager_->RemoveObserver(this);
201 // Wait for the first download item created after object creation.
202 // Note that this class provides no protection against the download
203 // being destroyed between creation and return of WaitForNewDownloadItem();
204 // the caller must guarantee that in some other fashion.
205 void WaitForDownloadItem(std::vector<DownloadItem*>* items_seen) {
206 if (!manager_) {
207 // The manager went away before we were asked to wait; return
208 // what we have, even if it's null.
209 *items_seen = items_seen_;
210 return;
213 if (items_seen_.empty()) {
214 waiting_ = true;
215 content::RunMessageLoop();
216 waiting_ = false;
219 *items_seen = items_seen_;
220 return;
223 private:
224 // DownloadManager::Observer
225 void OnDownloadCreated(DownloadManager* manager,
226 DownloadItem* item) override {
227 DCHECK_EQ(manager, manager_);
228 items_seen_.push_back(item);
230 if (waiting_)
231 base::MessageLoopForUI::current()->Quit();
234 void ManagerGoingDown(DownloadManager* manager) override {
235 manager_->RemoveObserver(this);
236 manager_ = NULL;
237 if (waiting_)
238 base::MessageLoopForUI::current()->Quit();
241 bool waiting_;
242 DownloadManager* manager_;
243 std::vector<DownloadItem*> items_seen_;
245 DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver);
248 class SavePackageFinishedObserver : public content::DownloadManager::Observer {
249 public:
250 SavePackageFinishedObserver(content::DownloadManager* manager,
251 const base::Closure& callback)
252 : download_manager_(manager),
253 callback_(callback) {
254 download_manager_->AddObserver(this);
257 ~SavePackageFinishedObserver() override {
258 if (download_manager_)
259 download_manager_->RemoveObserver(this);
262 // DownloadManager::Observer:
263 void OnSavePackageSuccessfullyFinished(content::DownloadManager* manager,
264 content::DownloadItem* item) override {
265 callback_.Run();
267 void ManagerGoingDown(content::DownloadManager* manager) override {
268 download_manager_->RemoveObserver(this);
269 download_manager_ = NULL;
272 private:
273 content::DownloadManager* download_manager_;
274 base::Closure callback_;
276 DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver);
279 class SavePageBrowserTest : public InProcessBrowserTest {
280 public:
281 SavePageBrowserTest() {}
283 protected:
284 void SetUp() override {
285 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
286 ASSERT_TRUE(save_dir_.CreateUniqueTempDir());
287 InProcessBrowserTest::SetUp();
290 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 void SaveCurrentTab(const GURL& url,
347 content::SavePageType save_page_type,
348 const std::string& prefix_for_output_files,
349 int expected_number_of_files,
350 base::FilePath* output_dir,
351 base::FilePath* main_file_name) {
352 GetDestinationPaths(prefix_for_output_files, main_file_name, output_dir);
353 DownloadPersistedObserver persisted(
354 browser()->profile(),
355 base::Bind(&DownloadStoredProperly, url, *main_file_name,
356 expected_number_of_files, history::DownloadState::COMPLETE));
357 base::RunLoop run_loop;
358 SavePackageFinishedObserver observer(
359 content::BrowserContext::GetDownloadManager(browser()->profile()),
360 run_loop.QuitClosure());
361 ASSERT_TRUE(GetCurrentTab(browser())
362 ->SavePage(*main_file_name, *output_dir, save_page_type));
363 run_loop.Run();
364 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
365 persisted.WaitForPersisted();
368 // Note on synchronization:
370 // For each Save Page As operation, we create a corresponding shell
371 // DownloadItem to display progress to the user. That DownloadItem goes
372 // through its own state transitions, including being persisted out to the
373 // history database, and the download shelf is not shown until after the
374 // persistence occurs. Save Package completion (and marking the DownloadItem
375 // as completed) occurs asynchronously from persistence. Thus if we want to
376 // examine either UI state or DB state, we need to wait until both the save
377 // package operation is complete and the relevant download item has been
378 // persisted.
380 DownloadManager* GetDownloadManager() const {
381 DownloadManager* download_manager =
382 BrowserContext::GetDownloadManager(browser()->profile());
383 EXPECT_TRUE(download_manager);
384 return download_manager;
387 // Path to directory containing test data.
388 base::FilePath test_dir_;
390 // Temporary directory we will save pages to.
391 base::ScopedTempDir save_dir_;
393 private:
394 DISALLOW_COPY_AND_ASSIGN(SavePageBrowserTest);
397 // Disabled on Windows due to flakiness. http://crbug.com/162323
398 #if defined(OS_WIN)
399 #define MAYBE_SaveHTMLOnly DISABLED_SaveHTMLOnly
400 #else
401 #define MAYBE_SaveHTMLOnly SaveHTMLOnly
402 #endif
403 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnly) {
404 GURL url = NavigateToMockURL("a");
406 base::FilePath full_file_name, dir;
407 SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir,
408 &full_file_name);
409 ASSERT_FALSE(HasFailure());
411 EXPECT_TRUE(base::PathExists(full_file_name));
412 EXPECT_FALSE(base::PathExists(dir));
413 EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
414 kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
417 // http://crbug.com/162323
418 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_SaveHTMLOnlyCancel) {
419 GURL url = NavigateToMockURL("a");
420 DownloadManager* manager(GetDownloadManager());
421 std::vector<DownloadItem*> downloads;
422 manager->GetAllDownloads(&downloads);
423 ASSERT_EQ(0u, downloads.size());
425 base::FilePath full_file_name, dir;
426 GetDestinationPaths("a", &full_file_name, &dir);
427 DownloadItemCreatedObserver creation_observer(manager);
428 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
429 &DownloadStoredProperly, url, full_file_name, -1,
430 history::DownloadState::CANCELLED));
431 // -1 to disable number of files check; we don't update after cancel, and
432 // we don't know when the single file completed in relationship to
433 // the cancel.
435 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
436 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
437 std::vector<DownloadItem*> items;
438 creation_observer.WaitForDownloadItem(&items);
439 ASSERT_EQ(1UL, items.size());
440 ASSERT_EQ(url.spec(), items[0]->GetOriginalUrl().spec());
441 items[0]->Cancel(true);
442 // TODO(rdsmith): Fix DII::Cancel() to actually cancel the save package.
443 // Currently it's ignored.
445 persisted.WaitForPersisted();
447 // TODO(benjhayden): Figure out how to safely wait for SavePackage's finished
448 // notification, then expect the contents of the downloaded file.
451 class DelayingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
452 public:
453 explicit DelayingDownloadManagerDelegate(Profile* profile)
454 : ChromeDownloadManagerDelegate(profile) {
456 ~DelayingDownloadManagerDelegate() override {}
458 bool ShouldCompleteDownload(
459 content::DownloadItem* item,
460 const base::Closure& user_complete_callback) override {
461 return false;
464 private:
465 DISALLOW_COPY_AND_ASSIGN(DelayingDownloadManagerDelegate);
468 // Disabled on Windows due to flakiness. http://crbug.com/162323
469 #if defined(OS_WIN)
470 #define MAYBE_SaveHTMLOnlyTabDestroy DISABLED_SaveHTMLOnlyTabDestroy
471 #else
472 #define MAYBE_SaveHTMLOnlyTabDestroy SaveHTMLOnlyTabDestroy
473 #endif
474 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnlyTabDestroy) {
475 GURL url = NavigateToMockURL("a");
476 scoped_ptr<DelayingDownloadManagerDelegate> delaying_delegate(
477 new DelayingDownloadManagerDelegate(browser()->profile()));
478 delaying_delegate->GetDownloadIdReceiverCallback().Run(
479 content::DownloadItem::kInvalidId + 1);
480 DownloadServiceFactory::GetForBrowserContext(browser()->profile())
481 ->SetDownloadManagerDelegateForTesting(delaying_delegate.Pass());
482 DownloadManager* manager(GetDownloadManager());
483 std::vector<DownloadItem*> downloads;
484 manager->GetAllDownloads(&downloads);
485 ASSERT_EQ(0u, downloads.size());
487 base::FilePath full_file_name, dir;
488 GetDestinationPaths("a", &full_file_name, &dir);
489 DownloadItemCreatedObserver creation_observer(manager);
490 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
491 content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
492 std::vector<DownloadItem*> items;
493 creation_observer.WaitForDownloadItem(&items);
494 ASSERT_TRUE(items.size() == 1);
496 // Close the tab; does this cancel the download?
497 GetCurrentTab(browser())->Close();
498 EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
500 EXPECT_FALSE(base::PathExists(full_file_name));
501 EXPECT_FALSE(base::PathExists(dir));
504 // Disabled on Windows due to flakiness. http://crbug.com/162323
505 #if defined(OS_WIN)
506 #define MAYBE_SaveViewSourceHTMLOnly DISABLED_SaveViewSourceHTMLOnly
507 #else
508 #define MAYBE_SaveViewSourceHTMLOnly SaveViewSourceHTMLOnly
509 #endif
510 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveViewSourceHTMLOnly) {
511 base::FilePath file_name(FILE_PATH_LITERAL("a.htm"));
512 GURL mock_url = URLRequestMockHTTPJob::GetMockUrl(
513 base::FilePath(kTestDir).Append(file_name));
514 GURL view_source_url =
515 GURL(content::kViewSourceScheme + std::string(":") + mock_url.spec());
516 GURL actual_page_url = URLRequestMockHTTPJob::GetMockUrl(
517 base::FilePath(kTestDir).Append(file_name));
518 ui_test_utils::NavigateToURL(browser(), view_source_url);
520 base::FilePath full_file_name, dir;
521 SaveCurrentTab(actual_page_url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1,
522 &dir, &full_file_name);
523 ASSERT_FALSE(HasFailure());
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, DISABLED_SaveCompleteHTML) {
539 GURL url = NavigateToMockURL("b");
541 base::FilePath full_file_name, dir;
542 SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, "b", 3, &dir,
543 &full_file_name);
544 ASSERT_FALSE(HasFailure());
546 EXPECT_TRUE(base::PathExists(full_file_name));
547 EXPECT_TRUE(base::PathExists(dir));
548 EXPECT_TRUE(base::TextContentsEqual(
549 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
550 full_file_name));
551 EXPECT_TRUE(base::ContentsEqual(
552 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
553 dir.AppendASCII("1.png")));
554 EXPECT_TRUE(base::ContentsEqual(
555 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
556 dir.AppendASCII("1.css")));
559 // Invoke a save page during the initial navigation.
560 // (Regression test for http://crbug.com/156538).
561 // Disabled on Windows due to flakiness. http://crbug.com/162323
562 #if defined(OS_WIN)
563 #define MAYBE_SaveDuringInitialNavigationIncognito DISABLED_SaveDuringInitialNavigationIncognito
564 #else
565 #define MAYBE_SaveDuringInitialNavigationIncognito SaveDuringInitialNavigationIncognito
566 #endif
567 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
568 MAYBE_SaveDuringInitialNavigationIncognito) {
569 // Open an Incognito window.
570 Browser* incognito = CreateIncognitoBrowser(); // Waits.
571 ASSERT_TRUE(incognito);
573 // Create a download item creation waiter on that window.
574 DownloadItemCreatedObserver creation_observer(
575 BrowserContext::GetDownloadManager(incognito->profile()));
577 // Navigate, unblocking with new tab.
578 GURL url = URLRequestMockHTTPJob::GetMockUrl(
579 base::FilePath(kTestDir).AppendASCII("b.htm"));
580 NavigateToURLWithDisposition(incognito, url, NEW_FOREGROUND_TAB,
581 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
583 // Save the page before completion.
584 base::FilePath full_file_name, dir;
585 GetDestinationPaths("b", &full_file_name, &dir);
586 scoped_refptr<content::MessageLoopRunner> loop_runner(
587 new content::MessageLoopRunner);
588 SavePackageFinishedObserver observer(
589 content::BrowserContext::GetDownloadManager(incognito->profile()),
590 loop_runner->QuitClosure());
591 ASSERT_TRUE(GetCurrentTab(incognito)->SavePage(
592 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
594 loop_runner->Run();
595 ASSERT_TRUE(VerifySavePackageExpectations(incognito, url));
597 // We can't check more than this because SavePackage is racing with
598 // the page load. If the page load won the race, then SavePackage
599 // might have completed. If the page load lost the race, then
600 // SavePackage will cancel because there aren't any resources to
601 // save.
604 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, NoSave) {
605 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
606 EXPECT_FALSE(chrome::CanSavePage(browser()));
609 // Disabled on Windows due to flakiness. http://crbug.com/162323
610 #if defined(OS_WIN)
611 #define MAYBE_FileNameFromPageTitle DISABLED_FileNameFromPageTitle
612 #else
613 #define MAYBE_FileNameFromPageTitle FileNameFromPageTitle
614 #endif
615 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_FileNameFromPageTitle) {
616 GURL url = NavigateToMockURL("b");
618 base::FilePath full_file_name = save_dir_.path().AppendASCII(
619 std::string("Test page for saving page feature") + kAppendedExtension);
620 base::FilePath dir = save_dir_.path().AppendASCII(
621 "Test page for saving page feature_files");
622 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
623 &DownloadStoredProperly, url, full_file_name, 3,
624 history::DownloadState::COMPLETE));
625 scoped_refptr<content::MessageLoopRunner> loop_runner(
626 new content::MessageLoopRunner);
627 SavePackageFinishedObserver observer(
628 content::BrowserContext::GetDownloadManager(browser()->profile()),
629 loop_runner->QuitClosure());
630 ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
631 full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
633 loop_runner->Run();
634 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
635 persisted.WaitForPersisted();
637 EXPECT_TRUE(base::PathExists(full_file_name));
638 EXPECT_TRUE(base::PathExists(dir));
639 EXPECT_TRUE(base::TextContentsEqual(
640 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
641 full_file_name));
642 EXPECT_TRUE(base::ContentsEqual(
643 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
644 dir.AppendASCII("1.png")));
645 EXPECT_TRUE(base::ContentsEqual(
646 test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
647 dir.AppendASCII("1.css")));
650 // Disabled on Windows due to flakiness. http://crbug.com/162323
651 #if defined(OS_WIN)
652 #define MAYBE_RemoveFromList DISABLED_RemoveFromList
653 #else
654 #define MAYBE_RemoveFromList RemoveFromList
655 #endif
656 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_RemoveFromList) {
657 GURL url = NavigateToMockURL("a");
659 base::FilePath full_file_name, dir;
660 SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir,
661 &full_file_name);
662 ASSERT_FALSE(HasFailure());
664 DownloadManager* manager(GetDownloadManager());
665 std::vector<DownloadItem*> downloads;
666 manager->GetAllDownloads(&downloads);
667 ASSERT_EQ(1UL, downloads.size());
668 DownloadRemovedObserver removed(browser()->profile(), downloads[0]->GetId());
670 EXPECT_EQ(manager->RemoveAllDownloads(), 1);
672 removed.WaitForRemoved();
674 EXPECT_TRUE(base::PathExists(full_file_name));
675 EXPECT_FALSE(base::PathExists(dir));
676 EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
677 kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
680 // This tests that a webpage with the title "test.exe" is saved as
681 // "test.exe.htm".
682 // We probably don't care to handle this on Linux or Mac.
683 #if defined(OS_WIN)
684 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, CleanFilenameFromPageTitle) {
685 const base::FilePath file_name(FILE_PATH_LITERAL("c.htm"));
686 base::FilePath download_dir =
687 DownloadPrefs::FromDownloadManager(GetDownloadManager())->
688 DownloadPath();
689 base::FilePath full_file_name =
690 download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension);
691 base::FilePath dir = download_dir.AppendASCII("test.exe_files");
693 EXPECT_FALSE(base::PathExists(full_file_name));
694 GURL url = URLRequestMockHTTPJob::GetMockUrl(
695 base::FilePath(kTestDir).Append(file_name));
696 ui_test_utils::NavigateToURL(browser(), url);
698 SavePackageFilePicker::SetShouldPromptUser(false);
699 scoped_refptr<content::MessageLoopRunner> loop_runner(
700 new content::MessageLoopRunner);
701 SavePackageFinishedObserver observer(
702 content::BrowserContext::GetDownloadManager(browser()->profile()),
703 loop_runner->QuitClosure());
704 chrome::SavePage(browser());
705 loop_runner->Run();
707 EXPECT_TRUE(base::PathExists(full_file_name));
709 EXPECT_TRUE(base::DieFileDie(full_file_name, false));
710 EXPECT_TRUE(base::DieFileDie(dir, true));
712 #endif
714 class SavePageAsMHTMLBrowserTest : public SavePageBrowserTest {
715 public:
716 SavePageAsMHTMLBrowserTest() {}
717 ~SavePageAsMHTMLBrowserTest() override;
718 void SetUpCommandLine(base::CommandLine* command_line) override {
719 command_line->AppendSwitch(switches::kSavePageAsMHTML);
722 private:
723 DISALLOW_COPY_AND_ASSIGN(SavePageAsMHTMLBrowserTest);
726 SavePageAsMHTMLBrowserTest::~SavePageAsMHTMLBrowserTest() {
729 IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
730 static const int64 kFileSizeMin = 2758;
731 GURL url = NavigateToMockURL("b");
732 base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
733 GetDownloadManager())->DownloadPath();
734 base::FilePath full_file_name = download_dir.AppendASCII(std::string(
735 "Test page for saving page feature.mhtml"));
736 SavePackageFilePicker::SetShouldPromptUser(false);
737 DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
738 &DownloadStoredProperly, url, full_file_name, -1,
739 history::DownloadState::COMPLETE));
740 scoped_refptr<content::MessageLoopRunner> loop_runner(
741 new content::MessageLoopRunner);
742 SavePackageFinishedObserver observer(
743 content::BrowserContext::GetDownloadManager(browser()->profile()),
744 loop_runner->QuitClosure());
745 chrome::SavePage(browser());
746 loop_runner->Run();
747 ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
748 persisted.WaitForPersisted();
750 ASSERT_TRUE(base::PathExists(full_file_name));
751 int64 actual_file_size = -1;
752 EXPECT_TRUE(base::GetFileSize(full_file_name, &actual_file_size));
753 EXPECT_LE(kFileSizeMin, actual_file_size);
756 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SavePageBrowserTest_NonMHTML) {
757 SavePackageFilePicker::SetShouldPromptUser(false);
758 GURL url("data:text/plain,foo");
759 ui_test_utils::NavigateToURL(browser(), url);
760 scoped_refptr<content::MessageLoopRunner> loop_runner(
761 new content::MessageLoopRunner);
762 SavePackageFinishedObserver observer(
763 content::BrowserContext::GetDownloadManager(browser()->profile()),
764 loop_runner->QuitClosure());
765 chrome::SavePage(browser());
766 loop_runner->Run();
767 base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
768 GetDownloadManager())->DownloadPath();
769 base::FilePath filename = download_dir.AppendASCII("dataurl.txt");
770 ASSERT_TRUE(base::PathExists(filename));
771 std::string contents;
772 EXPECT_TRUE(base::ReadFileToString(filename, &contents));
773 EXPECT_EQ("foo", contents);
776 class SavePageSitePerProcessBrowserTest : public SavePageBrowserTest {
777 public:
778 SavePageSitePerProcessBrowserTest() {}
780 protected:
781 void SetUpCommandLine(base::CommandLine* command_line) override {
782 SavePageBrowserTest::SetUpCommandLine(command_line);
784 // TODO(lukasza): Enable --site-per-process once crbug.com/526786 is fixed.
785 // (currently, when the line below is uncommented out, the test crashes
786 // under RenderViewImpl::OnGetAllSavableResourceLinksForCurrentPage).
787 // content::IsolateAllSitesForTesting(command_line);
790 void SetUpOnMainThread() override {
791 SavePageBrowserTest::SetUpOnMainThread();
793 host_resolver()->AddRule("*", "127.0.0.1");
794 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
795 content::SetupCrossSiteRedirector(embedded_test_server());
798 private:
799 DISALLOW_COPY_AND_ASSIGN(SavePageSitePerProcessBrowserTest);
802 // Test for crbug.com/526786. Without OOPIFs fixes, the test will trigger
803 // a crash in the renderer process.
804 IN_PROC_BROWSER_TEST_F(SavePageSitePerProcessBrowserTest, SaveCrossSitePage) {
805 // TODO(lukasza): Remove this check once crbug.com/526786 is fixed.
806 if (content::AreAllSitesIsolatedForTesting()) {
807 LOG(WARNING) << "Skipping the test.";
808 return; // Avoid failing on Site Isolation FYI bot.
811 GURL url(embedded_test_server()->GetURL(
812 "a.com", "/frame_tree/page_with_two_frames_remote_and_local.html"));
813 ui_test_utils::NavigateToURL(browser(), url);
815 base::FilePath full_file_name, dir;
816 SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, "xsite1", 3,
817 &dir, &full_file_name);
818 ASSERT_FALSE(HasFailure());
820 EXPECT_TRUE(base::DirectoryExists(dir));
821 base::FilePath expected_files[] = {
822 full_file_name, dir.AppendASCII("title1.html"),
823 dir.AppendASCII("title1(1).html"),
825 for (auto file_path : expected_files) {
826 EXPECT_TRUE(base::PathExists(file_path)) << "Does " << file_path.value()
827 << " exist?";
828 int64 actual_file_size = 0;
829 EXPECT_TRUE(base::GetFileSize(file_path, &actual_file_size));
830 EXPECT_NE(0, actual_file_size) << "Is " << file_path.value()
831 << " non-empty?";
835 } // namespace