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

Side by Side Diff: chrome/browser/pdf_browsertest.cc

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

Powered by Google App Engine
This is Rietveld 408576698