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