• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "base/command_line.h"
6 #include "chrome/common/chrome_switches.h"
7 #include "chrome/common/print_messages.h"
8 #include "chrome/renderer/mock_printer.h"
9 #include "chrome/renderer/printing/print_web_view_helper.h"
10 #include "chrome/test/base/chrome_render_view_test.h"
11 #include "content/public/renderer/render_view.h"
12 #include "printing/print_job_constants.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/platform/WebString.h"
15 #include "third_party/WebKit/public/web/WebFrame.h"
16 #include "third_party/WebKit/public/web/WebRange.h"
17 #include "third_party/WebKit/public/web/WebView.h"
18 
19 #if defined(OS_WIN) || defined(OS_MACOSX)
20 #include "base/file_util.h"
21 #include "printing/image.h"
22 
23 using blink::WebFrame;
24 using blink::WebString;
25 #endif
26 
27 namespace printing {
28 
29 namespace {
30 
31 // A simple web page.
32 const char kHelloWorldHTML[] = "<body><p>Hello World!</p></body>";
33 
34 // A simple webpage with a button to print itself with.
35 const char kPrintOnUserAction[] =
36     "<body>"
37     "  <button id=\"print\" onclick=\"window.print();\">Hello World!</button>"
38     "</body>";
39 
40 #if !defined(OS_CHROMEOS)
41 // HTML with 3 pages.
42 const char kMultipageHTML[] =
43   "<html><head><style>"
44   ".break { page-break-after: always; }"
45   "</style></head>"
46   "<body>"
47   "<div class='break'>page1</div>"
48   "<div class='break'>page2</div>"
49   "<div>page3</div>"
50   "</body></html>";
51 
52 // A simple web page with print page size css.
53 const char kHTMLWithPageSizeCss[] =
54     "<html><head><style>"
55     "@media print {"
56     "  @page {"
57     "     size: 4in 4in;"
58     "  }"
59     "}"
60     "</style></head>"
61     "<body>Lorem Ipsum:"
62     "</body></html>";
63 
64 // A simple web page with print page layout css.
65 const char kHTMLWithLandscapePageCss[] =
66     "<html><head><style>"
67     "@media print {"
68     "  @page {"
69     "     size: landscape;"
70     "  }"
71     "}"
72     "</style></head>"
73     "<body>Lorem Ipsum:"
74     "</body></html>";
75 
76 // A longer web page.
77 const char kLongPageHTML[] =
78     "<body><img src=\"\" width=10 height=10000 /></body>";
79 
80 // A web page to simulate the print preview page.
81 const char kPrintPreviewHTML[] =
82     "<body><p id=\"pdf-viewer\">Hello World!</p></body>";
83 
CreatePrintSettingsDictionary(base::DictionaryValue * dict)84 void CreatePrintSettingsDictionary(base::DictionaryValue* dict) {
85   dict->SetBoolean(kSettingLandscape, false);
86   dict->SetBoolean(kSettingCollate, false);
87   dict->SetInteger(kSettingColor, GRAY);
88   dict->SetBoolean(kSettingPrintToPDF, true);
89   dict->SetInteger(kSettingDuplexMode, SIMPLEX);
90   dict->SetInteger(kSettingCopies, 1);
91   dict->SetString(kSettingDeviceName, "dummy");
92   dict->SetInteger(kPreviewUIID, 4);
93   dict->SetInteger(kPreviewRequestID, 12345);
94   dict->SetBoolean(kIsFirstRequest, true);
95   dict->SetInteger(kSettingMarginsType, DEFAULT_MARGINS);
96   dict->SetBoolean(kSettingPreviewModifiable, false);
97   dict->SetBoolean(kSettingHeaderFooterEnabled, false);
98   dict->SetBoolean(kSettingGenerateDraftData, true);
99   dict->SetBoolean(kSettingShouldPrintBackgrounds, false);
100   dict->SetBoolean(kSettingShouldPrintSelectionOnly, false);
101 }
102 #endif  // !defined(OS_CHROMEOS)
103 
104 }  // namespace
105 
106 class PrintWebViewHelperTestBase : public ChromeRenderViewTest {
107  public:
PrintWebViewHelperTestBase()108   PrintWebViewHelperTestBase() {}
~PrintWebViewHelperTestBase()109   virtual ~PrintWebViewHelperTestBase() {}
110 
111  protected:
PrintWithJavaScript()112   void PrintWithJavaScript() {
113     ExecuteJavaScript("window.print();");
114     ProcessPendingMessages();
115   }
116   // The renderer should be done calculating the number of rendered pages
117   // according to the specified settings defined in the mock render thread.
118   // Verify the page count is correct.
VerifyPageCount(int count)119   void VerifyPageCount(int count) {
120 #if defined(OS_CHROMEOS)
121     // The DidGetPrintedPagesCount message isn't sent on ChromeOS. Right now we
122     // always print all pages, and there are checks to that effect built into
123     // the print code.
124 #else
125     const IPC::Message* page_cnt_msg =
126         render_thread_->sink().GetUniqueMessageMatching(
127             PrintHostMsg_DidGetPrintedPagesCount::ID);
128     ASSERT_TRUE(page_cnt_msg);
129     PrintHostMsg_DidGetPrintedPagesCount::Param post_page_count_param;
130     PrintHostMsg_DidGetPrintedPagesCount::Read(page_cnt_msg,
131                                                &post_page_count_param);
132     EXPECT_EQ(count, post_page_count_param.b);
133 #endif  // defined(OS_CHROMEOS)
134   }
135 
136   // The renderer should be done calculating the number of rendered pages
137   // according to the specified settings defined in the mock render thread.
138   // Verify the page count is correct.
VerifyPreviewPageCount(int count)139   void VerifyPreviewPageCount(int count) {
140     const IPC::Message* page_cnt_msg =
141         render_thread_->sink().GetUniqueMessageMatching(
142         PrintHostMsg_DidGetPreviewPageCount::ID);
143     ASSERT_TRUE(page_cnt_msg);
144     PrintHostMsg_DidGetPreviewPageCount::Param post_page_count_param;
145     PrintHostMsg_DidGetPreviewPageCount::Read(page_cnt_msg,
146                                               &post_page_count_param);
147     EXPECT_EQ(count, post_page_count_param.a.page_count);
148   }
149 
150   // Verifies whether the pages printed or not.
VerifyPagesPrinted(bool printed)151   void VerifyPagesPrinted(bool printed) {
152 #if defined(OS_CHROMEOS)
153     bool did_print_msg = (render_thread_->sink().GetUniqueMessageMatching(
154         PrintHostMsg_TempFileForPrintingWritten::ID) != NULL);
155     ASSERT_EQ(printed, did_print_msg);
156 #else
157     const IPC::Message* print_msg =
158         render_thread_->sink().GetUniqueMessageMatching(
159             PrintHostMsg_DidPrintPage::ID);
160     bool did_print_msg = (NULL != print_msg);
161     ASSERT_EQ(printed, did_print_msg);
162     if (printed) {
163       PrintHostMsg_DidPrintPage::Param post_did_print_page_param;
164       PrintHostMsg_DidPrintPage::Read(print_msg, &post_did_print_page_param);
165       EXPECT_EQ(0, post_did_print_page_param.a.page_number);
166     }
167 #endif  // defined(OS_CHROMEOS)
168   }
OnPrintPages()169   void OnPrintPages() {
170     PrintWebViewHelper::Get(view_)->OnPrintPages();
171     ProcessPendingMessages();
172   }
173 
OnPrintPreview(const base::DictionaryValue & dict)174   void OnPrintPreview(const base::DictionaryValue& dict) {
175     PrintWebViewHelper* print_web_view_helper = PrintWebViewHelper::Get(view_);
176     print_web_view_helper->OnInitiatePrintPreview(false);
177     print_web_view_helper->OnPrintPreview(dict);
178     ProcessPendingMessages();
179   }
180 
OnPrintForPrintPreview(const base::DictionaryValue & dict)181   void OnPrintForPrintPreview(const base::DictionaryValue& dict) {
182     PrintWebViewHelper::Get(view_)->OnPrintForPrintPreview(dict);
183     ProcessPendingMessages();
184   }
185 
186   DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTestBase);
187 };
188 
189 class PrintWebViewHelperTest : public PrintWebViewHelperTestBase {
190  public:
PrintWebViewHelperTest()191   PrintWebViewHelperTest() {}
~PrintWebViewHelperTest()192   virtual ~PrintWebViewHelperTest() {}
193 
SetUp()194   virtual void SetUp() OVERRIDE {
195     ChromeRenderViewTest::SetUp();
196   }
197 
198  protected:
199   DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTest);
200 };
201 
202 // Tests that printing pages work and sending and receiving messages through
203 // that channel all works.
TEST_F(PrintWebViewHelperTest,OnPrintPages)204 TEST_F(PrintWebViewHelperTest, OnPrintPages) {
205   LoadHTML(kHelloWorldHTML);
206   OnPrintPages();
207 
208   VerifyPageCount(1);
209   VerifyPagesPrinted(true);
210 }
211 
212 // Duplicate of OnPrintPagesTest only using javascript to print.
TEST_F(PrintWebViewHelperTest,PrintWithJavascript)213 TEST_F(PrintWebViewHelperTest, PrintWithJavascript) {
214   PrintWithJavaScript();
215 
216   VerifyPageCount(1);
217   VerifyPagesPrinted(true);
218 }
219 
220 // Tests that the renderer blocks window.print() calls if they occur too
221 // frequently.
TEST_F(PrintWebViewHelperTest,BlockScriptInitiatedPrinting)222 TEST_F(PrintWebViewHelperTest, BlockScriptInitiatedPrinting) {
223   // Pretend user will cancel printing.
224   chrome_render_thread_->set_print_dialog_user_response(false);
225   // Try to print with window.print() a few times.
226   PrintWithJavaScript();
227   PrintWithJavaScript();
228   PrintWithJavaScript();
229   VerifyPagesPrinted(false);
230 
231   // Pretend user will print. (but printing is blocked.)
232   chrome_render_thread_->set_print_dialog_user_response(true);
233   PrintWithJavaScript();
234   VerifyPagesPrinted(false);
235 
236   // Unblock script initiated printing and verify printing works.
237   PrintWebViewHelper::Get(view_)->ResetScriptedPrintCount();
238   chrome_render_thread_->printer()->ResetPrinter();
239   PrintWithJavaScript();
240   VerifyPageCount(1);
241   VerifyPagesPrinted(true);
242 }
243 
244 // Tests that the renderer always allows window.print() calls if they are user
245 // initiated.
TEST_F(PrintWebViewHelperTest,AllowUserOriginatedPrinting)246 TEST_F(PrintWebViewHelperTest, AllowUserOriginatedPrinting) {
247   // Pretend user will cancel printing.
248   chrome_render_thread_->set_print_dialog_user_response(false);
249   // Try to print with window.print() a few times.
250   PrintWithJavaScript();
251   PrintWithJavaScript();
252   PrintWithJavaScript();
253   VerifyPagesPrinted(false);
254 
255   // Pretend user will print. (but printing is blocked.)
256   chrome_render_thread_->set_print_dialog_user_response(true);
257   PrintWithJavaScript();
258   VerifyPagesPrinted(false);
259 
260   // Try again as if user initiated, without resetting the print count.
261   chrome_render_thread_->printer()->ResetPrinter();
262   LoadHTML(kPrintOnUserAction);
263   gfx::Size new_size(200, 100);
264   Resize(new_size, gfx::Rect(), false);
265 
266   gfx::Rect bounds = GetElementBounds("print");
267   EXPECT_FALSE(bounds.IsEmpty());
268   blink::WebMouseEvent mouse_event;
269   mouse_event.type = blink::WebInputEvent::MouseDown;
270   mouse_event.button = blink::WebMouseEvent::ButtonLeft;
271   mouse_event.x = bounds.CenterPoint().x();
272   mouse_event.y = bounds.CenterPoint().y();
273   mouse_event.clickCount = 1;
274   SendWebMouseEvent(mouse_event);
275   mouse_event.type = blink::WebInputEvent::MouseUp;
276   SendWebMouseEvent(mouse_event);
277   ProcessPendingMessages();
278 
279   VerifyPageCount(1);
280   VerifyPagesPrinted(true);
281 }
282 
TEST_F(PrintWebViewHelperTest,BlockScriptInitiatedPrintingFromPopup)283 TEST_F(PrintWebViewHelperTest, BlockScriptInitiatedPrintingFromPopup) {
284   PrintWebViewHelper* print_web_view_helper = PrintWebViewHelper::Get(view_);
285   print_web_view_helper->SetScriptedPrintBlocked(true);
286   PrintWithJavaScript();
287   VerifyPagesPrinted(false);
288 
289   print_web_view_helper->SetScriptedPrintBlocked(false);
290   PrintWithJavaScript();
291   VerifyPageCount(1);
292   VerifyPagesPrinted(true);
293 }
294 
295 #if defined(OS_WIN) || defined(OS_MACOSX)
296 // TODO(estade): I don't think this test is worth porting to Linux. We will have
297 // to rip out and replace most of the IPC code if we ever plan to improve
298 // printing, and the comment below by sverrir suggests that it doesn't do much
299 // for us anyway.
TEST_F(PrintWebViewHelperTest,PrintWithIframe)300 TEST_F(PrintWebViewHelperTest, PrintWithIframe) {
301   // Document that populates an iframe.
302   const char html[] =
303       "<html><body>Lorem Ipsum:"
304       "<iframe name=\"sub1\" id=\"sub1\"></iframe><script>"
305       "  document.write(frames['sub1'].name);"
306       "  frames['sub1'].document.write("
307       "      '<p>Cras tempus ante eu felis semper luctus!</p>');"
308       "</script></body></html>";
309 
310   LoadHTML(html);
311 
312   // Find the frame and set it as the focused one.  This should mean that that
313   // the printout should only contain the contents of that frame.
314   WebFrame* sub1_frame =
315       view_->GetWebView()->findFrameByName(WebString::fromUTF8("sub1"));
316   ASSERT_TRUE(sub1_frame);
317   view_->GetWebView()->setFocusedFrame(sub1_frame);
318   ASSERT_NE(view_->GetWebView()->focusedFrame(),
319             view_->GetWebView()->mainFrame());
320 
321   // Initiate printing.
322   OnPrintPages();
323   VerifyPagesPrinted(true);
324 
325   // Verify output through MockPrinter.
326   const MockPrinter* printer(chrome_render_thread_->printer());
327   ASSERT_EQ(1, printer->GetPrintedPages());
328   const Image& image1(printer->GetPrintedPage(0)->image());
329 
330   // TODO(sverrir): Figure out a way to improve this test to actually print
331   // only the content of the iframe.  Currently image1 will contain the full
332   // page.
333   EXPECT_NE(0, image1.size().width());
334   EXPECT_NE(0, image1.size().height());
335 }
336 #endif
337 
338 // Tests if we can print a page and verify its results.
339 // This test prints HTML pages into a pseudo printer and check their outputs,
340 // i.e. a simplified version of the PrintingLayoutTextTest UI test.
341 namespace {
342 // Test cases used in this test.
343 struct TestPageData {
344   const char* page;
345   size_t printed_pages;
346   int width;
347   int height;
348   const char* checksum;
349   const wchar_t* file;
350 };
351 
352 #if defined(OS_WIN) || defined(OS_MACOSX)
353 const TestPageData kTestPages[] = {
354   {"<html>"
355   "<head>"
356   "<meta"
357   "  http-equiv=\"Content-Type\""
358   "  content=\"text/html; charset=utf-8\"/>"
359   "<title>Test 1</title>"
360   "</head>"
361   "<body style=\"background-color: white;\">"
362   "<p style=\"font-family: arial;\">Hello World!</p>"
363   "</body>",
364 #if defined(OS_MACOSX)
365   // Mac printing code compensates for the WebKit scale factor while generating
366   // the metafile, so we expect smaller pages.
367   1, 600, 780,
368 #else
369   1, 675, 900,
370 #endif
371   NULL,
372   NULL,
373   },
374 };
375 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
376 }  // namespace
377 
378 // TODO(estade): need to port MockPrinter to get this on Linux. This involves
379 // hooking up Cairo to read a pdf stream, or accessing the cairo surface in the
380 // metafile directly.
381 #if defined(OS_WIN) || defined(OS_MACOSX)
TEST_F(PrintWebViewHelperTest,PrintLayoutTest)382 TEST_F(PrintWebViewHelperTest, PrintLayoutTest) {
383   bool baseline = false;
384 
385   EXPECT_TRUE(chrome_render_thread_->printer() != NULL);
386   for (size_t i = 0; i < arraysize(kTestPages); ++i) {
387     // Load an HTML page and print it.
388     LoadHTML(kTestPages[i].page);
389     OnPrintPages();
390     VerifyPagesPrinted(true);
391 
392     // MockRenderThread::Send() just calls MockRenderThread::OnReceived().
393     // So, all IPC messages sent in the above RenderView::OnPrintPages() call
394     // has been handled by the MockPrinter object, i.e. this printing job
395     // has been already finished.
396     // So, we can start checking the output pages of this printing job.
397     // Retrieve the number of pages actually printed.
398     size_t pages = chrome_render_thread_->printer()->GetPrintedPages();
399     EXPECT_EQ(kTestPages[i].printed_pages, pages);
400 
401     // Retrieve the width and height of the output page.
402     int width = chrome_render_thread_->printer()->GetWidth(0);
403     int height = chrome_render_thread_->printer()->GetHeight(0);
404 
405     // Check with margin for error.  This has been failing with a one pixel
406     // offset on our buildbot.
407     const int kErrorMargin = 5;  // 5%
408     EXPECT_GT(kTestPages[i].width * (100 + kErrorMargin) / 100, width);
409     EXPECT_LT(kTestPages[i].width * (100 - kErrorMargin) / 100, width);
410     EXPECT_GT(kTestPages[i].height * (100 + kErrorMargin) / 100, height);
411     EXPECT_LT(kTestPages[i].height* (100 - kErrorMargin) / 100, height);
412 
413     // Retrieve the checksum of the bitmap data from the pseudo printer and
414     // compare it with the expected result.
415     std::string bitmap_actual;
416     EXPECT_TRUE(
417         chrome_render_thread_->printer()->GetBitmapChecksum(0, &bitmap_actual));
418     if (kTestPages[i].checksum)
419       EXPECT_EQ(kTestPages[i].checksum, bitmap_actual);
420 
421     if (baseline) {
422       // Save the source data and the bitmap data into temporary files to
423       // create base-line results.
424       base::FilePath source_path;
425       base::CreateTemporaryFile(&source_path);
426       chrome_render_thread_->printer()->SaveSource(0, source_path);
427 
428       base::FilePath bitmap_path;
429       base::CreateTemporaryFile(&bitmap_path);
430       chrome_render_thread_->printer()->SaveBitmap(0, bitmap_path);
431     }
432   }
433 }
434 #endif
435 
436 // These print preview tests do not work on Chrome OS yet.
437 #if !defined(OS_CHROMEOS)
438 class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
439  public:
PrintWebViewHelperPreviewTest()440   PrintWebViewHelperPreviewTest() {}
~PrintWebViewHelperPreviewTest()441   virtual ~PrintWebViewHelperPreviewTest() {}
442 
SetUp()443   virtual void SetUp() OVERRIDE {
444     // Append the print preview switch before creating the PrintWebViewHelper.
445     CommandLine::ForCurrentProcess()->AppendSwitch(
446         switches::kRendererPrintPreview);
447 
448     ChromeRenderViewTest::SetUp();
449   }
450 
451  protected:
VerifyPrintPreviewCancelled(bool did_cancel)452   void VerifyPrintPreviewCancelled(bool did_cancel) {
453     bool print_preview_cancelled =
454         (render_thread_->sink().GetUniqueMessageMatching(
455             PrintHostMsg_PrintPreviewCancelled::ID) != NULL);
456     EXPECT_EQ(did_cancel, print_preview_cancelled);
457   }
458 
VerifyPrintPreviewFailed(bool did_fail)459   void VerifyPrintPreviewFailed(bool did_fail) {
460     bool print_preview_failed =
461         (render_thread_->sink().GetUniqueMessageMatching(
462             PrintHostMsg_PrintPreviewFailed::ID) != NULL);
463     EXPECT_EQ(did_fail, print_preview_failed);
464   }
465 
VerifyPrintPreviewGenerated(bool generated_preview)466   void VerifyPrintPreviewGenerated(bool generated_preview) {
467     const IPC::Message* preview_msg =
468         render_thread_->sink().GetUniqueMessageMatching(
469             PrintHostMsg_MetafileReadyForPrinting::ID);
470     bool did_get_preview_msg = (NULL != preview_msg);
471     ASSERT_EQ(generated_preview, did_get_preview_msg);
472     if (did_get_preview_msg) {
473       PrintHostMsg_MetafileReadyForPrinting::Param preview_param;
474       PrintHostMsg_MetafileReadyForPrinting::Read(preview_msg, &preview_param);
475       EXPECT_NE(0, preview_param.a.document_cookie);
476       EXPECT_NE(0, preview_param.a.expected_pages_count);
477       EXPECT_NE(0U, preview_param.a.data_size);
478     }
479   }
480 
VerifyPrintFailed(bool did_fail)481   void VerifyPrintFailed(bool did_fail) {
482     bool print_failed = (render_thread_->sink().GetUniqueMessageMatching(
483         PrintHostMsg_PrintingFailed::ID) != NULL);
484     EXPECT_EQ(did_fail, print_failed);
485   }
486 
VerifyPrintPreviewInvalidPrinterSettings(bool settings_invalid)487   void VerifyPrintPreviewInvalidPrinterSettings(bool settings_invalid) {
488     bool print_preview_invalid_printer_settings =
489         (render_thread_->sink().GetUniqueMessageMatching(
490             PrintHostMsg_PrintPreviewInvalidPrinterSettings::ID) != NULL);
491     EXPECT_EQ(settings_invalid, print_preview_invalid_printer_settings);
492   }
493 
494   // |page_number| is 0-based.
VerifyDidPreviewPage(bool generate_draft_pages,int page_number)495   void VerifyDidPreviewPage(bool generate_draft_pages, int page_number) {
496     bool msg_found = false;
497     size_t msg_count = render_thread_->sink().message_count();
498     for (size_t i = 0; i < msg_count; ++i) {
499       const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
500       if (msg->type() == PrintHostMsg_DidPreviewPage::ID) {
501         PrintHostMsg_DidPreviewPage::Param page_param;
502         PrintHostMsg_DidPreviewPage::Read(msg, &page_param);
503         if (page_param.a.page_number == page_number) {
504           msg_found = true;
505           if (generate_draft_pages)
506             EXPECT_NE(0U, page_param.a.data_size);
507           else
508             EXPECT_EQ(0U, page_param.a.data_size);
509           break;
510         }
511       }
512     }
513     ASSERT_EQ(generate_draft_pages, msg_found);
514   }
515 
VerifyDefaultPageLayout(int content_width,int content_height,int margin_top,int margin_bottom,int margin_left,int margin_right,bool page_has_print_css)516   void VerifyDefaultPageLayout(int content_width, int content_height,
517                                int margin_top, int margin_bottom,
518                                int margin_left, int margin_right,
519                                bool page_has_print_css) {
520     const IPC::Message* default_page_layout_msg =
521         render_thread_->sink().GetUniqueMessageMatching(
522             PrintHostMsg_DidGetDefaultPageLayout::ID);
523     bool did_get_default_page_layout_msg = (NULL != default_page_layout_msg);
524     if (did_get_default_page_layout_msg) {
525       PrintHostMsg_DidGetDefaultPageLayout::Param param;
526       PrintHostMsg_DidGetDefaultPageLayout::Read(default_page_layout_msg,
527                                                  &param);
528       EXPECT_EQ(content_width, param.a.content_width);
529       EXPECT_EQ(content_height, param.a.content_height);
530       EXPECT_EQ(margin_top, param.a.margin_top);
531       EXPECT_EQ(margin_right, param.a.margin_right);
532       EXPECT_EQ(margin_left, param.a.margin_left);
533       EXPECT_EQ(margin_bottom, param.a.margin_bottom);
534       EXPECT_EQ(page_has_print_css, param.c);
535     }
536   }
537 
538   DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest);
539 };
540 
541 // Tests that print preview work and sending and receiving messages through
542 // that channel all works.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreview)543 TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) {
544   LoadHTML(kHelloWorldHTML);
545 
546   // Fill in some dummy values.
547   base::DictionaryValue dict;
548   CreatePrintSettingsDictionary(&dict);
549   OnPrintPreview(dict);
550 
551   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
552   VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false);
553   VerifyPrintPreviewCancelled(false);
554   VerifyPrintPreviewFailed(false);
555   VerifyPrintPreviewGenerated(true);
556   VerifyPagesPrinted(false);
557 }
558 
TEST_F(PrintWebViewHelperPreviewTest,PrintPreviewHTMLWithPageMarginsCss)559 TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewHTMLWithPageMarginsCss) {
560   // A simple web page with print margins css.
561   const char kHTMLWithPageMarginsCss[] =
562       "<html><head><style>"
563       "@media print {"
564       "  @page {"
565       "     margin: 3in 1in 2in 0.3in;"
566       "  }"
567       "}"
568       "</style></head>"
569       "<body>Lorem Ipsum:"
570       "</body></html>";
571   LoadHTML(kHTMLWithPageMarginsCss);
572 
573   // Fill in some dummy values.
574   base::DictionaryValue dict;
575   CreatePrintSettingsDictionary(&dict);
576   dict.SetBoolean(kSettingPrintToPDF, false);
577   dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS);
578   OnPrintPreview(dict);
579 
580   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
581   VerifyDefaultPageLayout(519, 432, 216, 144, 21, 72, false);
582   VerifyPrintPreviewCancelled(false);
583   VerifyPrintPreviewFailed(false);
584   VerifyPrintPreviewGenerated(true);
585   VerifyPagesPrinted(false);
586 }
587 
588 // Test to verify that print preview ignores print media css when non-default
589 // margin is selected.
TEST_F(PrintWebViewHelperPreviewTest,NonDefaultMarginsSelectedIgnorePrintCss)590 TEST_F(PrintWebViewHelperPreviewTest, NonDefaultMarginsSelectedIgnorePrintCss) {
591   LoadHTML(kHTMLWithPageSizeCss);
592 
593   // Fill in some dummy values.
594   base::DictionaryValue dict;
595   CreatePrintSettingsDictionary(&dict);
596   dict.SetBoolean(kSettingPrintToPDF, false);
597   dict.SetInteger(kSettingMarginsType, NO_MARGINS);
598   OnPrintPreview(dict);
599 
600   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
601   VerifyDefaultPageLayout(612, 792, 0, 0, 0, 0, true);
602   VerifyPrintPreviewCancelled(false);
603   VerifyPrintPreviewFailed(false);
604   VerifyPrintPreviewGenerated(true);
605   VerifyPagesPrinted(false);
606 }
607 
608 // Test to verify that print preview honor print media size css when
609 // PRINT_TO_PDF is selected and doesn't fit to printer default paper size.
TEST_F(PrintWebViewHelperPreviewTest,PrintToPDFSelectedHonorPrintCss)610 TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPrintCss) {
611   LoadHTML(kHTMLWithPageSizeCss);
612 
613   // Fill in some dummy values.
614   base::DictionaryValue dict;
615   CreatePrintSettingsDictionary(&dict);
616   dict.SetBoolean(kSettingPrintToPDF, true);
617   dict.SetInteger(kSettingMarginsType,
618                   PRINTABLE_AREA_MARGINS);
619   OnPrintPreview(dict);
620 
621   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
622   // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page
623   // size.
624   VerifyDefaultPageLayout(252, 252, 18, 18, 18, 18, true);
625   VerifyPrintPreviewCancelled(false);
626   VerifyPrintPreviewFailed(false);
627 }
628 
629 // Test to verify that print preview honor print margin css when PRINT_TO_PDF
630 // is selected and doesn't fit to printer default paper size.
TEST_F(PrintWebViewHelperPreviewTest,PrintToPDFSelectedHonorPageMarginsCss)631 TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPageMarginsCss) {
632   // A simple web page with print margins css.
633   const char kHTMLWithPageCss[] =
634       "<html><head><style>"
635       "@media print {"
636       "  @page {"
637       "     margin: 3in 1in 2in 0.3in;"
638       "     size: 14in 14in;"
639       "  }"
640       "}"
641       "</style></head>"
642       "<body>Lorem Ipsum:"
643       "</body></html>";
644   LoadHTML(kHTMLWithPageCss);
645 
646   // Fill in some dummy values.
647   base::DictionaryValue dict;
648   CreatePrintSettingsDictionary(&dict);
649   dict.SetBoolean(kSettingPrintToPDF, true);
650   dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS);
651   OnPrintPreview(dict);
652 
653   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
654   // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page
655   // size.
656   VerifyDefaultPageLayout(915, 648, 216, 144, 21, 72, true);
657   VerifyPrintPreviewCancelled(false);
658   VerifyPrintPreviewFailed(false);
659 }
660 
661 // Test to verify that print preview workflow center the html page contents to
662 // fit the page size.
TEST_F(PrintWebViewHelperPreviewTest,PrintPreviewCenterToFitPage)663 TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewCenterToFitPage) {
664   LoadHTML(kHTMLWithPageSizeCss);
665 
666   // Fill in some dummy values.
667   base::DictionaryValue dict;
668   CreatePrintSettingsDictionary(&dict);
669   dict.SetBoolean(kSettingPrintToPDF, false);
670   dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS);
671   OnPrintPreview(dict);
672 
673   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
674   VerifyDefaultPageLayout(216, 216, 288, 288, 198, 198, true);
675   VerifyPrintPreviewCancelled(false);
676   VerifyPrintPreviewFailed(false);
677   VerifyPrintPreviewGenerated(true);
678 }
679 
680 // Test to verify that print preview workflow scale the html page contents to
681 // fit the page size.
TEST_F(PrintWebViewHelperPreviewTest,PrintPreviewShrinkToFitPage)682 TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewShrinkToFitPage) {
683   // A simple web page with print margins css.
684   const char kHTMLWithPageCss[] =
685       "<html><head><style>"
686       "@media print {"
687       "  @page {"
688       "     size: 15in 17in;"
689       "  }"
690       "}"
691       "</style></head>"
692       "<body>Lorem Ipsum:"
693       "</body></html>";
694   LoadHTML(kHTMLWithPageCss);
695 
696   // Fill in some dummy values.
697   base::DictionaryValue dict;
698   CreatePrintSettingsDictionary(&dict);
699   dict.SetBoolean(kSettingPrintToPDF, false);
700   dict.SetInteger(kSettingMarginsType, DEFAULT_MARGINS);
701   OnPrintPreview(dict);
702 
703   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
704   VerifyDefaultPageLayout(571, 652, 69, 71, 20, 21, true);
705   VerifyPrintPreviewCancelled(false);
706   VerifyPrintPreviewFailed(false);
707 }
708 
709 // Test to verify that print preview workflow honor the orientation settings
710 // specified in css.
TEST_F(PrintWebViewHelperPreviewTest,PrintPreviewHonorsOrientationCss)711 TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewHonorsOrientationCss) {
712   LoadHTML(kHTMLWithLandscapePageCss);
713 
714   // Fill in some dummy values.
715   base::DictionaryValue dict;
716   CreatePrintSettingsDictionary(&dict);
717   dict.SetBoolean(kSettingPrintToPDF, false);
718   dict.SetInteger(kSettingMarginsType, NO_MARGINS);
719   OnPrintPreview(dict);
720 
721   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
722   VerifyDefaultPageLayout(792, 612, 0, 0, 0, 0, true);
723   VerifyPrintPreviewCancelled(false);
724   VerifyPrintPreviewFailed(false);
725 }
726 
727 // Test to verify that print preview workflow honors the orientation settings
728 // specified in css when PRINT_TO_PDF is selected.
TEST_F(PrintWebViewHelperPreviewTest,PrintToPDFSelectedHonorOrientationCss)729 TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorOrientationCss) {
730   LoadHTML(kHTMLWithLandscapePageCss);
731 
732   // Fill in some dummy values.
733   base::DictionaryValue dict;
734   CreatePrintSettingsDictionary(&dict);
735   dict.SetBoolean(kSettingPrintToPDF, true);
736   dict.SetInteger(kSettingMarginsType, CUSTOM_MARGINS);
737   OnPrintPreview(dict);
738 
739   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
740   VerifyDefaultPageLayout(748, 568, 21, 23, 21, 23, true);
741   VerifyPrintPreviewCancelled(false);
742   VerifyPrintPreviewFailed(false);
743 }
744 
745 // Test to verify that complete metafile is generated for a subset of pages
746 // without creating draft pages.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewForSelectedPages)747 TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedPages) {
748   LoadHTML(kMultipageHTML);
749 
750   // Fill in some dummy values.
751   base::DictionaryValue dict;
752   CreatePrintSettingsDictionary(&dict);
753 
754   // Set a page range and update the dictionary to generate only the complete
755   // metafile with the selected pages. Page numbers used in the dictionary
756   // are 1-based.
757   base::DictionaryValue* page_range = new base::DictionaryValue();
758   page_range->SetInteger(kSettingPageRangeFrom, 2);
759   page_range->SetInteger(kSettingPageRangeTo, 3);
760 
761   base::ListValue* page_range_array = new base::ListValue();
762   page_range_array->Append(page_range);
763 
764   dict.Set(kSettingPageRange, page_range_array);
765   dict.SetBoolean(kSettingGenerateDraftData, false);
766 
767   OnPrintPreview(dict);
768 
769   VerifyDidPreviewPage(false, 0);
770   VerifyDidPreviewPage(false, 1);
771   VerifyDidPreviewPage(false, 2);
772   VerifyPreviewPageCount(3);
773   VerifyPrintPreviewCancelled(false);
774   VerifyPrintPreviewFailed(false);
775   VerifyPrintPreviewGenerated(true);
776   VerifyPagesPrinted(false);
777 }
778 
779 // Test to verify that preview generated only for one page.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewForSelectedText)780 TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedText) {
781   LoadHTML(kMultipageHTML);
782   GetMainFrame()->selectRange(
783       blink::WebRange::fromDocumentRange(GetMainFrame(), 1, 3));
784 
785   // Fill in some dummy values.
786   base::DictionaryValue dict;
787   CreatePrintSettingsDictionary(&dict);
788   dict.SetBoolean(kSettingShouldPrintSelectionOnly, true);
789 
790   OnPrintPreview(dict);
791 
792   VerifyPreviewPageCount(1);
793   VerifyPrintPreviewCancelled(false);
794   VerifyPrintPreviewFailed(false);
795   VerifyPrintPreviewGenerated(true);
796   VerifyPagesPrinted(false);
797 }
798 
799 // Tests that print preview fails and receiving error messages through
800 // that channel all works.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewFail)801 TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewFail) {
802   LoadHTML(kHelloWorldHTML);
803 
804   // An empty dictionary should fail.
805   base::DictionaryValue empty_dict;
806   OnPrintPreview(empty_dict);
807 
808   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
809   VerifyPrintPreviewCancelled(false);
810   VerifyPrintPreviewFailed(true);
811   VerifyPrintPreviewGenerated(false);
812   VerifyPagesPrinted(false);
813 }
814 
815 // Tests that cancelling print preview works.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewCancel)816 TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) {
817   LoadHTML(kLongPageHTML);
818 
819   const int kCancelPage = 3;
820   chrome_render_thread_->set_print_preview_cancel_page_number(kCancelPage);
821   // Fill in some dummy values.
822   base::DictionaryValue dict;
823   CreatePrintSettingsDictionary(&dict);
824   OnPrintPreview(dict);
825 
826   EXPECT_EQ(kCancelPage,
827             chrome_render_thread_->print_preview_pages_remaining());
828   VerifyPrintPreviewCancelled(true);
829   VerifyPrintPreviewFailed(false);
830   VerifyPrintPreviewGenerated(false);
831   VerifyPagesPrinted(false);
832 }
833 
834 // Tests that printing from print preview works and sending and receiving
835 // messages through that channel all works.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintForPrintPreview)836 TEST_F(PrintWebViewHelperPreviewTest, OnPrintForPrintPreview) {
837   LoadHTML(kPrintPreviewHTML);
838 
839   // Fill in some dummy values.
840   base::DictionaryValue dict;
841   CreatePrintSettingsDictionary(&dict);
842   OnPrintForPrintPreview(dict);
843 
844   VerifyPrintFailed(false);
845   VerifyPagesPrinted(true);
846 }
847 
848 // Tests that printing from print preview fails and receiving error messages
849 // through that channel all works.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintForPrintPreviewFail)850 TEST_F(PrintWebViewHelperPreviewTest, OnPrintForPrintPreviewFail) {
851   LoadHTML(kPrintPreviewHTML);
852 
853   // An empty dictionary should fail.
854   base::DictionaryValue empty_dict;
855   OnPrintForPrintPreview(empty_dict);
856 
857   VerifyPagesPrinted(false);
858 }
859 
860 // Tests that when default printer has invalid printer settings, print preview
861 // receives error message.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewUsingInvalidPrinterSettings)862 TEST_F(PrintWebViewHelperPreviewTest,
863        OnPrintPreviewUsingInvalidPrinterSettings) {
864   LoadHTML(kPrintPreviewHTML);
865 
866   // Set mock printer to provide invalid settings.
867   chrome_render_thread_->printer()->UseInvalidSettings();
868 
869   // Fill in some dummy values.
870   base::DictionaryValue dict;
871   CreatePrintSettingsDictionary(&dict);
872   OnPrintPreview(dict);
873 
874   // We should have received invalid printer settings from |printer_|.
875   VerifyPrintPreviewInvalidPrinterSettings(true);
876   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
877 
878   // It should receive the invalid printer settings message only.
879   VerifyPrintPreviewFailed(false);
880   VerifyPrintPreviewGenerated(false);
881 }
882 
883 // Tests that when the selected printer has invalid page settings, print preview
884 // receives error message.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewUsingInvalidPageSize)885 TEST_F(PrintWebViewHelperPreviewTest,
886        OnPrintPreviewUsingInvalidPageSize) {
887   LoadHTML(kPrintPreviewHTML);
888 
889   chrome_render_thread_->printer()->UseInvalidPageSize();
890 
891   base::DictionaryValue dict;
892   CreatePrintSettingsDictionary(&dict);
893   OnPrintPreview(dict);
894 
895   VerifyPrintPreviewInvalidPrinterSettings(true);
896   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
897 
898   // It should receive the invalid printer settings message only.
899   VerifyPrintPreviewFailed(false);
900   VerifyPrintPreviewGenerated(false);
901 }
902 
903 // Tests that when the selected printer has invalid content settings, print
904 // preview receives error message.
TEST_F(PrintWebViewHelperPreviewTest,OnPrintPreviewUsingInvalidContentSize)905 TEST_F(PrintWebViewHelperPreviewTest,
906        OnPrintPreviewUsingInvalidContentSize) {
907   LoadHTML(kPrintPreviewHTML);
908 
909   chrome_render_thread_->printer()->UseInvalidContentSize();
910 
911   base::DictionaryValue dict;
912   CreatePrintSettingsDictionary(&dict);
913   OnPrintPreview(dict);
914 
915   VerifyPrintPreviewInvalidPrinterSettings(true);
916   EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
917 
918   // It should receive the invalid printer settings message only.
919   VerifyPrintPreviewFailed(false);
920   VerifyPrintPreviewGenerated(false);
921 }
922 
TEST_F(PrintWebViewHelperPreviewTest,OnPrintForPrintPreviewUsingInvalidPrinterSettings)923 TEST_F(PrintWebViewHelperPreviewTest,
924        OnPrintForPrintPreviewUsingInvalidPrinterSettings) {
925   LoadHTML(kPrintPreviewHTML);
926 
927   // Set mock printer to provide invalid settings.
928   chrome_render_thread_->printer()->UseInvalidSettings();
929 
930   // Fill in some dummy values.
931   base::DictionaryValue dict;
932   CreatePrintSettingsDictionary(&dict);
933   OnPrintForPrintPreview(dict);
934 
935   VerifyPrintFailed(true);
936   VerifyPagesPrinted(false);
937 }
938 
939 #endif  // !defined(OS_CHROMEOS)
940 
941 class PrintWebViewHelperKioskTest : public PrintWebViewHelperTestBase {
942  public:
PrintWebViewHelperKioskTest()943   PrintWebViewHelperKioskTest() {}
~PrintWebViewHelperKioskTest()944   virtual ~PrintWebViewHelperKioskTest() {}
945 
SetUp()946   virtual void SetUp() OVERRIDE {
947     // Append the throttling disable switch before creating the
948     // PrintWebViewHelper.
949     CommandLine::ForCurrentProcess()->AppendSwitch(
950         switches::kDisableScriptedPrintThrottling);
951 
952     ChromeRenderViewTest::SetUp();
953   }
954 
955  protected:
956   DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperKioskTest);
957 };
958 
959 // Tests that the switch overrides the throttling that blocks window.print()
960 // calls if they occur too frequently. Compare with
961 // PrintWebViewHelperTest.BlockScriptInitiatedPrinting above.
TEST_F(PrintWebViewHelperKioskTest,DontBlockScriptInitiatedPrinting)962 TEST_F(PrintWebViewHelperKioskTest, DontBlockScriptInitiatedPrinting) {
963   // Pretend user will cancel printing.
964   chrome_render_thread_->set_print_dialog_user_response(false);
965   // Try to print with window.print() a few times.
966   PrintWithJavaScript();
967   chrome_render_thread_->printer()->ResetPrinter();
968   PrintWithJavaScript();
969   chrome_render_thread_->printer()->ResetPrinter();
970   PrintWithJavaScript();
971   chrome_render_thread_->printer()->ResetPrinter();
972   VerifyPagesPrinted(false);
973 
974   // Pretend user will print, should not be throttled.
975   chrome_render_thread_->set_print_dialog_user_response(true);
976   PrintWithJavaScript();
977   VerifyPagesPrinted(true);
978 }
979 
980 }  // namespace printing
981