Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1049)

Side by Side Diff: chrome/browser/printing/print_preview_pdf_generated_browsertest.cc

Issue 335583004: Added a test that currently is able to print to pdf. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed IPC_MESSAGE_UNHANDLED. Fixed style and spacing issues. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/resources/print_preview/native_layer.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <cstdio>
6 #include <iostream>
7 #include <iterator>
8 #include <limits>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/file_util.h"
14 #include "base/files/file.h"
15 #include "base/files/file_path.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/format_macros.h"
18 #include "base/logging.h"
19 #include "base/md5.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/numerics/safe_conversions.h"
22 #include "base/path_service.h"
23 #include "base/run_loop.h"
24 #include "base/scoped_native_library.h"
25 #include "base/strings/string16.h"
26 #include "base/strings/string_split.h"
27 #include "base/strings/string_util.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "chrome/app/chrome_command_ids.h"
30 #include "chrome/browser/net/referrer.h"
31 #include "chrome/browser/printing/print_preview_dialog_controller.h"
32 #include "chrome/browser/profiles/profile.h"
33 #include "chrome/browser/ui/browser.h"
34 #include "chrome/browser/ui/browser_commands.h"
35 #include "chrome/browser/ui/tabs/tab_strip_model.h"
36 #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h"
37 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
38 #include "chrome/browser/ui/webui/print_preview/sticky_settings.h"
39 #include "chrome/common/chrome_paths.h"
40 #include "chrome/common/print_messages.h"
41 #include "chrome/common/url_constants.h"
42 #include "chrome/test/base/in_process_browser_test.h"
43 #include "chrome/test/base/ui_test_utils.h"
44 #include "content/public/browser/web_contents.h"
45 #include "content/public/browser/web_ui_message_handler.h"
46 #include "content/public/common/page_transition_types.h"
47 #include "content/public/test/browser_test_utils.h"
48 #include "content/public/test/test_navigation_observer.h"
49 #include "content/public/test/test_utils.h"
50 #include "net/base/filename_util.h"
51 #include "printing/pdf_render_settings.h"
52 #include "printing/units.h"
53 #include "ui/events/keycodes/keyboard_codes.h"
54 #include "ui/gfx/codec/png_codec.h"
55 #include "ui/gfx/geometry/rect.h"
56 #include "url/gurl.h"
57 #include "ipc/ipc_message_macros.h"
58
59 #if defined(OS_POSIX)
60 #define STDIN_STREAM std::cin
61 #elif defined(OS_WIN)
62 #define STDIN_STREAM std::wcin
63 #endif
64
65 using content::WebContents;
66 using content::WebContentsObserver;
67
68 // Number of color channels in a BGRA bitmap.
69 const int kColorChannels = 4;
70
71 // Message refers to the 'UILoaded' message from print_preview.js.
72 // It gets sent either from onPreviewGenerationDone or from
73 // onManipulateSettings_() in print_preview.js
74 enum State {
75 // Waiting for the first message so the program can select Save as PDF
76 kWaitingToSendSaveAsPdf = 0,
77 // Waiting for the second message so the test can set the layout
78 kWaitingToSendLayoutSettings = 1,
79 // Waiting for the third message so the test can set the page numbers
80 kWaitingToSendPageNumbers = 2,
81 // Waiting for the forth message so the test can set the headers checkbox
82 kWaitingToSendHeadersAndFooters = 3,
83 // Waiting for the fifth message so the test can set the background checkbox
84 kWaitingToSendBackgroundColorsAndImages = 4,
85 // Waiting for the sixth message so the test can set the margins combobox
86 kWaitingToSendMargins = 5,
87 // Waiting for the final message so the program can save to PDF.
88 kWaitingForFinalMessage = 6,
89 };
90
91 // Settings for print preview. It reflects the current options provided by
92 // print preview. If more options are added, more states should be added and
93 // there should be more settings added to this struct.
94 struct PrintPreviewSettings {
95 PrintPreviewSettings(bool is_portrait,
96 std::string page_numbers,
97 bool headers_and_footers,
98 bool background_colors_and_images,
99 printing::MarginType margins,
100 bool is_already_pdf)
101 : is_portrait(is_portrait),
102 page_numbers(page_numbers),
103 headers_and_footers(headers_and_footers),
104 background_colors_and_images(background_colors_and_images),
105 margins(margins),
106 is_already_pdf(is_already_pdf) {}
107
108 bool is_portrait;
109 std::string page_numbers;
110 bool headers_and_footers;
111 bool background_colors_and_images;
112 printing::MarginType margins;
113 bool is_already_pdf;
114 };
115
116 // Observes the print preview webpage. Once it observes the PreviewPageCount
117 // message, will send a sequence of commands to the print preview dialog and
118 // change the settings of the preview dialog.
119 class PrintPreviewObserver : public WebContentsObserver {
120 public:
121 PrintPreviewObserver(WebContents* dialog, Browser* browser)
122 : WebContentsObserver(dialog),
123 browser_(browser),
124 state_(kWaitingToSendSaveAsPdf) {}
125
126 virtual ~PrintPreviewObserver() {}
127
128 // Sets closure for the observer so that it can end the loop.
129 void set_quit_closure(const base::Closure &closure) {
130 closure_ = closure;
131 }
132
133 // Actually stops the message_loop so that the test can proceed.
134 void EndLoop() {
135 base::MessageLoop::current()->PostTask(FROM_HERE, closure_);
136 }
137
138 // This method must always return false. If it ever returns true, it will
139 // cause the test to hang. This is because the PrintPreviewMessageHandler
140 // should still handle all of the messages to progress the print preview
141 // process.
142 bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
143 IPC_BEGIN_MESSAGE_MAP(PrintPreviewObserver, message)
144 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
145 OnDidGetPreviewPageCount)
146 IPC_END_MESSAGE_MAP();
147 return false;
148 }
149
150 // Gets the web contents for the print preview dialog so that the UI and
151 // other elements can be accessed.
152 WebContents* GetDialog() {
153 WebContents* tab = browser_->tab_strip_model()->GetActiveWebContents();
154 printing::PrintPreviewDialogController* dialog_controller =
155 printing::PrintPreviewDialogController::GetInstance();
156 WebContents* web_contents =
157 dialog_controller->GetPrintPreviewForContents(tab);
158 return web_contents;
159 }
160
161 // Gets the PrintPreviewUI so that certain elements can be accessed.
162 PrintPreviewUI* GetUI() {
163 return static_cast<PrintPreviewUI*>(
164 GetDialog()->GetWebUI()->GetController());
165 }
166
167 // Calls a javascript function that will change the print preview settings,
168 // such as the layout, the margins, page numbers, etc.
169 void ManipulatePreviewSettings() {
170 base::DictionaryValue script_argument;
171
172 if (state_ == kWaitingToSendSaveAsPdf) {
173 script_argument.SetBoolean("selectSaveAsPdfDestination", true);
174 state_ = settings_->is_already_pdf ?
175 kWaitingToSendPageNumbers : kWaitingToSendLayoutSettings;
176 } else if (state_ == kWaitingToSendLayoutSettings) {
177 script_argument.SetBoolean("layoutSettings.portrait",
178 settings_->is_portrait);
179 state_ = kWaitingToSendPageNumbers;
180 } else if (state_ == kWaitingToSendPageNumbers) {
181 script_argument.SetString("pageRange", settings_->page_numbers);
182 state_ = settings_->is_already_pdf ?
183 kWaitingForFinalMessage : kWaitingToSendHeadersAndFooters;
184 } else if (state_ == kWaitingToSendHeadersAndFooters) {
185 script_argument.SetBoolean("headersAndFooters",
186 settings_->headers_and_footers);
187 state_ = kWaitingToSendBackgroundColorsAndImages;
188 } else if (state_ == kWaitingToSendBackgroundColorsAndImages) {
189 script_argument.SetBoolean("backgroundColorsAndImages",
190 settings_->background_colors_and_images);
191 state_ = kWaitingToSendMargins;
192 } else if (state_ == kWaitingToSendMargins) {
193 script_argument.SetInteger("margins", settings_->margins);
194 state_ = kWaitingForFinalMessage;
195 } else if (state_ == kWaitingForFinalMessage) {
196 EndLoop();
197 return;
198 }
199
200 ASSERT_TRUE(!script_argument.empty());
201 GetUI()->web_ui()->CallJavascriptFunction(
202 "onManipulateSettingsForTest", script_argument);
203 }
204
205 // Function to set the print preview settings and save them so they
206 // can be sent later. Currently only used in the constructor. Will be
207 // used when creating a test and take command line arguments.
208 // |page_numbers| is a comma separated page range.
209 // Example: "1-5,9" will print pages 1 through 5 and page 9. The pages
210 // specified must be less than or equal to the maximum page number. An
211 // empty string seems to be valid input, however further testing will be
212 // required to see if that is actually true.
213 void SetPrintPreviewSettings(const PrintPreviewSettings& settings) {
214 settings_.reset(new PrintPreviewSettings(settings));
215 }
216
217 private:
218 // Listens for messages from the print preview dialog. Specifically, it
219 // listens for 'UILoadedForTest' and 'UIFailedLoadingForTest.'
220 class UIDoneLoadingMessageHandler : public content::WebUIMessageHandler {
221 public:
222 explicit UIDoneLoadingMessageHandler(PrintPreviewObserver* observer)
223 : observer_(observer) {}
224
225 virtual ~UIDoneLoadingMessageHandler() {}
226
227 // When a setting has been set succesfully, this is called and the observer
228 // is told to send the next setting to be set.
229 void HandleDone(const base::ListValue* /* args */) {
230 ASSERT_TRUE(observer_);
231 observer_->ManipulatePreviewSettings();
232 }
233
234 // Ends the test because a setting was not set successfully therefore, the
235 // test shouldn't continue.
236 // TODO(ivandavid): Print out error message to give context.
237 void HandleFailure(const base::ListValue* /* args */) {
238 FAIL();
239 }
240
241 // Sets up this class to listen for the UILoadedForTest and
242 // UIFailedLoadingForTest messages. These messages are sent by
243 // print_preview.js. On UILoadedForTest, a settings has been successfully
244 // set and its effects on the pdf have been finalized. On
245 // UIFailedLoadingForTest a setting has not been successfully set and the
246 // test should fail.
247 void RegisterMessages() OVERRIDE {
248 web_ui()->RegisterMessageCallback(
249 "UILoadedForTest",
250 base::Bind(&UIDoneLoadingMessageHandler::HandleDone,
251 base::Unretained(this)));
252
253 web_ui()->RegisterMessageCallback(
254 "UIFailedLoadingForTest",
255 base::Bind(&UIDoneLoadingMessageHandler::HandleFailure,
256 base::Unretained(this)));
257 }
258
259 private:
260 PrintPreviewObserver* observer_;
261
262 DISALLOW_COPY_AND_ASSIGN(UIDoneLoadingMessageHandler);
263 };
264
265 // Called when the observer gets the IPC message stating that the page count
266 // is ready. Due to forward declaration problem, the definition of the
267 // function must be separated from the declaration.
268 void OnDidGetPreviewPageCount(
269 const PrintHostMsg_DidGetPreviewPageCount_Params &params) {
270 WebContents* web_contents = GetDialog();
271 PrintPreviewUI* ui = GetUI();
272 ASSERT_TRUE(ui);
273 ASSERT_TRUE(ui->web_ui());
274 Observe(web_contents);
275 ASSERT_TRUE(web_contents);
276
277 // The web ui deallocates the memory for the handler when the web ui is
278 // destroyed.
279 ui->web_ui()->AddMessageHandler(new UIDoneLoadingMessageHandler(this));
280 ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest");
281 }
282
283 void DidCloneToNewWebContents(WebContents* old_web_contents,
284 WebContents* new_web_contents) OVERRIDE {
285 Observe(new_web_contents);
286 }
287
288 void WebContentsDestroyed() OVERRIDE {
289 EndLoop();
290 }
291
292 Browser* browser_;
293 base::Closure closure_;
294 scoped_ptr<PrintPreviewSettings> settings_;
295
296 // State of the observer. The state indicates what message it is to send
297 // next. The state advances whenever the message handler calls
298 // ManipulatePreviewSettings() on the observer.
299 State state_;
300
301 DISALLOW_COPY_AND_ASSIGN(PrintPreviewObserver);
302 };
303
304 class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest {
305 public:
306 PrintPreviewPdfGeneratedBrowserTest() {}
307 virtual ~PrintPreviewPdfGeneratedBrowserTest() {}
308
309 // Navigates to the web page given, then initiates print preview and waits
310 // for all the settings to be set.
311 void NavigateAndPreview(const base::FilePath::StringType& file_name,
312 PrintPreviewSettings settings) {
313 print_preview_observer_->SetPrintPreviewSettings(settings);
314 base::FilePath path(file_name);
315 GURL gurl = net::FilePathToFileURL(path);
316
317 ui_test_utils::NavigateToURL(browser(), gurl);
318
319 base::RunLoop loop;
320 print_preview_observer_->set_quit_closure(loop.QuitClosure());
321 chrome::Print(browser());
322 loop.Run();
323 }
324
325 // Prints the webpage to pdf, after the settings have been set.
326 void Print() {
327 ASSERT_FALSE(pdf_file_save_path_.empty());
328 base::RunLoop loop;
329 print_preview_observer_->set_quit_closure(loop.QuitClosure());
330 print_preview_observer_->GetUI()->handler_->FileSelected(
331 pdf_file_save_path_, 0, NULL);
332 loop.Run();
333 }
334
335 // Initializes the pdf lib functions. Called once when browser test starts.
336 // Library is closed when the test ends.
337 void InitPdfFunctions() {
338 base::FilePath pdf_module_path;
339
340 ASSERT_TRUE(PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path));
341 ASSERT_TRUE(base::PathExists(pdf_module_path));
342 pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL));
343
344 ASSERT_TRUE(pdf_lib_.is_valid());
345 pdf_to_bitmap_func_ =
346 reinterpret_cast<PDFPageToBitmapProc>(
347 pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap"));
348
349 pdf_doc_info_func_ =
350 reinterpret_cast<GetPDFDocInfoProc>(
351 pdf_lib_.GetFunctionPointer("GetPDFDocInfo"));
352
353 pdf_page_size_func_ =
354 reinterpret_cast<GetPDFPageSizeByIndexProc>(
355 pdf_lib_.GetFunctionPointer("GetPDFPageSizeByIndex"));
356
357 ASSERT_TRUE(pdf_to_bitmap_func_);
358 ASSERT_TRUE(pdf_doc_info_func_);
359 ASSERT_TRUE(pdf_page_size_func_);
360 }
361
362 // Converts the pdf to a png file, so that the layout test can do an image
363 // diff on this image and a reference image.
364 void PdfToPng() {
365 std::string data;
366 int num_pages;
367 const int kDpi = 300;
368 double max_width = 0;
369 std::vector<uint8_t> bitmap_data;
370 double total_height = 0;
371
372 ASSERT_TRUE(base::ReadFileToString(pdf_file_save_path_, &data));
373 ASSERT_TRUE(pdf_doc_info_func_(data.data(),
374 data.size(),
375 &num_pages,
376 &max_width));
377
378 max_width = printing::ConvertPointsToPixelDouble(max_width);
379
380 for (int i = 0; i < num_pages; ++i) {
381 double width, height;
382 bool autorotate = false;
383 ASSERT_TRUE(pdf_page_size_func_(
384 data.data(), data.size(), i, &width, &height));
385
386 width = printing::ConvertPointsToPixelDouble(width);
387 height = printing::ConvertPointsToPixelDouble(height);
388
389 // The image needs to be rotated if the width is > to the height. This
390 // is because, when the image is printed to a pdf, if it is in landscape
391 // mode (or the document is just wide) if will be printed horizontally,
392 // not vertically. However, if it printed, it would have been rotated.
393 // Therefore, the image has to be automatically rotated here to reflect
394 // what is printed.
395 //
396 // TODO(ivandavid): See if this is a linux only problem or if its on
397 // every platform. It might not matter, since if its autorotated, the
398 // width will never be greater than the height, so the if conditional
399 // will never evaluate to true.
400
401 if (width > height) {
402 std::swap<double>(width, height);
403 autorotate = true;
404 }
405
406 total_height += height;
407 gfx::Rect rect(width, height);
408 printing::PdfRenderSettings settings(rect, kDpi, true);
409
410 // TODO(ivandavid): Implement correct overflow detection. Need to check
ivandavid 2014/07/09 19:58:22 I'll do this in the next patch set. I'll see if I
411 // for signed multiplication overflow. Can't use size_t or any unsigned
412 // stuff, b/c internally everything in PdfRenderSettings is signed it
413 // seems.
414
415 std::vector<uint8_t> page_bitmap_data(
416 kColorChannels * settings.area().size().GetArea());
417
418 ASSERT_TRUE(pdf_to_bitmap_func_(data.data(),
419 data.size(),
420 i,
421 page_bitmap_data.data(),
422 settings.area().size().width(),
423 settings.area().size().height(),
424 settings.dpi(),
425 settings.dpi(),
426 autorotate));
427
428 // Must multiply width & max_width by number of color channels because
429 // the bitmap stores individual bytes, not int32's.
430 FillPng(&page_bitmap_data, width * kColorChannels,
431 max_width * kColorChannels,
432 settings.area().size().height());
433 bitmap_data.insert(bitmap_data.end(),
434 page_bitmap_data.begin(),
435 page_bitmap_data.end());
436 }
437
438 CreatePng(bitmap_data, max_width, total_height);
439 }
440
441 // Fills out a bitmap with the color white to fit within a png that is wider
442 // than the bitmap. This prevents the image from being cutoff or split. The
443 // desired_width must be greater than the current width of the image.
444 void FillPng(std::vector<uint8_t>* bitmap,
445 int current_width,
446 int desired_width,
447 int height) {
448 // Need to seperate the iterator and index. We can't use an iterator only
449 // since the vector will most likely be resized and will render the
450 // iterator invalid. Might need to re-do to make it faster, but there
451 // don't seem to be any speed issues.
452 ASSERT_TRUE(bitmap);
453 ASSERT_LE(current_width, desired_width);
454 const uint8_t kColorByte = 255;
455 size_t index = 0;
456 for (int i = 0; i < height; ++i, index = i * desired_width) {
457 index += current_width - 1;
458 std::vector<uint8_t>::iterator iterator = bitmap->begin();
459 std::advance(iterator, index);
460 // 255,255,255,255 is white in BGRA
461 bitmap->insert(iterator, desired_width - current_width, kColorByte);
462 }
463 }
464
465 // Sends the png image to the layout test framework for comparison.
466 void SendPng() {
467 // Send image header & hash_ to the layout test framework.
468 printf("Content-Type: image/png\n");
469 printf("ActualHash: %s\n", base::MD5DigestToBase16(hash_).data());
470 printf("Content-Length: %" PRIuS "\n", output_.size());
471
472 for (size_t i = 0; i < output_.size(); ++i)
473 printf("%c", output_[i]);
474
475 printf("#EOF\n");
476 fflush(stdout);
477 fprintf(stderr, "#EOF\n");
478 fflush(stderr);
479 }
480
481 // Duplicates the tab that was created when the browser opened. This is done,
482 // so that the observer can listen to the duplicated tab as soon as possible
483 // and start listening for messages related to print preview.
484 void DuplicateTab() {
485 WebContents* tab =
486 browser()->tab_strip_model()->GetActiveWebContents();
487 ASSERT_TRUE(tab);
488
489 print_preview_observer_.reset(new PrintPreviewObserver(tab, browser()));
490 chrome::DuplicateTab(browser());
491
492 WebContents* initiator =
493 browser()->tab_strip_model()->GetActiveWebContents();
494 ASSERT_TRUE(initiator);
495 ASSERT_NE(tab, initiator);
496 }
497
498 // Resets the test so that another web page can be printing.
499 // Deletes the duplicate tab as it isn't needed anymore.
500 void Reset() {
501 output_.clear();
502 ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
503 chrome::CloseTab(browser());
504 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
505 }
506
507 // Creates a temporary directory to store the file that will be used for
508 // stdin to accept input. Also sets up the path to save the pdf file that
509 // will be printed. Everything is cleaned up automatically once the test
510 // ends.
511 void SetupStdinAndSavePath() {
512 // Sends a message to the layout test framework indicating indicating
513 // that the browser test has completed setting itself up. The layout
514 // test will then expect the file path for stdin.
515 base::FilePath tmp_path;
516 printf("#READY\n");
517 fflush(stdout);
518
519 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
520 ASSERT_TRUE(base::CreateTemporaryFileInDir(tmp_dir_.path(), &tmp_path));
521 ASSERT_TRUE(freopen(tmp_path.value().c_str(), "r", stdin));
522
523 pdf_file_save_path_ = tmp_dir_.path().AppendASCII("dummy.pdf");
524
525 // Send the file path to the layout test framework so that it can
526 // communicate with this browsertest.
527 printf("StdinPath: %s\n#EOF\n", tmp_path.value().c_str());
528 fflush(stdout);
529 }
530
531 private:
532 // Generates a png from bitmap data and stores it in output_.
533 void CreatePng(
534 const std::vector<uint8_t>& bitmap_data, int width, int height) {
535 std::string hash_data(bitmap_data.begin(), bitmap_data.end());
536 base::MD5Sum(
537 static_cast<const void*>(hash_data.data()), hash_data.size(), &hash_);
538
539 gfx::Rect png_rect(width, height);
540
541 // tEXtchecksum looks funny, but that's what the layout test framework
542 // expects.
543 std::string comment_title("tEXtchecksum\x00");
544 gfx::PNGCodec::Comment hash_comment(comment_title,
545 base::MD5DigestToBase16(hash_));
546
547 std::vector<gfx::PNGCodec::Comment> comments;
548 comments.push_back(hash_comment);
549
550 ASSERT_TRUE(gfx::PNGCodec::Encode(bitmap_data.data(),
551 gfx::PNGCodec::FORMAT_BGRA,
552 png_rect.size(),
553 png_rect.size().width() * kColorChannels,
554 false,
555 comments,
556 &output_));
557 }
558
559 scoped_ptr<PrintPreviewObserver> print_preview_observer_;
560 base::FilePath pdf_file_save_path_;
561
562 // These typedefs are function pointers to pdflib functions that give
563 // information about the pdf as a whole and about specific pages.
564
565 // Converts the pdf to a bitmap.
566 typedef bool (*PDFPageToBitmapProc)(const void* pdf_buffer,
567 int pdf_buffer_size,
568 int page_number,
569 void* bitmap_buffer,
570 int bitmap_width,
571 int bitmap_height,
572 int dpi_x,
573 int dpi_y,
574 bool autorotate);
575
576 // Gets the page count and maximum page width of the pdf in points.
577 typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer,
578 int buffer_size,
579 int* pages_count,
580 double* max_page_width);
581
582 // Gets the dimensions of a specific page.
583 typedef bool (*GetPDFPageSizeByIndexProc)(const void* pdf_buffer,
584 int buffer_size,
585 int index,
586 double* width,
587 double* height);
588
589 // Instantiations of the function pointers described above.
590 PDFPageToBitmapProc pdf_to_bitmap_func_;
591 GetPDFDocInfoProc pdf_doc_info_func_;
592 GetPDFPageSizeByIndexProc pdf_page_size_func_;
593
594 // Used to open up the library that contains the pdflib functions.
595 base::ScopedNativeLibrary pdf_lib_;
596
597 // Vector where the png is finally stored.
598 std::vector<unsigned char> output_;
599
600 // Image hash of the bitmap that is turned into a PNG. The hash is put into
601 // the PNG as a comment, as it is needed by the layout test framework.
602 base::MD5Digest hash_;
603
604 // Temporary directory for storing the pdf and the file for stdin.
605 base::ScopedTempDir tmp_dir_;
606
607 DISALLOW_COPY_AND_ASSIGN(PrintPreviewPdfGeneratedBrowserTest);
608 };
609
610 IN_PROC_BROWSER_TEST_F(PrintPreviewPdfGeneratedBrowserTest,
611 MANUAL_DummyTest) {
612 // What this code is supposed to do:
613 // -Setup communication with the layout test framework
614 // -Print webpage to a pdf
615 // -Convert pdf to a png
616 // -Send png to layout test framework, where it doesn an image diff
617 // on the image sent by this test and a reference image.
618 //
619 // Throughout this code, there will be printf statements. The layout test
620 // framework uses stdout to get data from the browser test and uses stdin
621 // to send data to the browser test. Calling printf("#EOF\n") indicates that
622 // whatever block of data that the test was expecting has been completely
623 // sent. Sometimes EOF is printed to stderr because the test will expect it
624 // from stderr in addition to stdout for certain blocks of data.
625 InitPdfFunctions();
626 SetupStdinAndSavePath();
627
628 // There is no way to determine how many tests are to be run ahead of time
629 // without a ton of modifications to the layouy test framework. However,
630 // whenever it is done with a set of tests, it calls SIGKILL on the browser
631 // test that ran those set of tests. Thus, this while loop will end once the
632 // layout test framework decides to actually kill this process. For this to
633 // work, the test must be run with '--single_process'. There must be an
634 // underscore, not a dash, as that is something different.
635 while (true) {
636 base::FilePath::StringType cmd;
637 std::getline(STDIN_STREAM, cmd);
638 if (cmd.empty()) {
639 while (STDIN_STREAM.eof()) {
640 STDIN_STREAM.clear();
641 std::getline(STDIN_STREAM, cmd);
642 if (!cmd.empty()) {
643 break;
644 }
645 }
646 }
647
648 DuplicateTab();
649
650 // TODO(ivandavid): Get settings from file in resources.
651 PrintPreviewSettings settings(
652 true,
653 "",
654 false,
655 false,
656 printing::DEFAULT_MARGINS,
657 cmd.find(".pdf") != base::FilePath::StringType::npos);
658
659 // Splits the command sent by the layout test framework. The first command
660 // is always the file path to use for the test. The rest isn't relevant,
661 // so it can be ignored. The separator for the commands is an apostrophe.
662 std::vector<base::FilePath::StringType> cmd_arguments;
663 base::SplitString(cmd, '\'', &cmd_arguments);
664 base::FilePath::StringType test_name(cmd_arguments[0]);
665 NavigateAndPreview(test_name, settings);
666 Print();
667 PdfToPng();
668
669 // Message to the layout test framework indicating that it should start
670 // waiting for the image data, as there is no more text data to be read.
671 // There actually isn't any text data at all, however because the layout
672 // test framework requires it, a message has to be sent to stop it from
673 // waiting for this message and start waiting for the image data.
674 printf("#EOF\n");
675 fflush(stdout);
676
677 SendPng();
678 Reset();
679 }
680 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/print_preview/native_layer.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698