OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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/file_util.h" |
| 6 #include "chrome/renderer/print_web_view_helper.h" |
| 7 #include "chrome/renderer/render_view_wrapper.h" |
| 8 #include "chrome/test/render_view_test.h" |
| 9 #include "printing/image.h" |
| 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 13 |
| 14 using WebKit::WebFrame; |
| 15 using WebKit::WebString; |
| 16 |
| 17 namespace { |
| 18 |
| 19 const char kPrintWithJSHTML[] = |
| 20 "<body>Hello<script>window.print()</script>World</body>"; |
| 21 |
| 22 namespace { |
| 23 // Test cases used in this test. |
| 24 struct TestPageData { |
| 25 const char* page; |
| 26 size_t printed_pages; |
| 27 int width; |
| 28 int height; |
| 29 const char* checksum; |
| 30 const wchar_t* file; |
| 31 }; |
| 32 |
| 33 const TestPageData kTestPages[] = { |
| 34 {"<html>" |
| 35 "<head>" |
| 36 "<meta" |
| 37 " http-equiv=\"Content-Type\"" |
| 38 " content=\"text/html; charset=utf-8\"/>" |
| 39 "<title>Test 1</title>" |
| 40 "</head>" |
| 41 "<body style=\"background-color: white;\">" |
| 42 "<p style=\"font-family: arial;\">Hello World!</p>" |
| 43 "</body>", |
| 44 #if defined(OS_MACOSX) |
| 45 // Mac printing code compensates for the WebKit scale factor while generating |
| 46 // the metafile, so we expect smaller pages. |
| 47 1, 540, 720, |
| 48 #else |
| 49 1, 675, 900, |
| 50 #endif |
| 51 NULL, |
| 52 NULL, |
| 53 }, |
| 54 }; |
| 55 } // namespace |
| 56 |
| 57 } // namespace |
| 58 |
| 59 // Tests that printing pages work and sending and receiving messages through |
| 60 // that channel all works. |
| 61 TEST_F(RenderViewTest, OnPrintPages) { |
| 62 // Lets simulate a print pages with Hello world. |
| 63 LoadHTML("<body><p>Hello World!</p></body>"); |
| 64 print_helper_->OnPrintPages(); |
| 65 |
| 66 VerifyPageCount(1); |
| 67 VerifyPagesPrinted(true); |
| 68 } |
| 69 |
| 70 // Duplicate of OnPrintPagesTest only using javascript to print. |
| 71 TEST_F(RenderViewTest, PrintWithJavascript) { |
| 72 // HTML contains a call to window.print() |
| 73 LoadHTML(kPrintWithJSHTML); |
| 74 |
| 75 VerifyPageCount(1); |
| 76 VerifyPagesPrinted(true); |
| 77 } |
| 78 |
| 79 // Tests that the renderer blocks window.print() calls if they occur too |
| 80 // frequently. |
| 81 TEST_F(RenderViewTest, BlockScriptInitiatedPrinting) { |
| 82 // Pretend user will cancel printing. |
| 83 render_thread_.set_print_dialog_user_response(false); |
| 84 // Try to print with window.print() a few times. |
| 85 LoadHTML(kPrintWithJSHTML); |
| 86 LoadHTML(kPrintWithJSHTML); |
| 87 LoadHTML(kPrintWithJSHTML); |
| 88 VerifyPagesPrinted(false); |
| 89 |
| 90 // Pretend user will print. (but printing is blocked.) |
| 91 render_thread_.set_print_dialog_user_response(true); |
| 92 LoadHTML(kPrintWithJSHTML); |
| 93 VerifyPagesPrinted(false); |
| 94 |
| 95 // Unblock script initiated printing and verify printing works. |
| 96 print_helper_->ResetScriptedPrintCount(); |
| 97 render_thread_.printer()->ResetPrinter(); |
| 98 LoadHTML(kPrintWithJSHTML); |
| 99 VerifyPageCount(1); |
| 100 VerifyPagesPrinted(true); |
| 101 } |
| 102 |
| 103 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 104 // TODO(estade): I don't think this test is worth porting to Linux. We will have |
| 105 // to rip out and replace most of the IPC code if we ever plan to improve |
| 106 // printing, and the comment below by sverrir suggests that it doesn't do much |
| 107 // for us anyway. |
| 108 TEST_F(RenderViewTest, PrintWithIframe) { |
| 109 // Document that populates an iframe. |
| 110 const char html[] = |
| 111 "<html><body>Lorem Ipsum:" |
| 112 "<iframe name=\"sub1\" id=\"sub1\"></iframe><script>" |
| 113 " document.write(frames['sub1'].name);" |
| 114 " frames['sub1'].document.write(" |
| 115 " '<p>Cras tempus ante eu felis semper luctus!</p>');" |
| 116 "</script></body></html>"; |
| 117 |
| 118 LoadHTML(html); |
| 119 |
| 120 // Find the frame and set it as the focused one. This should mean that that |
| 121 // the printout should only contain the contents of that frame. |
| 122 WebFrame* sub1_frame = |
| 123 view_->webview()->findFrameByName(WebString::fromUTF8("sub1")); |
| 124 ASSERT_TRUE(sub1_frame); |
| 125 view_->webview()->setFocusedFrame(sub1_frame); |
| 126 ASSERT_NE(view_->webview()->focusedFrame(), |
| 127 view_->webview()->mainFrame()); |
| 128 |
| 129 // Initiate printing. |
| 130 print_helper_->OnPrintPages(); |
| 131 |
| 132 // Verify output through MockPrinter. |
| 133 const MockPrinter* printer(render_thread_.printer()); |
| 134 ASSERT_EQ(1, printer->GetPrintedPages()); |
| 135 const printing::Image& image1(printer->GetPrintedPage(0)->image()); |
| 136 |
| 137 // TODO(sverrir): Figure out a way to improve this test to actually print |
| 138 // only the content of the iframe. Currently image1 will contain the full |
| 139 // page. |
| 140 EXPECT_NE(0, image1.size().width()); |
| 141 EXPECT_NE(0, image1.size().height()); |
| 142 } |
| 143 #endif |
| 144 |
| 145 // TODO(estade): need to port MockPrinter to get this on Linux. This involves |
| 146 // hooking up Cairo to read a pdf stream, or accessing the cairo surface in the |
| 147 // metafile directly. |
| 148 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 149 TEST_F(RenderViewTest, PrintLayoutTest) { |
| 150 bool baseline = false; |
| 151 |
| 152 EXPECT_TRUE(render_thread_.printer() != NULL); |
| 153 for (size_t i = 0; i < arraysize(kTestPages); ++i) { |
| 154 // Load an HTML page and print it. |
| 155 LoadHTML(kTestPages[i].page); |
| 156 print_helper_->OnPrintPages(); |
| 157 |
| 158 // MockRenderThread::Send() just calls MockRenderThread::OnMsgReceived(). |
| 159 // So, all IPC messages sent in the above RenderView::OnPrintPages() call |
| 160 // has been handled by the MockPrinter object, i.e. this printing job |
| 161 // has been already finished. |
| 162 // So, we can start checking the output pages of this printing job. |
| 163 // Retrieve the number of pages actually printed. |
| 164 size_t pages = render_thread_.printer()->GetPrintedPages(); |
| 165 EXPECT_EQ(kTestPages[i].printed_pages, pages); |
| 166 |
| 167 // Retrieve the width and height of the output page. |
| 168 int width = render_thread_.printer()->GetWidth(0); |
| 169 int height = render_thread_.printer()->GetHeight(0); |
| 170 |
| 171 // Check with margin for error. This has been failing with a one pixel |
| 172 // offset on our buildbot. |
| 173 const int kErrorMargin = 5; // 5% |
| 174 EXPECT_GT(kTestPages[i].width * (100 + kErrorMargin) / 100, width); |
| 175 EXPECT_LT(kTestPages[i].width * (100 - kErrorMargin) / 100, width); |
| 176 EXPECT_GT(kTestPages[i].height * (100 + kErrorMargin) / 100, height); |
| 177 EXPECT_LT(kTestPages[i].height* (100 - kErrorMargin) / 100, height); |
| 178 |
| 179 // Retrieve the checksum of the bitmap data from the pseudo printer and |
| 180 // compare it with the expected result. |
| 181 std::string bitmap_actual; |
| 182 EXPECT_TRUE(render_thread_.printer()->GetBitmapChecksum(0, &bitmap_actual)); |
| 183 if (kTestPages[i].checksum) |
| 184 EXPECT_EQ(kTestPages[i].checksum, bitmap_actual); |
| 185 |
| 186 if (baseline) { |
| 187 // Save the source data and the bitmap data into temporary files to |
| 188 // create base-line results. |
| 189 FilePath source_path; |
| 190 file_util::CreateTemporaryFile(&source_path); |
| 191 render_thread_.printer()->SaveSource(0, source_path); |
| 192 |
| 193 FilePath bitmap_path; |
| 194 file_util::CreateTemporaryFile(&bitmap_path); |
| 195 render_thread_.printer()->SaveBitmap(0, bitmap_path); |
| 196 } |
| 197 } |
| 198 } |
| 199 #endif |
OLD | NEW |