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

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

Issue 7576018: Reorganize chrome/test, part #8 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months 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/chrome_tests.gypi ('k') | chrome/test/plugin/plugin_test.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "base/path_service.h"
7 #include "base/string_number_conversions.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_window.h"
12 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
13 #include "chrome/browser/ui/window_sizer.h"
14 #include "chrome/common/chrome_notification_types.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/test/base/in_process_browser_test.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/browser/renderer_host/render_view_host.h"
19 #include "content/browser/tab_contents/tab_contents.h"
20 #include "content/common/notification_observer.h"
21 #include "net/test/test_server.h"
22 #include "ui/base/clipboard/clipboard.h"
23 #include "ui/gfx/codec/png_codec.h"
24
25 namespace {
26
27 // Include things like browser frame and scrollbar and make sure we're bigger
28 // than the test pdf document.
29 static const int kBrowserWidth = 1000;
30 static const int kBrowserHeight = 600;
31
32 class PDFBrowserTest : public InProcessBrowserTest,
33 public NotificationObserver {
34 public:
35 PDFBrowserTest()
36 : snapshot_different_(true),
37 next_dummy_search_value_(0),
38 load_stop_notification_count_(0) {
39 EnableDOMAutomation();
40
41 pdf_test_server_.reset(new net::TestServer(
42 net::TestServer::TYPE_HTTP,
43 FilePath(FILE_PATH_LITERAL("pdf/test"))));
44 }
45
46 protected:
47 // Use our own TestServer so that we can serve files from the pdf directory.
48 net::TestServer* pdf_test_server() { return pdf_test_server_.get(); }
49
50 int load_stop_notification_count() const {
51 return load_stop_notification_count_;
52 }
53
54 FilePath GetPDFTestDir() {
55 return FilePath(FilePath::kCurrentDirectory).AppendASCII("..").
56 AppendASCII("..").AppendASCII("..").AppendASCII("pdf").
57 AppendASCII("test");
58 }
59
60 void Load() {
61 // Make sure to set the window size before rendering, as otherwise rendering
62 // to a smaller window and then expanding leads to slight anti-aliasing
63 // differences of the text and the pixel comparison fails.
64 gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight));
65 scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info(
66 WindowSizer::CreateDefaultMonitorInfoProvider());
67 gfx::Rect screen_bounds = monitor_info->GetPrimaryMonitorBounds();
68 ASSERT_GT(screen_bounds.width(), kBrowserWidth);
69 ASSERT_GT(screen_bounds.height(), kBrowserHeight);
70 browser()->window()->SetBounds(bounds);
71
72 GURL url(ui_test_utils::GetTestUrl(
73 GetPDFTestDir(),
74 FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf"))));
75 ui_test_utils::NavigateToURL(browser(), url);
76 }
77
78 void VerifySnapshot(const std::string& expected_filename) {
79 snapshot_different_ = true;
80 expected_filename_ = expected_filename;
81 TabContentsWrapper* wrapper = browser()->GetSelectedTabContentsWrapper();
82 wrapper->CaptureSnapshot();
83 ui_test_utils::RegisterAndWait(this,
84 chrome::NOTIFICATION_TAB_SNAPSHOT_TAKEN,
85 Source<TabContentsWrapper>(wrapper));
86 ASSERT_FALSE(snapshot_different_) << "Rendering didn't match, see result "
87 "at " << snapshot_filename_.value().c_str();
88 }
89
90 void WaitForResponse() {
91 // Even if the plugin has loaded the data or scrolled, because of how
92 // pepper painting works, we might not have the data. One way to force this
93 // to be flushed is to do a find operation, since on this two-page test
94 // document, it'll wait for us to flush the renderer message loop twice and
95 // also the browser's once, at which point we're guaranteed to have updated
96 // the backingstore. Hacky, but it works.
97 // Note that we need to change the text each time, because if we don't the
98 // renderer code will think the second message is to go to next result, but
99 // there are none so the plugin will assert.
100
101 string16 query = UTF8ToUTF16(
102 std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++)));
103 ASSERT_EQ(0, ui_test_utils::FindInPage(
104 browser()->GetSelectedTabContentsWrapper(), query, true, false, NULL));
105 }
106
107 private:
108 // NotificationObserver
109 virtual void Observe(int type,
110 const NotificationSource& source,
111 const NotificationDetails& details) {
112 if (type == chrome::NOTIFICATION_TAB_SNAPSHOT_TAKEN) {
113 MessageLoopForUI::current()->Quit();
114 FilePath reference = ui_test_utils::GetTestFilePath(
115 GetPDFTestDir(),
116 FilePath().AppendASCII(expected_filename_));
117 base::PlatformFileInfo info;
118 ASSERT_TRUE(file_util::GetFileInfo(reference, &info));
119 int size = static_cast<size_t>(info.size);
120 scoped_array<char> data(new char[size]);
121 ASSERT_EQ(size, file_util::ReadFile(reference, data.get(), size));
122
123 int w, h;
124 std::vector<unsigned char> decoded;
125 ASSERT_TRUE(gfx::PNGCodec::Decode(
126 reinterpret_cast<unsigned char*>(data.get()), size,
127 gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h));
128 int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]);
129
130 const SkBitmap* bitmap = Details<const SkBitmap>(details).ptr();
131 int32* pixels = static_cast<int32*>(bitmap->getPixels());
132
133 // Get the background color, and use it to figure out the x-offsets in
134 // each image. The reason is that depending on the theme in the OS, the
135 // same browser width can lead to slightly different plugin sizes, so the
136 // pdf content will start at different x offsets.
137 // Also note that the images we saved are cut off before the scrollbar, as
138 // that'll change depending on the theme, and also cut off vertically so
139 // that the ui controls don't show up, as those fade-in and so the timing
140 // will affect their transparency.
141 int32 bg_color = ref_pixels[0];
142 int ref_x_offset, snapshot_x_offset;
143 for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) {
144 if (ref_pixels[ref_x_offset] != bg_color)
145 break;
146 }
147
148 for (snapshot_x_offset = 0; snapshot_x_offset < bitmap->width();
149 ++snapshot_x_offset) {
150 if (pixels[snapshot_x_offset] != bg_color)
151 break;
152 }
153
154 int x_max = std::min(
155 w - ref_x_offset, bitmap->width() - snapshot_x_offset);
156 int y_max = std::min(h, bitmap->height());
157 int stride = bitmap->rowBytes();
158 snapshot_different_ = false;
159 for (int y = 0; y < y_max && !snapshot_different_; ++y) {
160 for (int x = 0; x < x_max && !snapshot_different_; ++x) {
161 if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] !=
162 ref_pixels[y * w + x + ref_x_offset])
163 snapshot_different_ = true;
164 }
165 }
166
167 if (snapshot_different_) {
168 std::vector<unsigned char> png_data;
169 gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data);
170 if (file_util::CreateTemporaryFile(&snapshot_filename_)) {
171 file_util::WriteFile(snapshot_filename_,
172 reinterpret_cast<char*>(&png_data[0]), png_data.size());
173 }
174 }
175 } else if (type == content::NOTIFICATION_LOAD_STOP) {
176 load_stop_notification_count_++;
177 }
178 }
179
180 // True if the snapshot differed from the expected value.
181 bool snapshot_different_;
182 // Internal variable used to synchronize to the renderer.
183 int next_dummy_search_value_;
184 // The filename of the bitmap to compare the snapshot to.
185 std::string expected_filename_;
186 // If the snapshot is different, holds the location where it's saved.
187 FilePath snapshot_filename_;
188 // How many times we've seen chrome::LOAD_STOP.
189 int load_stop_notification_count_;
190
191 scoped_ptr<net::TestServer> pdf_test_server_;
192 };
193
194 #if defined(OS_CHROMEOS)
195 // TODO(sanjeevr): http://crbug.com/79837
196 #define MAYBE_Basic DISABLED_Basic
197 #else
198 #define MAYBE_Basic Basic
199 #endif
200 // Tests basic PDF rendering. This can be broken depending on bad merges with
201 // the vendor, so it's important that we have basic sanity checking.
202 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_Basic) {
203 ASSERT_NO_FATAL_FAILURE(Load());
204 ASSERT_NO_FATAL_FAILURE(WaitForResponse());
205 ASSERT_NO_FATAL_FAILURE(VerifySnapshot("pdf_browsertest.png"));
206 }
207
208 #if defined(OS_CHROMEOS)
209 // TODO(sanjeevr): http://crbug.com/79837
210 #define MAYBE_Scroll DISABLED_Scroll
211 #else
212 #define MAYBE_Scroll Scroll
213 #endif
214 // Tests that scrolling works.
215 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_Scroll) {
216 ASSERT_NO_FATAL_FAILURE(Load());
217
218 // We use wheel mouse event since that's the only one we can easily push to
219 // the renderer. There's no way to push a cross-platform keyboard event at
220 // the moment.
221 WebKit::WebMouseWheelEvent wheel_event;
222 wheel_event.type = WebKit::WebInputEvent::MouseWheel;
223 wheel_event.deltaY = -200;
224 wheel_event.wheelTicksY = -2;
225 TabContents* tab_contents = browser()->GetSelectedTabContents();
226 tab_contents->render_view_host()->ForwardWheelEvent(wheel_event);
227 ASSERT_NO_FATAL_FAILURE(WaitForResponse());
228
229 int y_offset = 0;
230 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt(
231 browser()->GetSelectedTabContents()->render_view_host(),
232 std::wstring(),
233 L"window.domAutomationController.send(plugin.pageYOffset())",
234 &y_offset));
235 ASSERT_GT(y_offset, 0);
236 }
237
238 #if defined(OS_CHROMEOS)
239 // TODO(sanjeevr): http://crbug.com/79837
240 #define MAYBE_FindAndCopy DISABLED_FindAndCopy
241 #else
242 #define MAYBE_FindAndCopy FindAndCopy
243 #endif
244 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_FindAndCopy) {
245 ASSERT_NO_FATAL_FAILURE(Load());
246 // Verifies that find in page works.
247 ASSERT_EQ(3, ui_test_utils::FindInPage(
248 browser()->GetSelectedTabContentsWrapper(), UTF8ToUTF16("adipiscing"),
249 true, false, NULL));
250
251 // Verify that copying selected text works.
252 ui::Clipboard clipboard;
253 // Reset the clipboard first.
254 ui::Clipboard::ObjectMap objects;
255 ui::Clipboard::ObjectMapParams params;
256 params.push_back(std::vector<char>());
257 objects[ui::Clipboard::CBF_TEXT] = params;
258 clipboard.WriteObjects(objects);
259
260 browser()->GetSelectedTabContents()->render_view_host()->Copy();
261 ASSERT_NO_FATAL_FAILURE(WaitForResponse());
262
263 std::string text;
264 clipboard.ReadAsciiText(ui::Clipboard::BUFFER_STANDARD, &text);
265 ASSERT_EQ("adipiscing", text);
266 }
267
268 // Tests that loading async pdfs works correctly (i.e. document fully loads).
269 // This also loads all documents that used to crash, to ensure we don't have
270 // regressions.
271 // Flaky as per http://crbug.com/74548.
272 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, FLAKY_SLOW_Loading) {
273 ASSERT_TRUE(pdf_test_server()->Start());
274
275 NavigationController* controller =
276 &(browser()->GetSelectedTabContents()->controller());
277 NotificationRegistrar registrar;
278 registrar.Add(this,
279 content::NOTIFICATION_LOAD_STOP,
280 Source<NavigationController>(controller));
281 std::string base_url = std::string("files/");
282
283 file_util::FileEnumerator file_enumerator(
284 ui_test_utils::GetTestFilePath(GetPDFTestDir(), FilePath()),
285 false,
286 file_util::FileEnumerator::FILES,
287 FILE_PATH_LITERAL("*.pdf"));
288 for (FilePath file_path = file_enumerator.Next();
289 !file_path.empty();
290 file_path = file_enumerator.Next()) {
291 std::string filename = file_path.BaseName().MaybeAsASCII();
292 ASSERT_FALSE(filename.empty());
293
294 #if defined(OS_POSIX)
295 if (filename == "sample.pdf")
296 continue; // Crashes on Mac and Linux. http://crbug.com/63549
297 #endif
298
299 LOG(WARNING) << "PDFBrowserTest.Loading: " << filename;
300
301 GURL url = pdf_test_server()->GetURL(base_url + filename);
302 ui_test_utils::NavigateToURL(browser(), url);
303
304 while (true) {
305 int last_count = load_stop_notification_count();
306 // We might get extraneous chrome::LOAD_STOP notifications when
307 // doing async loading. This happens when the first loader is cancelled
308 // and before creating a byte-range request loader.
309 bool complete = false;
310 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
311 browser()->GetSelectedTabContents()->render_view_host(),
312 std::wstring(),
313 L"window.domAutomationController.send(plugin.documentLoadComplete())",
314 &complete));
315 if (complete)
316 break;
317
318 // Check if the LOAD_STOP notification could have come while we run a
319 // nested message loop for the JS call.
320 if (last_count != load_stop_notification_count())
321 continue;
322 ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
323 }
324 }
325 }
326
327 // Flaky as per http://crbug.com/74549.
328 #if defined(OS_MACOSX)
329 #define MAYBE_OnLoadAndReload DISABLED_OnLoadAndReload
330 #else
331 #define MAYBE_OnLoadAndReload FLAKY_OnLoadAndReload
332 #endif
333 IN_PROC_BROWSER_TEST_F(PDFBrowserTest, MAYBE_OnLoadAndReload) {
334 ASSERT_TRUE(pdf_test_server()->Start());
335
336 GURL url = pdf_test_server()->GetURL("files/onload_reload.html");
337 ui_test_utils::NavigateToURL(browser(), url);
338
339 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
340 browser()->GetSelectedTabContents()->render_view_host(),
341 std::wstring(),
342 L"reloadPDF();"));
343
344 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
345 ASSERT_EQ("success", browser()->GetSelectedTabContents()->GetURL().query());
346 }
347
348 } // namespace
OLDNEW
« no previous file with comments | « chrome/chrome_tests.gypi ('k') | chrome/test/plugin/plugin_test.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698