Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: chrome/test/plugin/pdf_browsertest.cc

Issue 2720002: Add automated tests for PDFs. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/test/data/pdf_browsertest_scroll.png ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 "app/clipboard/clipboard.h"
6 #include "base/command_line.h"
7 #include "base/file_util.h"
8 #include "base/path_service.h"
9 #include "base/string_number_conversions.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/browser.h"
12 #include "chrome/browser/browser_window.h"
13 #include "chrome/browser/renderer_host/render_view_host.h"
14 #include "chrome/browser/tab_contents/tab_contents.h"
15 #include "chrome/browser/window_sizer.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/notification_observer.h"
19 #include "chrome/test/in_process_browser_test.h"
20 #include "chrome/test/ui_test_utils.h"
21 #include "gfx/codec/png_codec.h"
22
23 namespace {
24
25 // Include things like browser frame and scrollbar and make sure we're bigger
26 // than the test pdf document.
27 static const int kBrowserWidth = 1000;
28 static const int kBrowserHeight = 600;
29
30 class PDFBrowserTest : public InProcessBrowserTest,
31 public NotificationObserver {
32 public:
33 PDFBrowserTest()
34 : have_plugin_(false),
35 snapshot_different_(true),
36 next_dummy_search_value_(0) {
37 }
38
39 protected:
40 bool have_plugin() const { return have_plugin_; }
41
42 virtual void SetUp() {
43 FilePath pdf_path;
44 PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path);
45 have_plugin_ = file_util::PathExists(pdf_path);
46 InProcessBrowserTest::SetUp();
47 }
48
49 void Load() {
50 GURL url(ui_test_utils::GetTestUrl(
51 FilePath(FilePath::kCurrentDirectory),
52 FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf"))));
53 ui_test_utils::NavigateToURL(browser(), url);
54 gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight));
55
56 scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info(
57 WindowSizer::CreateDefaultMonitorInfoProvider());
58 gfx::Rect screen_bounds = monitor_info->GetPrimaryMonitorBounds();
59 ASSERT_GT(screen_bounds.width(), kBrowserWidth);
60 ASSERT_GT(screen_bounds.height(), kBrowserHeight);
61
62 browser()->window()->SetBounds(bounds);
63 }
64
65 void VerifySnapshot(const std::string& expected_filename) {
66 snapshot_different_ = true;
67 expected_filename_ = expected_filename;
68 RenderViewHost* host =
69 browser()->GetSelectedTabContents()->render_view_host();
70
71 host->CaptureSnapshot();
72 ui_test_utils::RegisterAndWait(this,
73 NotificationType::TAB_SNAPSHOT_TAKEN,
74 Source<RenderViewHost>(host));
75 ASSERT_FALSE(snapshot_different_) << "Rendering didn't match, see result "
76 "at " << snapshot_filename_.value().c_str();
77 }
78
79 void WaitForResponse() {
80 // Even if the plugin has loaded the data or scrolled, because of how
81 // pepper painting works, we might not have the data. One way to force this
82 // to be flushed is to do a find operation, since on this two-page test
83 // document, it'll wait for us to flush the renderer message loop twice and
84 // also the browser's once, at which point we're guaranteed to have updated
85 // the backingstore. Hacky, but it works.
86 // Note that we need to change the text each time, because if we don't the
87 // renderer code will think the second message is to go to next result, but
88 // there are none so the plugin will assert.
89
90 string16 query = UTF8ToUTF16(
91 std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++)));
92 ASSERT_EQ(0, ui_test_utils::FindInPage(
93 browser()->GetSelectedTabContents(), query, true, false, NULL));
94 }
95
96 private:
97 virtual void SetUpCommandLine(CommandLine* command_line) {
98 command_line->AppendSwitch(switches::kForceInternalPDFPlugin);
99 }
100
101 // NotificationObserver
102 virtual void Observe(NotificationType type,
103 const NotificationSource& source,
104 const NotificationDetails& details) {
105 if (type == NotificationType::TAB_SNAPSHOT_TAKEN) {
106 MessageLoopForUI::current()->Quit();
107 FilePath reference = ui_test_utils::GetTestFilePath(
108 FilePath(FilePath::kCurrentDirectory),
109 FilePath().AppendASCII(expected_filename_));
110 base::PlatformFileInfo info;
111 ASSERT_TRUE(file_util::GetFileInfo(reference, &info));
112 int size = static_cast<size_t>(info.size);
113 scoped_array<char> data(new char[size]);
114 ASSERT_EQ(size, file_util::ReadFile(reference, data.get(), size));
115
116 int w, h;
117 std::vector<unsigned char> decoded;
118 ASSERT_TRUE(gfx::PNGCodec::Decode(
119 reinterpret_cast<unsigned char*>(data.get()), size,
120 gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h));
121 int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]);
122
123 const SkBitmap* bitmap = Details<const SkBitmap>(details).ptr();
124 int32* pixels = static_cast<int32*>(bitmap->getPixels());
125
126 // Get the background color, and use it to figure out the x-offsets in
127 // each image. The reason is that depending on the theme in the OS, the
128 // same browser width can lead to slightly different plugin sizes, so the
129 // pdf content will start at different x offsets.
130 // Also note that the images we saved are cut off before the scrollbar, as
131 // that'll change depending on the theme, and also cut off vertically so
132 // that the ui controls don't show up, as those fade-in and so the timing
133 // will affect their transparency.
134 int32 bg_color = ref_pixels[0];
135 int ref_x_offset, snapshot_x_offset;
136 for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) {
137 if (ref_pixels[ref_x_offset] != bg_color)
138 break;
139 }
140
141 for (snapshot_x_offset = 0; snapshot_x_offset < bitmap->width();
142 ++snapshot_x_offset) {
143 if (pixels[snapshot_x_offset] != bg_color)
144 break;
145 }
146
147 int x_max = std::min(
148 w - ref_x_offset, bitmap->width() - snapshot_x_offset);
149 int y_max = std::min(h, bitmap->height());
150 int stride = bitmap->rowBytes();
151 snapshot_different_ = false;
152 for (int y = 0; y < y_max && !snapshot_different_; ++y) {
153 for (int x = 0; x < x_max && !snapshot_different_; ++x) {
154 if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] !=
155 ref_pixels[y * w + x + ref_x_offset])
156 snapshot_different_ = true;
157 }
158 }
159
160 if (snapshot_different_) {
161 std::vector<unsigned char> png_data;
162 gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data);
163 if (file_util::CreateTemporaryFile(&snapshot_filename_)) {
164 file_util::WriteFile(snapshot_filename_,
165 reinterpret_cast<char*>(&png_data[0]), png_data.size());
166 }
167 }
168 }
169 }
170
171 // True if we found the pdf plugin. Needed since only official builders have
172 // the pdf plugin, so for the rest, and for other devs, we don't want the test
173 // to fail.
174 bool have_plugin_;
175 // True if the snapshot differed from the expected value.
176 bool snapshot_different_;
177 // Internal variable used to synchronize to the renderer.
178 int next_dummy_search_value_;
179 // The filename of the bitmap to compare the snapshot to.
180 std::string expected_filename_;
181 // If the snapshot is different, holds the location where it's saved.
182 FilePath snapshot_filename_;
183 };
184
185 // Tests basic PDF rendering. This can be broken depending on bad merges with
186 // the vendor, so it's important that we have basic sanity checking.
187 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, Basic) {
188 if (!have_plugin())
189 return;
190
191 ASSERT_NO_FATAL_FAILURE(Load());
192 ASSERT_NO_FATAL_FAILURE(WaitForResponse());
193 ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest.png"));
194 }
195
196 // Tests that scrolling works.
197 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, Scroll) {
198 if (!have_plugin())
199 return;
200
201 ASSERT_NO_FATAL_FAILURE(Load());
202
203 // We use wheel mouse event since that's the only one we can easily push to
204 // the renderer. There's no way to push a cross-platform keyboard event at
205 // the moment.
206 WebKit::WebMouseWheelEvent wheel_event;
207 wheel_event.type = WebKit::WebInputEvent::MouseWheel;
208 wheel_event.deltaY = -200;
209 wheel_event.wheelTicksY = -2;
210 TabContents* tab_contents = browser()->GetSelectedTabContents();
211 tab_contents->render_view_host()->ForwardWheelEvent(wheel_event);
212 ASSERT_NO_FATAL_FAILURE(WaitForResponse());
213 ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest_scroll.png"));
214 }
215
216 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, FindAndCopy) {
217 if (!have_plugin())
218 return;
219
220 ASSERT_NO_FATAL_FAILURE(Load());
221 // Verifies that find in page works.
222 ASSERT_EQ(3, ui_test_utils::FindInPage(
223 browser()->GetSelectedTabContents(), UTF8ToUTF16("adipiscing"), true,
224 false, NULL));
225
226 // Verify that copying selected text works.
227 Clipboard clipboard;
228 // Reset the clipboard first.
229 Clipboard::ObjectMap objects;
230 Clipboard::ObjectMapParams params;
231 params.push_back(std::vector<char>());
232 objects[Clipboard::CBF_TEXT] = params;
233 clipboard.WriteObjects(objects);
234
235 browser()->GetSelectedTabContents()->render_view_host()->Copy();
236 ASSERT_NO_FATAL_FAILURE(WaitForResponse());
237
238 std::string text;
239 clipboard.ReadAsciiText(Clipboard::BUFFER_STANDARD, &text);
240 ASSERT_EQ("adipiscing", text);
241 }
242
243 } // namespace
OLDNEW
« no previous file with comments | « chrome/test/data/pdf_browsertest_scroll.png ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698