Index: chrome/test/plugin/pdf_browsertest.cc |
=================================================================== |
--- chrome/test/plugin/pdf_browsertest.cc (revision 0) |
+++ chrome/test/plugin/pdf_browsertest.cc (revision 0) |
@@ -0,0 +1,243 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "app/clipboard/clipboard.h" |
+#include "base/command_line.h" |
+#include "base/file_util.h" |
+#include "base/path_service.h" |
+#include "base/string_number_conversions.h" |
+#include "base/utf_string_conversions.h" |
+#include "chrome/browser/browser.h" |
+#include "chrome/browser/browser_window.h" |
+#include "chrome/browser/renderer_host/render_view_host.h" |
+#include "chrome/browser/tab_contents/tab_contents.h" |
+#include "chrome/browser/window_sizer.h" |
+#include "chrome/common/chrome_paths.h" |
+#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/notification_observer.h" |
+#include "chrome/test/in_process_browser_test.h" |
+#include "chrome/test/ui_test_utils.h" |
+#include "gfx/codec/png_codec.h" |
+ |
+namespace { |
+ |
+// Include things like browser frame and scrollbar and make sure we're bigger |
+// than the test pdf document. |
+static const int kBrowserWidth = 1000; |
+static const int kBrowserHeight = 600; |
+ |
+class PDFBrowserTest : public InProcessBrowserTest, |
+ public NotificationObserver { |
+ public: |
+ PDFBrowserTest() |
+ : have_plugin_(false), |
+ snapshot_different_(true), |
+ next_dummy_search_value_(0) { |
+ } |
+ |
+ protected: |
+ bool have_plugin() const { return have_plugin_; } |
+ |
+ virtual void SetUp() { |
+ FilePath pdf_path; |
+ PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path); |
+ have_plugin_ = file_util::PathExists(pdf_path); |
+ InProcessBrowserTest::SetUp(); |
+ } |
+ |
+ void Load() { |
+ GURL url(ui_test_utils::GetTestUrl( |
+ FilePath(FilePath::kCurrentDirectory), |
+ FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf")))); |
+ ui_test_utils::NavigateToURL(browser(), url); |
+ gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight)); |
+ |
+ scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info( |
+ WindowSizer::CreateDefaultMonitorInfoProvider()); |
+ gfx::Rect screen_bounds = monitor_info->GetPrimaryMonitorBounds(); |
+ ASSERT_GT(screen_bounds.width(), kBrowserWidth); |
+ ASSERT_GT(screen_bounds.height(), kBrowserHeight); |
+ |
+ browser()->window()->SetBounds(bounds); |
+ } |
+ |
+ void VerifySnapshot(const std::string& expected_filename) { |
+ snapshot_different_ = true; |
+ expected_filename_ = expected_filename; |
+ RenderViewHost* host = |
+ browser()->GetSelectedTabContents()->render_view_host(); |
+ |
+ host->CaptureSnapshot(); |
+ ui_test_utils::RegisterAndWait(this, |
+ NotificationType::TAB_SNAPSHOT_TAKEN, |
+ Source<RenderViewHost>(host)); |
+ ASSERT_FALSE(snapshot_different_) << "Rendering didn't match, see result " |
+ "at " << snapshot_filename_.value().c_str(); |
+ } |
+ |
+ void WaitForResponse() { |
+ // Even if the plugin has loaded the data or scrolled, because of how |
+ // pepper painting works, we might not have the data. One way to force this |
+ // to be flushed is to do a find operation, since on this two-page test |
+ // document, it'll wait for us to flush the renderer message loop twice and |
+ // also the browser's once, at which point we're guaranteed to have updated |
+ // the backingstore. Hacky, but it works. |
+ // Note that we need to change the text each time, because if we don't the |
+ // renderer code will think the second message is to go to next result, but |
+ // there are none so the plugin will assert. |
+ |
+ string16 query = UTF8ToUTF16( |
+ std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++))); |
+ ASSERT_EQ(0, ui_test_utils::FindInPage( |
+ browser()->GetSelectedTabContents(), query, true, false, NULL)); |
+ } |
+ |
+ private: |
+ virtual void SetUpCommandLine(CommandLine* command_line) { |
+ command_line->AppendSwitch(switches::kForceInternalPDFPlugin); |
+ } |
+ |
+ // NotificationObserver |
+ virtual void Observe(NotificationType type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ if (type == NotificationType::TAB_SNAPSHOT_TAKEN) { |
+ MessageLoopForUI::current()->Quit(); |
+ FilePath reference = ui_test_utils::GetTestFilePath( |
+ FilePath(FilePath::kCurrentDirectory), |
+ FilePath().AppendASCII(expected_filename_)); |
+ base::PlatformFileInfo info; |
+ ASSERT_TRUE(file_util::GetFileInfo(reference, &info)); |
+ int size = static_cast<size_t>(info.size); |
+ scoped_array<char> data(new char[size]); |
+ ASSERT_EQ(size, file_util::ReadFile(reference, data.get(), size)); |
+ |
+ int w, h; |
+ std::vector<unsigned char> decoded; |
+ ASSERT_TRUE(gfx::PNGCodec::Decode( |
+ reinterpret_cast<unsigned char*>(data.get()), size, |
+ gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h)); |
+ int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]); |
+ |
+ const SkBitmap* bitmap = Details<const SkBitmap>(details).ptr(); |
+ int32* pixels = static_cast<int32*>(bitmap->getPixels()); |
+ |
+ // Get the background color, and use it to figure out the x-offsets in |
+ // each image. The reason is that depending on the theme in the OS, the |
+ // same browser width can lead to slightly different plugin sizes, so the |
+ // pdf content will start at different x offsets. |
+ // Also note that the images we saved are cut off before the scrollbar, as |
+ // that'll change depending on the theme, and also cut off vertically so |
+ // that the ui controls don't show up, as those fade-in and so the timing |
+ // will affect their transparency. |
+ int32 bg_color = ref_pixels[0]; |
+ int ref_x_offset, snapshot_x_offset; |
+ for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) { |
+ if (ref_pixels[ref_x_offset] != bg_color) |
+ break; |
+ } |
+ |
+ for (snapshot_x_offset = 0; snapshot_x_offset < bitmap->width(); |
+ ++snapshot_x_offset) { |
+ if (pixels[snapshot_x_offset] != bg_color) |
+ break; |
+ } |
+ |
+ int x_max = std::min( |
+ w - ref_x_offset, bitmap->width() - snapshot_x_offset); |
+ int y_max = std::min(h, bitmap->height()); |
+ int stride = bitmap->rowBytes(); |
+ snapshot_different_ = false; |
+ for (int y = 0; y < y_max && !snapshot_different_; ++y) { |
+ for (int x = 0; x < x_max && !snapshot_different_; ++x) { |
+ if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] != |
+ ref_pixels[y * w + x + ref_x_offset]) |
+ snapshot_different_ = true; |
+ } |
+ } |
+ |
+ if (snapshot_different_) { |
+ std::vector<unsigned char> png_data; |
+ gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data); |
+ if (file_util::CreateTemporaryFile(&snapshot_filename_)) { |
+ file_util::WriteFile(snapshot_filename_, |
+ reinterpret_cast<char*>(&png_data[0]), png_data.size()); |
+ } |
+ } |
+ } |
+ } |
+ |
+ // True if we found the pdf plugin. Needed since only official builders have |
+ // the pdf plugin, so for the rest, and for other devs, we don't want the test |
+ // to fail. |
+ bool have_plugin_; |
+ // True if the snapshot differed from the expected value. |
+ bool snapshot_different_; |
+ // Internal variable used to synchronize to the renderer. |
+ int next_dummy_search_value_; |
+ // The filename of the bitmap to compare the snapshot to. |
+ std::string expected_filename_; |
+ // If the snapshot is different, holds the location where it's saved. |
+ FilePath snapshot_filename_; |
+}; |
+ |
+// Tests basic PDF rendering. This can be broken depending on bad merges with |
+// the vendor, so it's important that we have basic sanity checking. |
+IN_PROC_BROWSER_TEST_F(PDFBrowserTest, Basic) { |
+ if (!have_plugin()) |
+ return; |
+ |
+ ASSERT_NO_FATAL_FAILURE(Load()); |
+ ASSERT_NO_FATAL_FAILURE(WaitForResponse()); |
+ ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest.png")); |
+} |
+ |
+// Tests that scrolling works. |
+IN_PROC_BROWSER_TEST_F(PDFBrowserTest, Scroll) { |
+ if (!have_plugin()) |
+ return; |
+ |
+ ASSERT_NO_FATAL_FAILURE(Load()); |
+ |
+ // We use wheel mouse event since that's the only one we can easily push to |
+ // the renderer. There's no way to push a cross-platform keyboard event at |
+ // the moment. |
+ WebKit::WebMouseWheelEvent wheel_event; |
+ wheel_event.type = WebKit::WebInputEvent::MouseWheel; |
+ wheel_event.deltaY = -200; |
+ wheel_event.wheelTicksY = -2; |
+ TabContents* tab_contents = browser()->GetSelectedTabContents(); |
+ tab_contents->render_view_host()->ForwardWheelEvent(wheel_event); |
+ ASSERT_NO_FATAL_FAILURE(WaitForResponse()); |
+ ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest_scroll.png")); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(PDFBrowserTest, FindAndCopy) { |
+ if (!have_plugin()) |
+ return; |
+ |
+ ASSERT_NO_FATAL_FAILURE(Load()); |
+ // Verifies that find in page works. |
+ ASSERT_EQ(3, ui_test_utils::FindInPage( |
+ browser()->GetSelectedTabContents(), UTF8ToUTF16("adipiscing"), true, |
+ false, NULL)); |
+ |
+ // Verify that copying selected text works. |
+ Clipboard clipboard; |
+ // Reset the clipboard first. |
+ Clipboard::ObjectMap objects; |
+ Clipboard::ObjectMapParams params; |
+ params.push_back(std::vector<char>()); |
+ objects[Clipboard::CBF_TEXT] = params; |
+ clipboard.WriteObjects(objects); |
+ |
+ browser()->GetSelectedTabContents()->render_view_host()->Copy(); |
+ ASSERT_NO_FATAL_FAILURE(WaitForResponse()); |
+ |
+ std::string text; |
+ clipboard.ReadAsciiText(Clipboard::BUFFER_STANDARD, &text); |
+ ASSERT_EQ("adipiscing", text); |
+} |
+ |
+} // namespace |
Property changes on: chrome\test\plugin\pdf_browsertest.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |