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