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 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: 108 PrintWebViewHelperTestBase() {} 109 virtual ~PrintWebViewHelperTestBase() {} 110 111 protected: 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. 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. 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. 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 } 169 void OnPrintPages() { 170 PrintWebViewHelper::Get(view_)->OnPrintPages(); 171 ProcessPendingMessages(); 172 } 173 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 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: 191 PrintWebViewHelperTest() {} 192 virtual ~PrintWebViewHelperTest() {} 193 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. 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. 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. 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. 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 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. 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) 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: 440 PrintWebViewHelperPreviewTest() {} 441 virtual ~PrintWebViewHelperPreviewTest() {} 442 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: 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 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 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 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 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. 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 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 ¶m); 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. 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 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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 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: 943 PrintWebViewHelperKioskTest() {} 944 virtual ~PrintWebViewHelperKioskTest() {} 945 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. 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