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

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: Refactored browser test and GetPDFPageSizeByIndex. Fixed style 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
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 <limits>
8 #include <string>
9 #include <vector>
10
11 #include "base/file_util.h"
12 #include "base/files/file.h"
13 #include "base/files/file_path.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/format_macros.h"
16 #include "base/logging.h"
17 #include "base/md5.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/numerics/safe_conversions.h"
20 #include "base/path_service.h"
21 #include "base/run_loop.h"
22 #include "base/scoped_native_library.h"
23 #include "base/strings/string16.h"
24 #include "base/strings/string_split.h"
25 #include "base/strings/string_util.h"
26 #include "base/strings/utf_string_conversions.h"
27 #include "chrome/app/chrome_command_ids.h"
28 #include "chrome/browser/net/referrer.h"
29 #include "chrome/browser/printing/print_preview_dialog_controller.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/browser.h"
32 #include "chrome/browser/ui/browser_commands.h"
33 #include "chrome/browser/ui/tabs/tab_strip_model.h"
34 #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h"
35 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
36 #include "chrome/browser/ui/webui/print_preview/sticky_settings.h"
37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/print_messages.h"
39 #include "chrome/common/url_constants.h"
40 #include "chrome/test/base/in_process_browser_test.h"
41 #include "chrome/test/base/ui_test_utils.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/browser/web_ui_message_handler.h"
44 #include "content/public/common/page_transition_types.h"
45 #include "content/public/test/browser_test_utils.h"
46 #include "content/public/test/test_navigation_observer.h"
47 #include "content/public/test/test_utils.h"
48 #include "net/base/filename_util.h"
49 #include "printing/pdf_render_settings.h"
50 #include "printing/units.h"
51 #include "ui/events/keycodes/keyboard_codes.h"
52 #include "ui/gfx/codec/png_codec.h"
53 #include "ui/gfx/geometry/rect.h"
54 #include "url/gurl.h"
55 #include "ipc/ipc_message_macros.h"
56
57 #if defined(OS_POSIX)
58 #define STDIN_STREAM std::cin
59 #elif defined(OS_WIN)
60 #define STDIN_STREAM std::wcin
61 #endif
62
63 using content::WebContents;
64 using content::WebContentsObserver;
65
66 // Message refers to the 'UILoaded' message from print_preview.js.
67 // It gets sent either from onPreviewGenerationDone or from
68 // onManipulateSettings_() in print_preview.js
69 enum State {
70 // Waiting for the first message so the program can select Save as PDF
71 kWaitingToSendSaveAsPdf = 0,
72 // Waiting for the second message so the test can set the layout
73 kWaitingToSendLayoutSettings = 1,
74 // Waiting for the third message so the test can set the page numbers
75 kWaitingToSendPageNumbers = 2,
76 // Waiting for the forth message so the test can set the headers checkbox
77 kWaitingToSendHeadersAndFooters = 3,
78 // Waiting for the fifth message so the test can set the background checkbox
79 kWaitingToSendBackgroundColorsAndImages = 4,
80 // Waiting for the sixth message so the test can set the margins combobox
81 kWaitingToSendMargins = 5,
82 // Waiting for the final message so the program can save to PDF.
83 kWaitingForFinalMessage = 6,
84 };
85
86 struct PrintPreviewSettings {
87 PrintPreviewSettings(bool is_portrait,
88 std::string page_numbers,
89 bool headers_and_footers,
90 bool background_colors_and_images,
91 printing::MarginType margins,
92 bool is_already_pdf)
93 : is_portrait(is_portrait),
94 page_numbers(page_numbers),
95 headers_and_footers(headers_and_footers),
96 background_colors_and_images(background_colors_and_images),
97 margins(margins),
98 is_already_pdf(is_already_pdf) {}
99
100 bool is_portrait;
101 std::string page_numbers;
102 bool headers_and_footers;
103 bool background_colors_and_images;
104 printing::MarginType margins;
105 bool is_already_pdf;
106 };
107
108 // Observes the print preview webpage. Once it observes the
109 // PreviewPageCount message, will send a sequence of commands
110 // to the print preview dialog and change the settings of the
111 // preview dialog.
112 class PrintPreviewObserver : public WebContentsObserver {
113 public:
114 PrintPreviewObserver(WebContents* dialog,
115 Browser* browser)
116 : WebContentsObserver(dialog),
117 browser_(browser),
118 state_(kWaitingToSendSaveAsPdf) {}
119
120 virtual ~PrintPreviewObserver() {}
121
122 // Sets closure for the observer so that it can end the loop.
123 void set_quit_closure(const base::Closure &closure) {
124 closure_ = closure;
125 }
126
127 // Actually stops the message_loop so that the test can proceed.
128 void EndLoop() {
129 base::MessageLoop::current()->PostTask(FROM_HERE, closure_);
130 }
131
132 // This method must always return false. If it ever returns true,
133 // it will cause the test to hang. This is because the
134 // PrintPreviewMessageHandler should still handle all of the messages to
135 // progress the print preview process.
136 bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
137 IPC_BEGIN_MESSAGE_MAP(PrintPreviewObserver, message)
138 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
139 OnDidGetPreviewPageCount)
140 IPC_MESSAGE_UNHANDLED(break;)
Dan Beam 2014/07/08 04:25:13 i still don't love that there's a break; here beca
ivandavid 2014/07/08 23:24:21 I decided to remove it. It doesn't affect my test,
141 IPC_END_MESSAGE_MAP();
142 return false;
143 }
144
145 // Gets the web contents for the print preview dialog so that
146 // the UI and other elements can be accessed.
147 WebContents* GetDialog() {
148 WebContents* tab = browser_->tab_strip_model()->GetActiveWebContents();
149 printing::PrintPreviewDialogController* dialog_controller =
150 printing::PrintPreviewDialogController::GetInstance();
151 WebContents* web_contents =
152 dialog_controller->GetPrintPreviewForContents(tab);
153 return web_contents;
154 }
155
156 // Gets the PrintPreviewUI so that certain elements can be accessed.
157 PrintPreviewUI* GetUI() {
158 return static_cast<PrintPreviewUI*>(
159 GetDialog()->GetWebUI()->GetController());
160 }
161
162 // Calls a javascript function that will change the print preview settings,
163 // such as the layout, the margins, page numbers, etc.
164 void ManipulatePreviewSettings() {
165 base::DictionaryValue script_argument;
166
167 if (state_ == kWaitingToSendSaveAsPdf) {
168 script_argument.SetBoolean("selectSaveAsPdfDestination", true);
169 state_ = settings_->is_already_pdf ?
170 kWaitingToSendPageNumbers :
171 kWaitingToSendLayoutSettings;
172 } else if (state_ == kWaitingToSendLayoutSettings) {
173 script_argument.SetBoolean("layoutSettings.portrait",
174 settings_->is_portrait);
175 state_ = kWaitingToSendPageNumbers;
176 } else if (state_ == kWaitingToSendPageNumbers) {
177 script_argument.SetString("pageRange", settings_->page_numbers);
178 state_ = settings_->is_already_pdf ?
179 kWaitingForFinalMessage :
180 kWaitingToSendHeadersAndFooters;
181 } else if (state_ == kWaitingToSendHeadersAndFooters) {
182 script_argument.SetBoolean("headersAndFooters",
183 settings_->headers_and_footers);
184 state_ = kWaitingToSendBackgroundColorsAndImages;
185 } else if (state_ == kWaitingToSendBackgroundColorsAndImages) {
186 script_argument.SetBoolean("backgroundColorsAndImages",
187 settings_->background_colors_and_images);
188 state_ = kWaitingToSendMargins;
189 } else if (state_ == kWaitingToSendMargins) {
190 script_argument.SetInteger("margins", settings_->margins);
191 state_ = kWaitingForFinalMessage;
192 } else if (state_ == kWaitingForFinalMessage) {
193 EndLoop();
194 }
195
196 DCHECK(!script_argument.empty());
Dan Beam 2014/07/08 04:25:13 ^ wouldn't this fail in the case of kWaitingForFin
ivandavid 2014/07/08 23:24:21 It should have, but it wasn't. I changed it to ASS
197 GetUI()->web_ui()->CallJavascriptFunction(
198 "onManipulateSettingsForTest", script_argument);
199 }
200
201 // Function to set the print preview settings and save them so they
202 // can be sent later. Currently only used in the constructor. Will be
203 // used when creating a test and take command line arguments.
204 // |page_numbers| is a comma separated page range.
205 // Example: "1-5,9" will print pages 1 through 5 and page 9.
206 // The pages specified must be less than or equal to the maximum
207 // page number. An empty string seems to be valid input, however
208 // further testing will be required to see if that is actually
209 // true.
210 void SetPrintPreviewSettings(const PrintPreviewSettings& settings) {
211 settings_.reset(new PrintPreviewSettings(settings));
212 }
213
214 private:
215 class UIDoneLoadingMessageHandler : public content::WebUIMessageHandler {
216 public:
217 explicit UIDoneLoadingMessageHandler(PrintPreviewObserver* observer) {
218 observer_ = observer;
Dan Beam 2014/07/08 04:25:13 nit: explicit UIDoneLoadingMessageHandler(Print
ivandavid 2014/07/08 23:24:21 Dunno why I changed it to that. Done.
219 }
220
221 virtual ~UIDoneLoadingMessageHandler() {}
222
223 // When a setting has been set succesfully, this is called and
224 // the observer_ is told to send the next setting to be set.
225 void HandleDone(const base::ListValue* /* args */) {
226 ASSERT_TRUE(observer_);
227 observer_->ManipulatePreviewSettings();
228 }
229
230 // Ends the test because a setting was not set successfully,
231 // therefore, the test shouldn't continue.
232 // TODO(ivandavid): Print out error message to give context.
233 void HandleFailure(const base::ListValue* /* args */) {
234 FAIL();
235 }
236
237 // Sets up this class to listen for the UILoadedForTest and
238 // UIFailedLoadingForTest messages. These messages are sent
239 // by print_preview.js. On UILoadedForTest, a settings has
240 // been successfully set and its effects on the pdf have been finalized.
241 // On UIFaieldLoadingForTest a setting has not been successfully set
242 // and the test should fail.
243 void RegisterMessages() OVERRIDE {
244 web_ui()->RegisterMessageCallback(
245 "UILoadedForTest",
246 base::Bind(&UIDoneLoadingMessageHandler::HandleDone,
247 base::Unretained(this)));
248
249 web_ui()->RegisterMessageCallback(
250 "UIFailedLoadingForTest",
251 base::Bind(&UIDoneLoadingMessageHandler::HandleFailure,
252 base::Unretained(this)));
253 }
254
255 private:
256 PrintPreviewObserver* observer_;
Dan Beam 2014/07/08 04:25:13 nit: PrintPreviewObserver* observer_ const;
ivandavid 2014/07/08 23:24:21 I'm not sure I can make observer_ const because th
Dan Beam 2014/07/09 01:56:32 PrintPreviewObserver* observer_ const; means that
ivandavid 2014/07/09 19:58:21 Ahh. I see. I think what we want is this however,
Dan Beam 2014/07/09 22:03:04 yeah, my bad, ^ that one (sorry if this took a whi
257
258 DISALLOW_COPY_AND_ASSIGN(UIDoneLoadingMessageHandler);
259 };
260
261 // Called when the observer gets the IPC message stating that the
262 // page count is ready.
263 // Due to forward declaration problem, the definition of the function
264 // must be separated from the declaration.
265 void OnDidGetPreviewPageCount(
266 const PrintHostMsg_DidGetPreviewPageCount_Params &params) {
267 WebContents* web_contents = GetDialog();
268 PrintPreviewUI* ui = GetUI();
269 ASSERT_TRUE(ui);
270 ASSERT_TRUE(ui->web_ui());
271 Observe(web_contents);
272 ASSERT_TRUE(web_contents);
273 ui->web_ui()->AddMessageHandler(new UIDoneLoadingMessageHandler(this));
274 ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest");
275 }
276
277 void DidCloneToNewWebContents(WebContents* old_web_contents,
278 WebContents* new_web_contents) OVERRIDE {
279 Observe(new_web_contents);
280 }
281
282 void WebContentsDestroyed() OVERRIDE {
283 EndLoop();
284 }
285
286 Browser* browser_;
287 base::Closure closure_;
288 scoped_ptr<PrintPreviewSettings> settings_;
289 State state_;
290
291 DISALLOW_COPY_AND_ASSIGN(PrintPreviewObserver);
292 };
293
294 class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest {
295 public:
296 PrintPreviewPdfGeneratedBrowserTest() {}
297 virtual ~PrintPreviewPdfGeneratedBrowserTest() {}
298
299 // Navigates to the web page given, then initiates print preview
300 // and waits for all the settings to be set.
301 void NavigateAndPreview(const base::FilePath::StringType& file_name,
302 PrintPreviewSettings settings) {
303 print_preview_observer_->SetPrintPreviewSettings(settings);
304 base::FilePath path(file_name);
305 GURL gurl = net::FilePathToFileURL(path);
306
307 ui_test_utils::NavigateToURL(browser(), gurl);
308
309 base::RunLoop loop;
310 print_preview_observer_->set_quit_closure(loop.QuitClosure());
311 chrome::Print(browser());
312 loop.Run();
313 }
314
315 // Prints the webpage to pdf, after the settings have been set.
316 void Print() {
317 ASSERT_FALSE(pdf_file_save_path_.empty());
318 base::RunLoop loop;
319 print_preview_observer_->set_quit_closure(loop.QuitClosure());
320 print_preview_observer_->GetUI()->handler_->FileSelected(
321 pdf_file_save_path_, 0, NULL);
322 loop.Run();
323 }
324
325 // Converts the pdf to a png file, so that the layout test can
326 // do an image diff on this image and a reference image.
327 void PdfToPng() {
328 // Get the library functions to get the pdf info.
329 base::ScopedNativeLibrary pdf_lib;
330 base::FilePath pdf_module_path;
331
332 ASSERT_TRUE(PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path));
333 ASSERT_TRUE(base::PathExists(pdf_module_path));
334 pdf_lib.Reset(base::LoadNativeLibrary(pdf_module_path, NULL));
335
336 ASSERT_TRUE(pdf_lib.is_valid());
337 pdf_to_bitmap_func_ =
338 reinterpret_cast<PDFPageToBitmap>(
339 pdf_lib.GetFunctionPointer("RenderPDFPageToBitmap"));
340
341 pdf_doc_info_func_ =
342 reinterpret_cast<GetPDFDocInfoProc>(
343 pdf_lib.GetFunctionPointer("GetPDFDocInfo"));
344
345 pdf_page_size_func_ =
346 reinterpret_cast<GetPDFPageSizeByIndexProc>(
347 pdf_lib.GetFunctionPointer("GetPDFPageSizeByIndex"));
348
349 ASSERT_TRUE(pdf_to_bitmap_func_);
350 ASSERT_TRUE(pdf_doc_info_func_);
351 ASSERT_TRUE(pdf_page_size_func_);
352
353 std::string data;
354 int num_pages;
355 ASSERT_TRUE(base::ReadFileToString(pdf_file_save_path_, &data));
356 ASSERT_TRUE(pdf_doc_info_func_(data.data(),
357 data.size(),
358 &num_pages,
359 NULL));
360 std::vector<uint8_t> bitmap_data;
361 double min_width = std::numeric_limits<double>::max();
362 double total_height = 0;
363
364 for (int i = 0; i < num_pages; i++) {
365 double height, width;
366 ASSERT_TRUE(pdf_page_size_func_(
367 data.data(), data.size(), i, &width, &height));
368
369 height = printing::ConvertPointsToPixelDouble(height);
370 width = printing::ConvertPointsToPixelDouble(width);
371
372 bool autorotate = false;
373
374 if (height < width) {
375 double temp = height;
376 height = width;
377 width = temp;
378 autorotate = true;
379 }
380
381 total_height += height;
382
383 if (width < min_width)
384 min_width = width;
385
386 gfx::Rect rect(width, height);
387 printing::PdfRenderSettings settings(rect, 300, true);
388
389 // Detecting overflow. If a * b > max_size then there is overflow.
390 // So just check if a > max_size / b.
391 // Need to check both the cases in which GetArea() overflows and where
392 // GetArea() * 4 overflows. If the latter is just checked, then it is
393 // possible that if GetArea() overflows, the latter case will pass by
394 // virtue of it overflowing to a value of 1 or something like that.
395 // Also, for the first comparison, height is promoted to size_t.
396 size_t max_size = std::numeric_limits<size_t>::max();
397 if (static_cast<size_t>(settings.area().size().width()) >
398 max_size / settings.area().size().height() ||
399 static_cast<size_t>(settings.area().size().GetArea()) >
400 max_size / 4) {
401 LOG(ERROR) << "OVERFLOW DETECTED: IMAGE DIMENSIONS ARE TOO LARGE!";
402 FAIL();
403 }
404
405 std::vector<uint8_t> page_bitmap_data(
406 4 * settings.area().size().GetArea());
407
408 ASSERT_TRUE(pdf_to_bitmap_func_(data.data(),
409 data.size(),
410 i,
411 page_bitmap_data.data(),
412 settings.area().size().width(),
413 settings.area().size().height(),
414 settings.dpi(),
415 settings.dpi(),
416 autorotate));
417
418 bitmap_data.insert(bitmap_data.end(),
419 page_bitmap_data.begin(),
420 page_bitmap_data.end());
421 }
422
423 std::string hash_input(bitmap_data.begin(), bitmap_data.end());
424 base::MD5Sum(static_cast<void*>(const_cast<char*>(hash_input.data())),
425 hash_input.size(),
426 &hash_);
427
428 gfx::Rect png_rect(min_width, total_height);
429
430 std::string comment_title("tEXtchecksum\x00");
431 gfx::PNGCodec::Comment hash_comment(
432 comment_title,
433 base::MD5DigestToBase16(hash_));
434
435 std::vector<gfx::PNGCodec::Comment> comments;
436 comments.push_back(hash_comment);
437
438 ASSERT_TRUE(
439 gfx::PNGCodec::Encode(static_cast<unsigned char*>(
440 bitmap_data.data()),
441 gfx::PNGCodec::FORMAT_BGRA,
442 png_rect.size(),
443 png_rect.size().width() * sizeof(uint32_t),
444 false,
445 comments,
446 &output_));
447 }
448
449 // Sends the png image to the layout test framework for comparison.
450 void SendPng() {
451 // Send image header & hash_ to the layout test framework.
452 printf("Content-Type: image/png\n");
453 printf("ActualHash: %s\n", base::MD5DigestToBase16(hash_).data());
454 printf("Content-Length: %" PRIuS "\n", output_.size());
455
456 for (size_t i = 0; i < output_.size(); ++i)
457 printf("%c", output_[i]);
458
459 printf("#EOF\n");
460 fflush(stdout);
461 fprintf(stderr, "#EOF\n");
462 fflush(stderr);
463 }
464
465 // Duplicates the tab that was created when the browser opened.
466 // This is done, so that the observer can listen to the duplicated
467 // tab as soon as possible and start listening for messages related to
468 // print preview.
469 void DuplicateTab() {
470 WebContents* tab =
471 browser()->tab_strip_model()->GetActiveWebContents();
472 ASSERT_TRUE(tab);
473
474 print_preview_observer_.reset(
475 new PrintPreviewObserver(tab, browser()));
476 chrome::DuplicateTab(browser());
477
478 WebContents* initiator =
479 browser()->tab_strip_model()->GetActiveWebContents();
480 ASSERT_TRUE(initiator);
481 ASSERT_NE(tab, initiator);
482 }
483
484 // Resets the test so that another web page can be printing.
485 // Deletes the duplicate tab as it isn't needed anymore.
486 void Reset() {
487 output_.clear();
488 ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
489 chrome::CloseTab(browser());
490 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
491 }
492
493 // Creates a temporary directory to store the file that will be used for
494 // stdin to accept input. Also sets up the path to save the pdf file
495 // that will be printed. Everything is cleaned up automatically once
496 // the test ends.
497 void SetupStdinAndSavePath() {
498 // Sends a message to the layout test framework indicating indicating
499 // that the browser test has completed setting itself up. The layout
500 // test will then expect the file path for stdin.
501 printf("#READY\n");
502 fflush(stdout);
503
504 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
505 ASSERT_TRUE(base::CreateTemporaryFileInDir(tmp_dir_.path(), &tmp_path_));
506 ASSERT_TRUE(freopen(tmp_path_.value().c_str(), "r", stdin));
507
508 pdf_file_save_path_ = tmp_dir_.path().AppendASCII("dummy.pdf");
509
510 // Send the file path to the layout test framework so that it can
511 // communicate with this browsertest.
512 printf("StdinPath: %s\n#EOF\n", tmp_path_.value().c_str());
513 fflush(stdout);
514 }
515
516 private:
517 scoped_ptr<PrintPreviewObserver> print_preview_observer_;
518 base::FilePath pdf_file_save_path_;
519
520 typedef bool (*PDFPageToBitmap)(const void* pdf_buffer,
521 int pdf_buffer_size,
522 int page_number,
523 void* bitmap_buffer,
524 int bitmap_width,
525 int bitmap_height,
526 int dpi_x,
527 int dpi_y,
528 bool autorotate);
529
530 typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer,
531 int buffer_size,
532 int* pages_count,
533 double* max_page_width);
534
535 typedef bool (*GetPDFPageSizeByIndexProc)(const void* pdf_buffer,
536 int buffer_size,
537 int index,
538 double* width,
539 double* height);
540
541 PDFPageToBitmap pdf_to_bitmap_func_;
542 GetPDFDocInfoProc pdf_doc_info_func_;
543 GetPDFPageSizeByIndexProc pdf_page_size_func_;
544 std::vector<unsigned char> output_;
545 base::MD5Digest hash_;
546 base::ScopedTempDir tmp_dir_;
547 base::FilePath tmp_path_;
548
549 DISALLOW_COPY_AND_ASSIGN(PrintPreviewPdfGeneratedBrowserTest);
550 };
551
552 IN_PROC_BROWSER_TEST_F(PrintPreviewPdfGeneratedBrowserTest,
553 MANUAL_DummyTest) {
554 // What this code is supposed to do:
555 // -Setup communication with the layout test framework
556 // -Print webpage to a pdf
557 // -Convert pdf to a png
558 // -Send png to layout test framework, where it doesn an image diff
559 // on the image sent by this test and a reference image.
560 //
561 // Throughout this code, there will be printf statements.
562 // The layout test framework uses stdout to get data from the browser test
563 // and uses stdin to send data to the browser test.
564 // Calling printf("#EOF\n") indicates that whatever block of data that
565 // the test was expecting has been completely sent. Sometimes EOF is
566 // printed to stderr because the test will expect it from stderr
567 // in addition to stdout for certain blocks of data.
568 SetupStdinAndSavePath();
569
570 // There is no way to determine how many tests are to be run
571 // ahead of time without a ton of modifications to the layout
572 // test framework. However, whenever it is done with a set of tests,
573 // it calls SIGKILL on the browser test that ran those set of tests.
574 // Thus, this while loop will end once the layout test framework
575 // decides to actually kill this process. For this to work,
576 // the test must be run with '--single_process'. There must be an
577 // underscore, not a dash, as that is something different.
578 while (true) {
579 base::FilePath::StringType cmd;
580 std::getline(STDIN_STREAM, cmd);
581 if (cmd.empty()) {
582 while (STDIN_STREAM.eof()) {
583 STDIN_STREAM.clear();
584 std::getline(STDIN_STREAM, cmd);
585 if (!cmd.empty()) {
586 break;
587 }
588 }
589 }
590
591 DuplicateTab();
592
593 // TODO(ivandavid): Get settings from file in resources.
594 PrintPreviewSettings settings(
595 true,
596 "",
597 false,
598 false,
599 printing::DEFAULT_MARGINS,
600 cmd.find(".pdf") != base::FilePath::StringType::npos);
601
602 std::vector<base::FilePath::StringType> cmd_arguments;
603 base::SplitString(cmd, '\'', &cmd_arguments);
604 base::FilePath::StringType test_name(cmd_arguments[0]);
605 NavigateAndPreview(test_name, settings);
606 Print();
607 PdfToPng();
608
609 // Message to the layout test framework indicating that it should start
610 // waiting for the image data, as there is no more text data to be read.
611 // There actually isn't any text data at all, however because the layout
612 // test framework requires it, a message has to be sent to stop it from
613 // waiting for this message and start waiting for the image data.
614 printf("#EOF\n");
615 fflush(stdout);
616
617 SendPng();
618 Reset();
619 }
620 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698