OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <fstream> | 6 #include <fstream> |
7 #include <iostream> | 7 #include <iostream> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <limits> | 9 #include <limits> |
10 #include <string> | 10 #include <string> |
11 #include <utility> | 11 #include <utility> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/bind.h" | |
15 #include "base/callback.h" | |
14 #include "base/file_util.h" | 16 #include "base/file_util.h" |
15 #include "base/files/file.h" | 17 #include "base/files/file.h" |
16 #include "base/files/file_path.h" | 18 #include "base/files/file_path.h" |
17 #include "base/files/scoped_temp_dir.h" | 19 #include "base/files/scoped_temp_dir.h" |
18 #include "base/logging.h" | 20 #include "base/logging.h" |
19 #include "base/md5.h" | 21 #include "base/md5.h" |
20 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
21 #include "base/path_service.h" | 23 #include "base/path_service.h" |
22 #include "base/run_loop.h" | 24 #include "base/run_loop.h" |
23 #include "base/scoped_native_library.h" | 25 #include "base/scoped_native_library.h" |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 bool background_colors_and_images; | 102 bool background_colors_and_images; |
101 MarginType margins; | 103 MarginType margins; |
102 bool source_is_pdf; | 104 bool source_is_pdf; |
103 }; | 105 }; |
104 | 106 |
105 // Observes the print preview webpage. Once it observes the PreviewPageCount | 107 // Observes the print preview webpage. Once it observes the PreviewPageCount |
106 // message, will send a sequence of commands to the print preview dialog and | 108 // message, will send a sequence of commands to the print preview dialog and |
107 // change the settings of the preview dialog. | 109 // change the settings of the preview dialog. |
108 class PrintPreviewObserver : public WebContentsObserver { | 110 class PrintPreviewObserver : public WebContentsObserver { |
109 public: | 111 public: |
110 PrintPreviewObserver(Browser* browser, WebContents* dialog) | 112 PrintPreviewObserver(Browser* browser, |
113 WebContents* dialog, | |
114 const base::FilePath& pdf_file_save_path) | |
111 : WebContentsObserver(dialog), | 115 : WebContentsObserver(dialog), |
112 browser_(browser), | 116 browser_(browser), |
113 state_(kWaitingToSendSaveAsPdf), | 117 state_(kWaitingToSendSaveAsPdf), |
114 failed_setting_("None") {} | 118 failed_setting_("None"), |
119 pdf_file_save_path_(pdf_file_save_path) {} | |
115 | 120 |
116 virtual ~PrintPreviewObserver() {} | 121 virtual ~PrintPreviewObserver() {} |
117 | 122 |
118 // Sets closure for the observer so that it can end the loop. | 123 // Sets closure for the observer so that it can end the loop. |
119 void set_quit_closure(const base::Closure &closure) { | 124 void set_quit_closure(const base::Closure &closure) { |
120 quit_closure_ = closure; | 125 quit_closure_ = closure; |
121 } | 126 } |
122 | 127 |
123 // Actually stops the message loop so that the test can proceed. | 128 // Actually stops the message loop so that the test can proceed. |
124 void EndLoop() { | 129 void EndLoop() { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 } else if (state_ == kWaitingToSendBackgroundColorsAndImages) { | 182 } else if (state_ == kWaitingToSendBackgroundColorsAndImages) { |
178 script_argument.SetBoolean("backgroundColorsAndImages", | 183 script_argument.SetBoolean("backgroundColorsAndImages", |
179 settings_->background_colors_and_images); | 184 settings_->background_colors_and_images); |
180 state_ = kWaitingToSendMargins; | 185 state_ = kWaitingToSendMargins; |
181 failed_setting_ = "Background Colors and Images"; | 186 failed_setting_ = "Background Colors and Images"; |
182 } else if (state_ == kWaitingToSendMargins) { | 187 } else if (state_ == kWaitingToSendMargins) { |
183 script_argument.SetInteger("margins", settings_->margins); | 188 script_argument.SetInteger("margins", settings_->margins); |
184 state_ = kWaitingForFinalMessage; | 189 state_ = kWaitingForFinalMessage; |
185 failed_setting_ = "Margins"; | 190 failed_setting_ = "Margins"; |
186 } else if (state_ == kWaitingForFinalMessage) { | 191 } else if (state_ == kWaitingForFinalMessage) { |
187 EndLoop(); | 192 // Called by PrintPreviewMessageHandler when the PDF is saved. This ends |
193 // the message loop for |this|. | |
194 base::Closure end_loop_callback = | |
195 base::Bind(&PrintPreviewObserver::EndLoop, base::Unretained(this)); | |
196 GetUI()->SetPdfSavedCallbackForTesting(end_loop_callback); | |
197 GetUI()->SetSelectedFileForTesting(pdf_file_save_path_); | |
188 return; | 198 return; |
189 } | 199 } |
190 | 200 |
191 ASSERT_FALSE(script_argument.empty()); | 201 ASSERT_FALSE(script_argument.empty()); |
192 GetUI()->web_ui()->CallJavascriptFunction( | 202 GetUI()->web_ui()->CallJavascriptFunction( |
193 "onManipulateSettingsForTest", script_argument); | 203 "onManipulateSettingsForTest", script_argument); |
194 } | 204 } |
195 | 205 |
196 // Saves the print preview settings to be sent to the print preview dialog. | 206 // Saves the print preview settings to be sent to the print preview dialog. |
197 void SetPrintPreviewSettings(const PrintPreviewSettings& settings) { | 207 void SetPrintPreviewSettings(const PrintPreviewSettings& settings) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 ui->web_ui()->AddMessageHandler(new UIDoneLoadingMessageHandler(this)); | 275 ui->web_ui()->AddMessageHandler(new UIDoneLoadingMessageHandler(this)); |
266 ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest"); | 276 ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest"); |
267 } | 277 } |
268 | 278 |
269 virtual void DidCloneToNewWebContents( | 279 virtual void DidCloneToNewWebContents( |
270 WebContents* old_web_contents, | 280 WebContents* old_web_contents, |
271 WebContents* new_web_contents) OVERRIDE { | 281 WebContents* new_web_contents) OVERRIDE { |
272 Observe(new_web_contents); | 282 Observe(new_web_contents); |
273 } | 283 } |
274 | 284 |
275 virtual void WebContentsDestroyed() OVERRIDE { | |
276 EndLoop(); | |
277 } | |
278 | |
279 Browser* browser_; | 285 Browser* browser_; |
280 base::Closure quit_closure_; | 286 base::Closure quit_closure_; |
281 scoped_ptr<PrintPreviewSettings> settings_; | 287 scoped_ptr<PrintPreviewSettings> settings_; |
282 | 288 |
283 // State of the observer. The state indicates what message to send | 289 // State of the observer. The state indicates what message to send |
284 // next. The state advances whenever the message handler calls | 290 // next. The state advances whenever the message handler calls |
285 // ManipulatePreviewSettings() on the observer. | 291 // ManipulatePreviewSettings() on the observer. |
286 State state_; | 292 State state_; |
287 std::string failed_setting_; | 293 std::string failed_setting_; |
294 base::FilePath pdf_file_save_path_; | |
288 | 295 |
289 DISALLOW_COPY_AND_ASSIGN(PrintPreviewObserver); | 296 DISALLOW_COPY_AND_ASSIGN(PrintPreviewObserver); |
290 }; | 297 }; |
291 | 298 |
292 class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest { | 299 class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest { |
293 public: | 300 public: |
294 PrintPreviewPdfGeneratedBrowserTest() {} | 301 PrintPreviewPdfGeneratedBrowserTest() {} |
295 virtual ~PrintPreviewPdfGeneratedBrowserTest() {} | 302 virtual ~PrintPreviewPdfGeneratedBrowserTest() {} |
296 | 303 |
297 // Navigates to the given web page, then initiates print preview and waits | 304 // Navigates to the given web page, then initiates print preview and waits |
298 // for all the settings to be set. | 305 // for all the settings to be set, then the webpage is printed to a PDF. |
Lei Zhang
2014/07/22 03:04:39
... then save the preview to PDF.
ivandavid
2014/07/22 19:02:00
Done.
| |
299 void NavigateAndPreview(const base::FilePath::StringType& file_name, | 306 void NavigateAndPrint(const base::FilePath::StringType& file_name, |
300 const PrintPreviewSettings& settings) { | 307 const PrintPreviewSettings& settings) { |
301 print_preview_observer_->SetPrintPreviewSettings(settings); | 308 print_preview_observer_->SetPrintPreviewSettings(settings); |
302 base::FilePath path(file_name); | 309 base::FilePath path(file_name); |
303 GURL gurl = net::FilePathToFileURL(path); | 310 GURL gurl = net::FilePathToFileURL(path); |
304 | 311 |
305 ui_test_utils::NavigateToURL(browser(), gurl); | 312 ui_test_utils::NavigateToURL(browser(), gurl); |
306 | 313 |
307 base::RunLoop loop; | 314 base::RunLoop loop; |
308 print_preview_observer_->set_quit_closure(loop.QuitClosure()); | 315 print_preview_observer_->set_quit_closure(loop.QuitClosure()); |
309 chrome::Print(browser()); | 316 chrome::Print(browser()); |
310 loop.Run(); | 317 loop.Run(); |
311 } | 318 } |
312 | 319 |
313 // Prints the web page to a PDF. NavigateAndPreview must be called first. | |
314 void Print() { | |
315 ASSERT_FALSE(pdf_file_save_path_.empty()); | |
316 | |
317 base::RunLoop loop; | |
318 print_preview_observer_->set_quit_closure(loop.QuitClosure()); | |
319 print_preview_observer_->GetUI()->SetSelectedFileForTesting( | |
320 pdf_file_save_path_); | |
321 loop.Run(); | |
322 | |
323 // Checks to see if the file exists and is readable. If the file doesn't | |
324 // exist, the test will fail. If it exists, but isn't readable, the test | |
325 // will keep polling until the file becomes readable. This is due to a | |
326 // problem on Windows where the file exists, but isn't readable, causing | |
327 // other ASSERT statements in this test to fail. | |
328 // TODO(ivandavid): Come up with a better way to do this. | |
329 ASSERT_TRUE(base::PathExists(pdf_file_save_path_)); | |
330 while (true) { | |
331 base::File pdf_file( | |
332 pdf_file_save_path_, base::File::FLAG_OPEN | base::File::FLAG_READ); | |
333 if (pdf_file.IsValid()) | |
334 break; | |
335 } | |
336 } | |
337 | |
338 // Initializes function pointers from the PDF library. Called once when the | 320 // Initializes function pointers from the PDF library. Called once when the |
339 // test starts. The library is closed when the browser test ends. | 321 // test starts. The library is closed when the browser test ends. |
340 void InitPdfFunctions() { | 322 void InitPdfFunctions() { |
341 base::FilePath pdf_module_path; | 323 base::FilePath pdf_module_path; |
342 | 324 |
343 ASSERT_TRUE(PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path)); | 325 ASSERT_TRUE(PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path)); |
344 ASSERT_TRUE(base::PathExists(pdf_module_path)); | 326 ASSERT_TRUE(base::PathExists(pdf_module_path)); |
345 pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); | 327 pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); |
346 | 328 |
347 ASSERT_TRUE(pdf_lib_.is_valid()); | 329 ASSERT_TRUE(pdf_lib_.is_valid()); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 } | 470 } |
489 | 471 |
490 // Duplicates the tab that was created when the browser opened. This is done | 472 // Duplicates the tab that was created when the browser opened. This is done |
491 // so that the observer can listen to the duplicated tab as soon as possible | 473 // so that the observer can listen to the duplicated tab as soon as possible |
492 // and start listening for messages related to print preview. | 474 // and start listening for messages related to print preview. |
493 void DuplicateTab() { | 475 void DuplicateTab() { |
494 WebContents* tab = | 476 WebContents* tab = |
495 browser()->tab_strip_model()->GetActiveWebContents(); | 477 browser()->tab_strip_model()->GetActiveWebContents(); |
496 ASSERT_TRUE(tab); | 478 ASSERT_TRUE(tab); |
497 | 479 |
498 print_preview_observer_.reset(new PrintPreviewObserver(browser(), tab)); | 480 print_preview_observer_.reset( |
481 new PrintPreviewObserver(browser(), tab, pdf_file_save_path_)); | |
499 chrome::DuplicateTab(browser()); | 482 chrome::DuplicateTab(browser()); |
500 | 483 |
501 WebContents* initiator = | 484 WebContents* initiator = |
502 browser()->tab_strip_model()->GetActiveWebContents(); | 485 browser()->tab_strip_model()->GetActiveWebContents(); |
503 ASSERT_TRUE(initiator); | 486 ASSERT_TRUE(initiator); |
504 ASSERT_NE(tab, initiator); | 487 ASSERT_NE(tab, initiator); |
505 } | 488 } |
506 | 489 |
507 // Resets the test so that another web page can be printed. It also deletes | 490 // Resets the test so that another web page can be printed. It also deletes |
508 // the duplicated tab as it isn't needed anymore. | 491 // the duplicated tab as it isn't needed anymore. |
(...skipping 28 matching lines...) Expand all Loading... | |
537 | 520 |
538 // Redirects |std::cin| to the file |stdin_path|. |in| is not freed because | 521 // Redirects |std::cin| to the file |stdin_path|. |in| is not freed because |
539 // if it goes out of scope, |std::cin.rdbuf| will be freed, causing an | 522 // if it goes out of scope, |std::cin.rdbuf| will be freed, causing an |
540 // error. | 523 // error. |
541 std::ifstream* in = new std::ifstream(stdin_path.value().c_str()); | 524 std::ifstream* in = new std::ifstream(stdin_path.value().c_str()); |
542 ASSERT_TRUE(in->is_open()); | 525 ASSERT_TRUE(in->is_open()); |
543 std::cin.rdbuf(in->rdbuf()); | 526 std::cin.rdbuf(in->rdbuf()); |
544 | 527 |
545 pdf_file_save_path_ = | 528 pdf_file_save_path_ = |
546 tmp_dir_.path().Append(FILE_PATH_LITERAL("dummy.pdf")); | 529 tmp_dir_.path().Append(FILE_PATH_LITERAL("dummy.pdf")); |
530 ASSERT_FALSE(pdf_file_save_path_.empty()); | |
Lei Zhang
2014/07/22 03:04:39
This can't be false, you just appended to it one l
ivandavid
2014/07/22 19:02:00
Done.
ivandavid
2014/07/22 19:02:00
I moved this to ManipulatePreviewSettings() when |
| |
547 | 531 |
548 // Send the file path to the layout test framework so that it can | 532 // Send the file path to the layout test framework so that it can |
549 // communicate with this browser test. | 533 // communicate with this browser test. |
550 std::cout << "StdinPath: " << stdin_path.value() << "\n"; | 534 std::cout << "StdinPath: " << stdin_path.value() << "\n"; |
551 std::cout << "#EOF\n"; | 535 std::cout << "#EOF\n"; |
552 std::cout.flush(); | 536 std::cout.flush(); |
553 } | 537 } |
554 | 538 |
555 private: | 539 private: |
556 // Generates a png from bitmap data and stores it in |png_output_|. | 540 // Generates a png from bitmap data and stores it in |png_output_|. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 cmd.find(file_extension) != base::FilePath::StringType::npos); | 675 cmd.find(file_extension) != base::FilePath::StringType::npos); |
692 | 676 |
693 // Splits the command sent by the layout test framework. The first command | 677 // Splits the command sent by the layout test framework. The first command |
694 // is always the file path to use for the test. The rest isn't relevant, | 678 // is always the file path to use for the test. The rest isn't relevant, |
695 // so it can be ignored. The separator for the commands is an apostrophe. | 679 // so it can be ignored. The separator for the commands is an apostrophe. |
696 std::vector<base::FilePath::StringType> cmd_arguments; | 680 std::vector<base::FilePath::StringType> cmd_arguments; |
697 base::SplitString(cmd, '\'', &cmd_arguments); | 681 base::SplitString(cmd, '\'', &cmd_arguments); |
698 | 682 |
699 ASSERT_GE(cmd_arguments.size(), 1U); | 683 ASSERT_GE(cmd_arguments.size(), 1U); |
700 base::FilePath::StringType test_name(cmd_arguments[0]); | 684 base::FilePath::StringType test_name(cmd_arguments[0]); |
701 NavigateAndPreview(test_name, settings); | 685 NavigateAndPrint(test_name, settings); |
702 Print(); | |
703 PdfToPng(); | 686 PdfToPng(); |
704 | 687 |
705 // Message to the layout test framework indicating that it should start | 688 // Message to the layout test framework indicating that it should start |
706 // waiting for the image data, as there is no more text data to be read. | 689 // waiting for the image data, as there is no more text data to be read. |
707 // There actually isn't any text data at all, however because the layout | 690 // There actually isn't any text data at all, however because the layout |
708 // test framework requires it, a message has to be sent to stop it from | 691 // test framework requires it, a message has to be sent to stop it from |
709 // waiting for this message and start waiting for the image data. | 692 // waiting for this message and start waiting for the image data. |
710 std::cout << "#EOF\n"; | 693 std::cout << "#EOF\n"; |
711 std::cout.flush(); | 694 std::cout.flush(); |
712 | 695 |
713 SendPng(); | 696 SendPng(); |
714 Reset(); | 697 Reset(); |
715 } | 698 } |
716 } | 699 } |
717 | 700 |
718 } // namespace printing | 701 } // namespace printing |
OLD | NEW |