OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 | 6 |
7 #include "base/file_util.h" | |
8 #include "base/shared_memory.h" | |
9 #include "base/string_util.h" | 7 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
11 #include "chrome/common/autofill_messages.h" | 9 #include "chrome/common/autofill_messages.h" |
12 #include "chrome/common/content_settings.h" | 10 #include "chrome/common/content_settings.h" |
13 #include "chrome/common/render_messages.h" | 11 #include "chrome/common/render_messages.h" |
14 #include "chrome/common/render_messages_params.h" | 12 #include "chrome/common/render_messages_params.h" |
15 #include "chrome/renderer/autofill/autofill_agent.h" | 13 #include "chrome/renderer/autofill/autofill_agent.h" |
16 #include "chrome/renderer/print_web_view_helper.h" | |
17 #include "chrome/test/render_view_test.h" | 14 #include "chrome/test/render_view_test.h" |
18 #include "content/common/native_web_keyboard_event.h" | 15 #include "content/common/native_web_keyboard_event.h" |
19 #include "content/common/view_messages.h" | 16 #include "content/common/view_messages.h" |
20 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
21 #include "printing/image.h" | |
22 #include "printing/native_metafile.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" |
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" |
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
29 #include "ui/base/keycodes/keyboard_codes.h" | 24 #include "ui/base/keycodes/keyboard_codes.h" |
30 #include "ui/gfx/codec/jpeg_codec.h" | |
31 #include "webkit/glue/form_data.h" | 25 #include "webkit/glue/form_data.h" |
32 #include "webkit/glue/form_field.h" | 26 #include "webkit/glue/form_field.h" |
33 #include "webkit/glue/web_io_operators.h" | 27 #include "webkit/glue/web_io_operators.h" |
34 | 28 |
35 using WebKit::WebDocument; | 29 using WebKit::WebDocument; |
36 using WebKit::WebFrame; | 30 using WebKit::WebFrame; |
37 using WebKit::WebInputElement; | 31 using WebKit::WebInputElement; |
38 using WebKit::WebString; | 32 using WebKit::WebString; |
39 using WebKit::WebTextDirection; | 33 using WebKit::WebTextDirection; |
40 using WebKit::WebURLError; | 34 using WebKit::WebURLError; |
41 using webkit_glue::FormData; | 35 using webkit_glue::FormData; |
42 using webkit_glue::FormField; | 36 using webkit_glue::FormField; |
43 | 37 |
44 namespace { | |
45 | |
46 const char kPrintWithJSHTML[] = | |
47 "<body>Hello<script>window.print()</script>World</body>"; | |
48 | |
49 } // namespace | |
50 | |
51 // Test that we get form state change notifications when input fields change. | 38 // Test that we get form state change notifications when input fields change. |
52 TEST_F(RenderViewTest, OnNavStateChanged) { | 39 TEST_F(RenderViewTest, OnNavStateChanged) { |
53 // Don't want any delay for form state sync changes. This will still post a | 40 // Don't want any delay for form state sync changes. This will still post a |
54 // message so updates will get coalesced, but as soon as we spin the message | 41 // message so updates will get coalesced, but as soon as we spin the message |
55 // loop, it will generate an update. | 42 // loop, it will generate an update. |
56 view_->set_send_content_state_immediately(true); | 43 view_->set_send_content_state_immediately(true); |
57 | 44 |
58 LoadHTML("<input type=\"text\" id=\"elt_text\"></input>"); | 45 LoadHTML("<input type=\"text\" id=\"elt_text\"></input>"); |
59 | 46 |
60 // We should NOT have gotten a form state change notification yet. | 47 // We should NOT have gotten a form state change notification yet. |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 377 |
391 // Copy the document content to std::wstring and compare with the | 378 // Copy the document content to std::wstring and compare with the |
392 // expected result. | 379 // expected result. |
393 const int kMaxOutputCharacters = 16; | 380 const int kMaxOutputCharacters = 16; |
394 std::wstring output = UTF16ToWideHack( | 381 std::wstring output = UTF16ToWideHack( |
395 GetMainFrame()->contentAsText(kMaxOutputCharacters)); | 382 GetMainFrame()->contentAsText(kMaxOutputCharacters)); |
396 EXPECT_EQ(output, kTextDirection[i].expected_result); | 383 EXPECT_EQ(output, kTextDirection[i].expected_result); |
397 } | 384 } |
398 } | 385 } |
399 | 386 |
400 // Tests that printing pages work and sending and receiving messages through | |
401 // that channel all works. | |
402 TEST_F(RenderViewTest, OnPrintPages) { | |
403 // Lets simulate a print pages with Hello world. | |
404 LoadHTML("<body><p>Hello World!</p></body>"); | |
405 view_->print_helper_->OnPrintPages(); | |
406 | |
407 VerifyPageCount(1); | |
408 VerifyPagesPrinted(true); | |
409 } | |
410 | |
411 // Duplicate of OnPrintPagesTest only using javascript to print. | |
412 TEST_F(RenderViewTest, PrintWithJavascript) { | |
413 // HTML contains a call to window.print() | |
414 LoadHTML(kPrintWithJSHTML); | |
415 | |
416 VerifyPageCount(1); | |
417 VerifyPagesPrinted(true); | |
418 } | |
419 | |
420 // Tests that the renderer blocks window.print() calls if they occur too | |
421 // frequently. | |
422 TEST_F(RenderViewTest, BlockScriptInitiatedPrinting) { | |
423 // Pretend user will cancel printing. | |
424 render_thread_.set_print_dialog_user_response(false); | |
425 // Try to print with window.print() a few times. | |
426 LoadHTML(kPrintWithJSHTML); | |
427 LoadHTML(kPrintWithJSHTML); | |
428 LoadHTML(kPrintWithJSHTML); | |
429 VerifyPagesPrinted(false); | |
430 | |
431 // Pretend user will print. (but printing is blocked.) | |
432 render_thread_.set_print_dialog_user_response(true); | |
433 LoadHTML(kPrintWithJSHTML); | |
434 VerifyPagesPrinted(false); | |
435 | |
436 // Unblock script initiated printing and verify printing works. | |
437 view_->print_helper_->ResetScriptedPrintCount(); | |
438 render_thread_.printer()->ResetPrinter(); | |
439 LoadHTML(kPrintWithJSHTML); | |
440 VerifyPageCount(1); | |
441 VerifyPagesPrinted(true); | |
442 } | |
443 | |
444 #if defined(OS_WIN) || defined(OS_MACOSX) | |
445 // TODO(estade): I don't think this test is worth porting to Linux. We will have | |
446 // to rip out and replace most of the IPC code if we ever plan to improve | |
447 // printing, and the comment below by sverrir suggests that it doesn't do much | |
448 // for us anyway. | |
449 TEST_F(RenderViewTest, PrintWithIframe) { | |
450 // Document that populates an iframe. | |
451 const char html[] = | |
452 "<html><body>Lorem Ipsum:" | |
453 "<iframe name=\"sub1\" id=\"sub1\"></iframe><script>" | |
454 " document.write(frames['sub1'].name);" | |
455 " frames['sub1'].document.write(" | |
456 " '<p>Cras tempus ante eu felis semper luctus!</p>');" | |
457 "</script></body></html>"; | |
458 | |
459 LoadHTML(html); | |
460 | |
461 // Find the frame and set it as the focused one. This should mean that that | |
462 // the printout should only contain the contents of that frame. | |
463 WebFrame* sub1_frame = | |
464 view_->webview()->findFrameByName(WebString::fromUTF8("sub1")); | |
465 ASSERT_TRUE(sub1_frame); | |
466 view_->webview()->setFocusedFrame(sub1_frame); | |
467 ASSERT_NE(view_->webview()->focusedFrame(), | |
468 view_->webview()->mainFrame()); | |
469 | |
470 // Initiate printing. | |
471 view_->print_helper_->OnPrintPages(); | |
472 | |
473 // Verify output through MockPrinter. | |
474 const MockPrinter* printer(render_thread_.printer()); | |
475 ASSERT_EQ(1, printer->GetPrintedPages()); | |
476 const printing::Image& image1(printer->GetPrintedPage(0)->image()); | |
477 | |
478 // TODO(sverrir): Figure out a way to improve this test to actually print | |
479 // only the content of the iframe. Currently image1 will contain the full | |
480 // page. | |
481 EXPECT_NE(0, image1.size().width()); | |
482 EXPECT_NE(0, image1.size().height()); | |
483 } | |
484 #endif | |
485 | |
486 // Tests if we can print a page and verify its results. | |
487 // This test prints HTML pages into a pseudo printer and check their outputs, | |
488 // i.e. a simplified version of the PrintingLayoutTextTest UI test. | |
489 namespace { | |
490 // Test cases used in this test. | |
491 struct TestPageData { | |
492 const char* page; | |
493 size_t printed_pages; | |
494 int width; | |
495 int height; | |
496 const char* checksum; | |
497 const wchar_t* file; | |
498 }; | |
499 | |
500 const TestPageData kTestPages[] = { | |
501 {"<html>" | |
502 "<head>" | |
503 "<meta" | |
504 " http-equiv=\"Content-Type\"" | |
505 " content=\"text/html; charset=utf-8\"/>" | |
506 "<title>Test 1</title>" | |
507 "</head>" | |
508 "<body style=\"background-color: white;\">" | |
509 "<p style=\"font-family: arial;\">Hello World!</p>" | |
510 "</body>", | |
511 #if defined(OS_MACOSX) | |
512 // Mac printing code compensates for the WebKit scale factor while generating | |
513 // the metafile, so we expect smaller pages. | |
514 1, 540, 720, | |
515 #else | |
516 1, 675, 900, | |
517 #endif | |
518 NULL, | |
519 NULL, | |
520 }, | |
521 }; | |
522 } // namespace | |
523 | |
524 // TODO(estade): need to port MockPrinter to get this on Linux. This involves | |
525 // hooking up Cairo to read a pdf stream, or accessing the cairo surface in the | |
526 // metafile directly. | |
527 #if defined(OS_WIN) || defined(OS_MACOSX) | |
528 TEST_F(RenderViewTest, PrintLayoutTest) { | |
529 bool baseline = false; | |
530 | |
531 EXPECT_TRUE(render_thread_.printer() != NULL); | |
532 for (size_t i = 0; i < arraysize(kTestPages); ++i) { | |
533 // Load an HTML page and print it. | |
534 LoadHTML(kTestPages[i].page); | |
535 view_->print_helper_->OnPrintPages(); | |
536 | |
537 // MockRenderThread::Send() just calls MockRenderThread::OnMsgReceived(). | |
538 // So, all IPC messages sent in the above RenderView::OnPrintPages() call | |
539 // has been handled by the MockPrinter object, i.e. this printing job | |
540 // has been already finished. | |
541 // So, we can start checking the output pages of this printing job. | |
542 // Retrieve the number of pages actually printed. | |
543 size_t pages = render_thread_.printer()->GetPrintedPages(); | |
544 EXPECT_EQ(kTestPages[i].printed_pages, pages); | |
545 | |
546 // Retrieve the width and height of the output page. | |
547 int width = render_thread_.printer()->GetWidth(0); | |
548 int height = render_thread_.printer()->GetHeight(0); | |
549 | |
550 // Check with margin for error. This has been failing with a one pixel | |
551 // offset on our buildbot. | |
552 const int kErrorMargin = 5; // 5% | |
553 EXPECT_GT(kTestPages[i].width * (100 + kErrorMargin) / 100, width); | |
554 EXPECT_LT(kTestPages[i].width * (100 - kErrorMargin) / 100, width); | |
555 EXPECT_GT(kTestPages[i].height * (100 + kErrorMargin) / 100, height); | |
556 EXPECT_LT(kTestPages[i].height* (100 - kErrorMargin) / 100, height); | |
557 | |
558 // Retrieve the checksum of the bitmap data from the pseudo printer and | |
559 // compare it with the expected result. | |
560 std::string bitmap_actual; | |
561 EXPECT_TRUE(render_thread_.printer()->GetBitmapChecksum(0, &bitmap_actual)); | |
562 if (kTestPages[i].checksum) | |
563 EXPECT_EQ(kTestPages[i].checksum, bitmap_actual); | |
564 | |
565 if (baseline) { | |
566 // Save the source data and the bitmap data into temporary files to | |
567 // create base-line results. | |
568 FilePath source_path; | |
569 file_util::CreateTemporaryFile(&source_path); | |
570 render_thread_.printer()->SaveSource(0, source_path); | |
571 | |
572 FilePath bitmap_path; | |
573 file_util::CreateTemporaryFile(&bitmap_path); | |
574 render_thread_.printer()->SaveBitmap(0, bitmap_path); | |
575 } | |
576 } | |
577 } | |
578 #endif | |
579 | |
580 // Test that we can receive correct DOM events when we send input events | 387 // Test that we can receive correct DOM events when we send input events |
581 // through the RenderWidget::OnHandleInputEvent() function. | 388 // through the RenderWidget::OnHandleInputEvent() function. |
582 TEST_F(RenderViewTest, OnHandleKeyboardEvent) { | 389 TEST_F(RenderViewTest, OnHandleKeyboardEvent) { |
583 #if defined(OS_WIN) || defined(OS_LINUX) | 390 #if defined(OS_WIN) || defined(OS_LINUX) |
584 // Load an HTML page consisting of one <input> element and three | 391 // Load an HTML page consisting of one <input> element and three |
585 // contentediable <div> elements. | 392 // contentediable <div> elements. |
586 // The <input> element is used for sending keyboard events, and the <div> | 393 // The <input> element is used for sending keyboard events, and the <div> |
587 // elements are used for writing DOM events in the following format: | 394 // elements are used for writing DOM events in the following format: |
588 // "<keyCode>,<shiftKey>,<controlKey>,<altKey>". | 395 // "<keyCode>,<shiftKey>,<controlKey>,<altKey>". |
589 // TODO(hbono): <http://crbug.com/2215> Our WebKit port set |ev.metaKey| to | 396 // TODO(hbono): <http://crbug.com/2215> Our WebKit port set |ev.metaKey| to |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 LoadHTML("<html><head><meta http-equiv=\"content-language\" " | 1040 LoadHTML("<html><head><meta http-equiv=\"content-language\" " |
1234 "content=\" fr , es,en \">" | 1041 "content=\" fr , es,en \">" |
1235 "</head><body>A random page with random content.</body></html>"); | 1042 "</head><body>A random page with random content.</body></html>"); |
1236 ProcessPendingMessages(); | 1043 ProcessPendingMessages(); |
1237 message = render_thread_.sink().GetUniqueMessageMatching( | 1044 message = render_thread_.sink().GetUniqueMessageMatching( |
1238 ViewHostMsg_PageContents::ID); | 1045 ViewHostMsg_PageContents::ID); |
1239 ASSERT_NE(static_cast<IPC::Message*>(NULL), message); | 1046 ASSERT_NE(static_cast<IPC::Message*>(NULL), message); |
1240 ViewHostMsg_PageContents::Read(message, ¶ms); | 1047 ViewHostMsg_PageContents::Read(message, ¶ms); |
1241 EXPECT_EQ("fr", params.d); | 1048 EXPECT_EQ("fr", params.d); |
1242 } | 1049 } |
OLD | NEW |