blob: 4ee07e3a262916d5d32974233becf11d95132681 [file] [log] [blame]
[email protected]31d71b02012-01-26 03:42:311// Copyright (c) 2012 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
[email protected]9b4c6cd2012-08-20 10:47:455#include "content/shell/webkit_test_runner.h"
[email protected]31d71b02012-01-26 03:42:316
[email protected]b9fad24c2012-11-15 08:22:107#include <cmath>
8
[email protected]09ec9f92012-12-17 09:46:369#include "base/base64.h"
[email protected]0799da02012-06-27 10:58:5110#include "base/md5.h"
[email protected]e225b922012-08-18 01:43:0411#include "base/memory/scoped_ptr.h"
[email protected]b2324b092012-11-01 10:34:1112#include "base/message_loop.h"
[email protected]c272c5b2012-06-06 09:01:0613#include "base/stringprintf.h"
[email protected]0d2dfb92d2012-11-05 10:26:4514#include "base/sys_string_conversions.h"
[email protected]b2324b092012-11-01 10:34:1115#include "base/time.h"
[email protected]0d2dfb92d2012-11-05 10:26:4516#include "base/utf_string_conversions.h"
[email protected]efb5f572012-01-29 10:57:3317#include "content/public/renderer/render_view.h"
[email protected]e5196922012-12-11 22:18:2518#include "content/public/test/layouttest_support.h"
[email protected]efb5f572012-01-29 10:57:3319#include "content/shell/shell_messages.h"
[email protected]b2324b092012-11-01 10:34:1120#include "content/shell/shell_render_process_observer.h"
[email protected]55915a72012-12-18 11:55:2521#include "content/shell/webkit_test_helpers.h"
[email protected]9d9ec982013-01-10 18:53:3922#include "net/base/net_errors.h"
[email protected]0d2dfb92d2012-11-05 10:26:4523#include "net/base/net_util.h"
[email protected]0799da02012-06-27 10:58:5124#include "skia/ext/platform_canvas.h"
[email protected]2a58eb12012-12-18 07:56:4025#include "third_party/WebKit/Source/Platform/chromium/public/Platform.h"
[email protected]87884c42013-01-10 01:56:2726#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
27#include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
28#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
29#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
30#include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
[email protected]9d9ec982013-01-10 18:53:3931#include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h"
[email protected]0ac1a032013-02-12 12:53:3732#include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h"
[email protected]b2324b092012-11-01 10:34:1133#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
[email protected]0ac1a032013-02-12 12:53:3734#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
[email protected]001841c92012-12-11 17:00:1335#include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
[email protected]efb5f572012-01-29 10:57:3336#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
37#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
38#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
[email protected]b2324b092012-11-01 10:34:1139#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
[email protected]efb5f572012-01-29 10:57:3340#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
[email protected]b2324b092012-11-01 10:34:1141#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTask.h"
[email protected]b9fad24c2012-11-15 08:22:1042#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTestProxy.h"
[email protected]984a5f72012-12-13 21:41:5043#include "webkit/base/file_path_string_conversions.h"
[email protected]0799da02012-06-27 10:58:5144#include "webkit/glue/webkit_glue.h"
[email protected]324825d2012-11-30 12:37:1545#include "webkit/glue/webpreferences.h"
[email protected]efb5f572012-01-29 10:57:3346
[email protected]2a58eb12012-12-18 07:56:4047using WebKit::Platform;
[email protected]b2324b092012-11-01 10:34:1148using WebKit::WebContextMenuData;
[email protected]001841c92012-12-11 17:00:1349using WebKit::WebDevToolsAgent;
[email protected]efb5f572012-01-29 10:57:3350using WebKit::WebElement;
[email protected]b2324b092012-11-01 10:34:1151using WebKit::WebFrame;
52using WebKit::WebGamepads;
[email protected]0799da02012-06-27 10:58:5153using WebKit::WebRect;
[email protected]c272c5b2012-06-06 09:01:0654using WebKit::WebSize;
[email protected]b2324b092012-11-01 10:34:1155using WebKit::WebString;
[email protected]09ec9f92012-12-17 09:46:3656using WebKit::WebURL;
[email protected]9d9ec982013-01-10 18:53:3957using WebKit::WebURLError;
[email protected]b2324b092012-11-01 10:34:1158using WebKit::WebVector;
[email protected]0799da02012-06-27 10:58:5159using WebKit::WebView;
[email protected]b3dbcb5e2012-12-17 00:16:3760using WebTestRunner::WebPreferences;
[email protected]b2324b092012-11-01 10:34:1161using WebTestRunner::WebTask;
[email protected]efb5f572012-01-29 10:57:3362
[email protected]31d71b02012-01-26 03:42:3163namespace content {
64
[email protected]efb5f572012-01-29 10:57:3365namespace {
66
[email protected]b2324b092012-11-01 10:34:1167void InvokeTaskHelper(void* context) {
68 WebTask* task = reinterpret_cast<WebTask*>(context);
69 task->run();
70 delete task;
71}
72
[email protected]efb5f572012-01-29 10:57:3373std::string DumpDocumentText(WebFrame* frame) {
74 // We use the document element's text instead of the body text here because
75 // not all documents have a body, such as XML documents.
76 WebElement documentElement = frame->document().documentElement();
77 if (documentElement.isNull())
78 return std::string();
79 return documentElement.innerText().utf8();
80}
81
[email protected]c272c5b2012-06-06 09:01:0682std::string DumpDocumentPrintedText(WebFrame* frame) {
83 return frame->renderTreeAsText(WebFrame::RenderAsTextPrinting).utf8();
84}
85
86std::string DumpFramesAsText(WebFrame* frame, bool printing, bool recursive) {
[email protected]efb5f572012-01-29 10:57:3387 std::string result;
88
[email protected]c272c5b2012-06-06 09:01:0689 // Cannot do printed format for anything other than HTML.
90 if (printing && !frame->document().isHTMLDocument())
91 return std::string();
92
[email protected]efb5f572012-01-29 10:57:3393 // Add header for all but the main frame. Skip emtpy frames.
94 if (frame->parent() && !frame->document().documentElement().isNull()) {
95 result.append("\n--------\nFrame: '");
[email protected]6d454d92012-09-13 17:06:2996 result.append(frame->uniqueName().utf8().data());
[email protected]efb5f572012-01-29 10:57:3397 result.append("'\n--------\n");
98 }
99
[email protected]c272c5b2012-06-06 09:01:06100 result.append(
101 printing ? DumpDocumentPrintedText(frame) : DumpDocumentText(frame));
[email protected]efb5f572012-01-29 10:57:33102 result.append("\n");
103
104 if (recursive) {
105 for (WebFrame* child = frame->firstChild(); child;
106 child = child->nextSibling()) {
[email protected]c272c5b2012-06-06 09:01:06107 result.append(DumpFramesAsText(child, printing, recursive));
108 }
109 }
110 return result;
111}
112
113std::string DumpFrameScrollPosition(WebFrame* frame, bool recursive) {
114 std::string result;
115
116 WebSize offset = frame->scrollOffset();
117 if (offset.width > 0 || offset.height > 0) {
118 if (frame->parent()) {
119 result.append(
[email protected]6d454d92012-09-13 17:06:29120 base::StringPrintf("frame '%s' ", frame->uniqueName().utf8().data()));
[email protected]c272c5b2012-06-06 09:01:06121 }
122 result.append(
123 base::StringPrintf("scrolled to %d,%d\n", offset.width, offset.height));
124 }
125
126 if (recursive) {
127 for (WebFrame* child = frame->firstChild(); child;
128 child = child->nextSibling()) {
129 result.append(DumpFrameScrollPosition(child, recursive));
[email protected]efb5f572012-01-29 10:57:33130 }
131 }
132 return result;
133}
134
[email protected]0799da02012-06-27 10:58:51135#if !defined(OS_MACOSX)
136void MakeBitmapOpaque(SkBitmap* bitmap) {
137 SkAutoLockPixels lock(*bitmap);
138 DCHECK(bitmap->config() == SkBitmap::kARGB_8888_Config);
139 for (int y = 0; y < bitmap->height(); ++y) {
140 uint32_t* row = bitmap->getAddr32(0, y);
141 for (int x = 0; x < bitmap->width(); ++x)
142 row[x] |= 0xFF000000; // Set alpha bits to 1.
143 }
144}
145#endif
146
[email protected]b9fad24c2012-11-15 08:22:10147void CopyCanvasToBitmap(SkCanvas* canvas, SkBitmap* snapshot) {
[email protected]9d611ca2012-11-14 13:46:56148 SkDevice* device = skia::GetTopDevice(*canvas);
[email protected]0799da02012-06-27 10:58:51149 const SkBitmap& bitmap = device->accessBitmap(false);
150 bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config);
151
152#if !defined(OS_MACOSX)
153 // Only the expected PNGs for Mac have a valid alpha channel.
154 MakeBitmapOpaque(snapshot);
155#endif
156
157}
158
[email protected]efb5f572012-01-29 10:57:33159} // namespace
[email protected]cccb5cf2012-06-06 22:20:04160
[email protected]9b4c6cd2012-08-20 10:47:45161WebKitTestRunner::WebKitTestRunner(RenderView* render_view)
[email protected]01f0cad02013-01-09 21:42:50162 : RenderViewObserver(render_view) {
163 Reset();
[email protected]31d71b02012-01-26 03:42:31164}
165
[email protected]9b4c6cd2012-08-20 10:47:45166WebKitTestRunner::~WebKitTestRunner() {
[email protected]31d71b02012-01-26 03:42:31167}
168
[email protected]b2324b092012-11-01 10:34:11169// WebTestDelegate -----------------------------------------------------------
170
171void WebKitTestRunner::clearContextMenuData() {
172 last_context_menu_data_.reset();
173}
174
175WebContextMenuData* WebKitTestRunner::lastContextMenuData() const {
176 return last_context_menu_data_.get();
177}
178
179void WebKitTestRunner::clearEditCommand() {
180 render_view()->ClearEditCommands();
181}
182
183void WebKitTestRunner::setEditCommand(const std::string& name,
184 const std::string& value) {
185 render_view()->SetEditCommandForNextKeyEvent(name, value);
186}
187
188void WebKitTestRunner::fillSpellingSuggestionList(
189 const WebString& word, WebVector<WebString>* suggestions) {
190 if (word == WebString::fromUTF8("wellcome")) {
191 WebVector<WebString> result(suggestions->size() + 1);
192 for (size_t i = 0; i < suggestions->size(); ++i)
193 result[i] = (*suggestions)[i];
194 result[suggestions->size()] = WebString::fromUTF8("welcome");
195 suggestions->swap(result);
196 }
197}
198
199void WebKitTestRunner::setGamepadData(const WebGamepads& gamepads) {
[email protected]e5196922012-12-11 22:18:25200 SetMockGamepads(gamepads);
[email protected]b2324b092012-11-01 10:34:11201}
202
203void WebKitTestRunner::printMessage(const std::string& message) {
204 Send(new ShellViewHostMsg_PrintMessage(routing_id(), message));
205}
206
207void WebKitTestRunner::postTask(WebTask* task) {
[email protected]2a58eb12012-12-18 07:56:40208 Platform::current()->callOnMainThread(InvokeTaskHelper, task);
[email protected]b2324b092012-11-01 10:34:11209}
210
211void WebKitTestRunner::postDelayedTask(WebTask* task, long long ms) {
212 MessageLoop::current()->PostDelayedTask(
213 FROM_HERE,
214 base::Bind(&WebTask::run, base::Owned(task)),
215 base::TimeDelta::FromMilliseconds(ms));
216}
217
218WebString WebKitTestRunner::registerIsolatedFileSystem(
219 const WebKit::WebVector<WebKit::WebString>& absolute_filenames) {
[email protected]d30a36f2013-02-07 04:16:26220 std::vector<base::FilePath> files;
[email protected]984a5f72012-12-13 21:41:50221 for (size_t i = 0; i < absolute_filenames.size(); ++i)
222 files.push_back(webkit_base::WebStringToFilePath(absolute_filenames[i]));
223 std::string filesystem_id;
224 Send(new ShellViewHostMsg_RegisterIsolatedFileSystem(
225 routing_id(), files, &filesystem_id));
226 return WebString::fromUTF8(filesystem_id);
[email protected]b2324b092012-11-01 10:34:11227}
228
229long long WebKitTestRunner::getCurrentTimeInMillisecond() {
230 return base::TimeTicks::Now().ToInternalValue() /
231 base::Time::kMicrosecondsPerMillisecond;
232}
233
234WebString WebKitTestRunner::getAbsoluteWebStringFromUTF8Path(
235 const std::string& utf8_path) {
[email protected]0d2dfb92d2012-11-05 10:26:45236#if defined(OS_WIN)
[email protected]d30a36f2013-02-07 04:16:26237 base::FilePath path(UTF8ToWide(utf8_path));
[email protected]0d2dfb92d2012-11-05 10:26:45238#else
[email protected]d30a36f2013-02-07 04:16:26239 base::FilePath path(base::SysWideToNativeMB(base::SysUTF8ToWide(utf8_path)));
[email protected]0d2dfb92d2012-11-05 10:26:45240#endif
241 if (!path.IsAbsolute()) {
242 GURL base_url =
243 net::FilePathToFileURL(current_working_directory_.Append(
244 FILE_PATH_LITERAL("foo")));
245 net::FileURLToFilePath(base_url.Resolve(utf8_path), &path);
246 }
[email protected]984a5f72012-12-13 21:41:50247 return webkit_base::FilePathToWebString(path);
[email protected]b2324b092012-11-01 10:34:11248}
249
[email protected]09ec9f92012-12-17 09:46:36250WebURL WebKitTestRunner::localFileToDataURL(const WebURL& file_url) {
[email protected]d30a36f2013-02-07 04:16:26251 base::FilePath local_path;
[email protected]09ec9f92012-12-17 09:46:36252 if (!net::FileURLToFilePath(file_url, &local_path))
253 return WebURL();
254
255 std::string contents;
256 Send(new ShellViewHostMsg_ReadFileToString(
257 routing_id(), local_path, &contents));
258
259 std::string contents_base64;
260 if (!base::Base64Encode(contents, &contents_base64))
261 return WebURL();
262
263 const char data_url_prefix[] = "data:text/css:charset=utf-8;base64,";
264 return WebURL(GURL(data_url_prefix + contents_base64));
265}
266
267WebURL WebKitTestRunner::rewriteLayoutTestsURL(const std::string& utf8_url) {
268 const char kPrefix[] = "file:///tmp/LayoutTests/";
269 const int kPrefixLen = arraysize(kPrefix) - 1;
270
271 if (utf8_url.compare(0, kPrefixLen, kPrefix, kPrefixLen))
272 return WebURL(GURL(utf8_url));
273
[email protected]d30a36f2013-02-07 04:16:26274 base::FilePath replace_path =
[email protected]09ec9f92012-12-17 09:46:36275 ShellRenderProcessObserver::GetInstance()->webkit_source_dir().Append(
276 FILE_PATH_LITERAL("LayoutTests/"));
277#if defined(OS_WIN)
278 std::string utf8_path = WideToUTF8(replace_path.value());
279#else
280 std::string utf8_path =
281 WideToUTF8(base::SysNativeMBToWide(replace_path.value()));
282#endif
283 std::string new_url =
284 std::string("file://") + utf8_path + utf8_url.substr(kPrefixLen);
285 return WebURL(GURL(new_url));
286}
287
[email protected]b3dbcb5e2012-12-17 00:16:37288WebPreferences* WebKitTestRunner::preferences() {
289 return &prefs_;
290}
291
292void WebKitTestRunner::applyPreferences() {
293 webkit_glue::WebPreferences prefs = render_view()->GetWebkitPreferences();
[email protected]d48eab082012-12-19 09:25:47294 ExportLayoutTestSpecificPreferences(prefs_, &prefs);
[email protected]b3dbcb5e2012-12-17 00:16:37295 render_view()->SetWebkitPreferences(prefs);
[email protected]55915a72012-12-18 11:55:25296 Send(new ShellViewHostMsg_OverridePreferences(routing_id(), prefs));
[email protected]b3dbcb5e2012-12-17 00:16:37297}
298
[email protected]9d9ec982013-01-10 18:53:39299std::string WebKitTestRunner::makeURLErrorDescription(
300 const WebURLError& error) {
301 std::string domain = error.domain.utf8();
302 int code = error.reason;
303
304 if (domain == net::kErrorDomain) {
305 domain = "NSURLErrorDomain";
306 switch (error.reason) {
307 case net::ERR_ABORTED:
308 code = -999; // NSURLErrorCancelled
309 break;
310 case net::ERR_UNSAFE_PORT:
311 // Our unsafe port checking happens at the network stack level, but we
312 // make this translation here to match the behavior of stock WebKit.
313 domain = "WebKitErrorDomain";
314 code = 103;
315 break;
316 case net::ERR_ADDRESS_INVALID:
317 case net::ERR_ADDRESS_UNREACHABLE:
318 case net::ERR_NETWORK_ACCESS_DENIED:
319 code = -1004; // NSURLErrorCannotConnectToHost
320 break;
321 }
322 } else {
323 DLOG(WARNING) << "Unknown error domain";
324 }
325
326 return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">",
327 domain.c_str(), code, error.unreachableURL.spec().data());
328}
329
[email protected]b2324b092012-11-01 10:34:11330// RenderViewObserver --------------------------------------------------------
331
[email protected]9b4c6cd2012-08-20 10:47:45332void WebKitTestRunner::DidClearWindowObject(WebFrame* frame) {
[email protected]b2324b092012-11-01 10:34:11333 ShellRenderProcessObserver::GetInstance()->BindTestRunnersToWindow(frame);
[email protected]96b80b472012-07-03 19:41:56334}
335
[email protected]9b4c6cd2012-08-20 10:47:45336void WebKitTestRunner::DidFinishLoad(WebFrame* frame) {
[email protected]09c48ef52013-01-09 12:25:07337 if (!frame->parent()) {
[email protected]0ac1a032013-02-12 12:53:37338 if (!wait_until_done_) {
[email protected]09c48ef52013-01-09 12:25:07339 test_is_running_ = false;
[email protected]0ac1a032013-02-12 12:53:37340 CaptureDump();
341 }
[email protected]01f0cad02013-01-09 21:42:50342 load_finished_ = true;
[email protected]09c48ef52013-01-09 12:25:07343 }
[email protected]c272c5b2012-06-06 09:01:06344}
345
[email protected]b2324b092012-11-01 10:34:11346void WebKitTestRunner::DidRequestShowContextMenu(
347 WebFrame* frame,
348 const WebContextMenuData& data) {
349 last_context_menu_data_.reset(new WebContextMenuData(data));
350}
351
[email protected]9b4c6cd2012-08-20 10:47:45352bool WebKitTestRunner::OnMessageReceived(const IPC::Message& message) {
[email protected]efb5f572012-01-29 10:57:33353 bool handled = true;
[email protected]9b4c6cd2012-08-20 10:47:45354 IPC_BEGIN_MESSAGE_MAP(WebKitTestRunner, message)
[email protected]0ac1a032013-02-12 12:53:37355 IPC_MESSAGE_HANDLER(ShellViewMsg_SetTestConfiguration,
356 OnSetTestConfiguration)
[email protected]efb5f572012-01-29 10:57:33357 IPC_MESSAGE_UNHANDLED(handled = false)
358 IPC_END_MESSAGE_MAP()
359
360 return handled;
361}
362
[email protected]b9fad24c2012-11-15 08:22:10363// Public methods - -----------------------------------------------------------
364
[email protected]2dd3a27a2012-12-10 11:24:16365void WebKitTestRunner::NotifyDone() {
[email protected]0ac1a032013-02-12 12:53:37366 if (load_finished_) {
[email protected]01f0cad02013-01-09 21:42:50367 test_is_running_ = false;
[email protected]0ac1a032013-02-12 12:53:37368 CaptureDump();
369 } else {
[email protected]01f0cad02013-01-09 21:42:50370 wait_until_done_ = false;
[email protected]0ac1a032013-02-12 12:53:37371 }
[email protected]2dd3a27a2012-12-10 11:24:16372}
373
374void WebKitTestRunner::DumpAsText() {
[email protected]0ac1a032013-02-12 12:53:37375 dump_as_text_ = true;
[email protected]2dd3a27a2012-12-10 11:24:16376}
377
378void WebKitTestRunner::DumpChildFramesAsText() {
[email protected]0ac1a032013-02-12 12:53:37379 dump_child_frames_as_text_ = true;
[email protected]2dd3a27a2012-12-10 11:24:16380}
381
[email protected]2dd3a27a2012-12-10 11:24:16382void WebKitTestRunner::WaitUntilDone() {
[email protected]09c48ef52013-01-09 12:25:07383 wait_until_done_ = true;
[email protected]2dd3a27a2012-12-10 11:24:16384}
385
[email protected]375db13a2012-12-18 21:42:58386void WebKitTestRunner::OverridePreference(const std::string& key,
387 v8::Local<v8::Value> value) {
388 if (key == "WebKitDefaultFontSize") {
389 prefs_.defaultFontSize = value->Int32Value();
390 } else if (key == "WebKitMinimumFontSize") {
391 prefs_.minimumFontSize = value->Int32Value();
392 } else if (key == "WebKitDefaultTextEncodingName") {
393 prefs_.defaultTextEncodingName =
394 WebString::fromUTF8(std::string(*v8::String::AsciiValue(value)));
395 } else if (key == "WebKitJavaScriptEnabled") {
396 prefs_.javaScriptEnabled = value->BooleanValue();
397 } else if (key == "WebKitSupportsMultipleWindows") {
398 prefs_.supportsMultipleWindows = value->BooleanValue();
399 } else if (key == "WebKitDisplayImagesKey") {
400 prefs_.loadsImagesAutomatically = value->BooleanValue();
401 } else if (key == "WebKitPluginsEnabled") {
402 prefs_.pluginsEnabled = value->BooleanValue();
403 } else if (key == "WebKitJavaEnabled") {
404 prefs_.javaEnabled = value->BooleanValue();
405 } else if (key == "WebKitUsesPageCachePreferenceKey") {
406 prefs_.usesPageCache = value->BooleanValue();
407 } else if (key == "WebKitPageCacheSupportsPluginsPreferenceKey") {
408 prefs_.pageCacheSupportsPlugins = value->BooleanValue();
409 } else if (key == "WebKitOfflineWebApplicationCacheEnabled") {
410 prefs_.offlineWebApplicationCacheEnabled = value->BooleanValue();
411 } else if (key == "WebKitTabToLinksPreferenceKey") {
412 prefs_.tabsToLinks = value->BooleanValue();
413 } else if (key == "WebKitWebGLEnabled") {
414 prefs_.experimentalWebGLEnabled = value->BooleanValue();
415 } else if (key == "WebKitCSSRegionsEnabled") {
416 prefs_.experimentalCSSRegionsEnabled = value->BooleanValue();
417 } else if (key == "WebKitCSSGridLayoutEnabled") {
418 prefs_.experimentalCSSGridLayoutEnabled = value->BooleanValue();
419 } else if (key == "WebKitHyperlinkAuditingEnabled") {
420 prefs_.hyperlinkAuditingEnabled = value->BooleanValue();
421 } else if (key == "WebKitEnableCaretBrowsing") {
422 prefs_.caretBrowsingEnabled = value->BooleanValue();
423 } else if (key == "WebKitAllowDisplayingInsecureContent") {
424 prefs_.allowDisplayOfInsecureContent = value->BooleanValue();
425 } else if (key == "WebKitAllowRunningInsecureContent") {
426 prefs_.allowRunningOfInsecureContent = value->BooleanValue();
427 } else if (key == "WebKitCSSCustomFilterEnabled") {
428 prefs_.cssCustomFilterEnabled = value->BooleanValue();
429 } else if (key == "WebKitShouldRespectImageOrientation") {
430 prefs_.shouldRespectImageOrientation = value->BooleanValue();
431 } else if (key == "WebKitWebAudioEnabled") {
432 DCHECK(value->BooleanValue());
433 } else {
434 std::string message("CONSOLE MESSAGE: Invalid name for preference: ");
435 printMessage(message + key + "\n");
436 }
437 applyPreferences();
438}
439
[email protected]43c7e6952012-12-11 13:50:51440void WebKitTestRunner::NotImplemented(const std::string& object,
441 const std::string& method) {
[email protected]2dd3a27a2012-12-10 11:24:16442 Send(new ShellViewHostMsg_NotImplemented(routing_id(), object, method));
443}
444
[email protected]324825d2012-11-30 12:37:15445void WebKitTestRunner::Reset() {
[email protected]b3dbcb5e2012-12-17 00:16:37446 prefs_.reset();
[email protected]324825d2012-11-30 12:37:15447 webkit_glue::WebPreferences prefs = render_view()->GetWebkitPreferences();
[email protected]d48eab082012-12-19 09:25:47448 ExportLayoutTestSpecificPreferences(prefs_, &prefs);
[email protected]324825d2012-11-30 12:37:15449 render_view()->SetWebkitPreferences(prefs);
[email protected]09c48ef52013-01-09 12:25:07450 test_is_running_ = true;
[email protected]01f0cad02013-01-09 21:42:50451 load_finished_ = false;
[email protected]09c48ef52013-01-09 12:25:07452 wait_until_done_ = false;
[email protected]0ac1a032013-02-12 12:53:37453 dump_as_text_ = false;
454 dump_child_frames_as_text_ = false;
455 printing_ = false;
456 enable_pixel_dumping_ = true;
457 layout_test_timeout_ = 30 * 1000;
458 allow_external_pages_ = false;
459 expected_pixel_hash_ = std::string();
[email protected]324825d2012-11-30 12:37:15460}
461
[email protected]b2324b092012-11-01 10:34:11462// Private methods -----------------------------------------------------------
463
[email protected]0ac1a032013-02-12 12:53:37464void WebKitTestRunner::CaptureDump() {
465 std::string mime_type = render_view()->GetWebView()->mainFrame()->dataSource()
466 ->response().mimeType().utf8();
467 if (mime_type == "text/plain") {
468 dump_as_text_ = true;
469 enable_pixel_dumping_ = false;
470 }
471 CaptureTextDump();
472 if (enable_pixel_dumping_)
473 CaptureImageDump();
474 Send(new ShellViewHostMsg_TestFinished(routing_id(), false));
475}
476
477void WebKitTestRunner::CaptureTextDump() {
[email protected]c272c5b2012-06-06 09:01:06478 WebFrame* frame = render_view()->GetWebView()->mainFrame();
479 std::string dump;
[email protected]0ac1a032013-02-12 12:53:37480 if (dump_as_text_) {
481 dump = DumpFramesAsText(frame, printing_, dump_child_frames_as_text_);
[email protected]c272c5b2012-06-06 09:01:06482 } else {
483 WebFrame::RenderAsTextControls render_text_behavior =
484 WebFrame::RenderAsTextNormal;
[email protected]0ac1a032013-02-12 12:53:37485 if (printing_)
[email protected]c272c5b2012-06-06 09:01:06486 render_text_behavior |= WebFrame::RenderAsTextPrinting;
487 dump = frame->renderTreeAsText(render_text_behavior).utf8();
[email protected]0ac1a032013-02-12 12:53:37488 dump.append(DumpFrameScrollPosition(frame, dump_child_frames_as_text_));
[email protected]c272c5b2012-06-06 09:01:06489 }
[email protected]efb5f572012-01-29 10:57:33490 Send(new ShellViewHostMsg_TextDump(routing_id(), dump));
[email protected]31d71b02012-01-26 03:42:31491}
492
[email protected]0ac1a032013-02-12 12:53:37493void WebKitTestRunner::CaptureImageDump() {
[email protected]0799da02012-06-27 10:58:51494 SkBitmap snapshot;
[email protected]b9fad24c2012-11-15 08:22:10495 PaintInvalidatedRegion();
496 CopyCanvasToBitmap(GetCanvas(), &snapshot);
[email protected]0799da02012-06-27 10:58:51497
498 SkAutoLockPixels snapshot_lock(snapshot);
499 base::MD5Digest digest;
[email protected]e225b922012-08-18 01:43:04500#if defined(OS_ANDROID)
501 // On Android, pixel layout is RGBA, however, other Chrome platforms use BGRA.
502 const uint8_t* raw_pixels =
503 reinterpret_cast<const uint8_t*>(snapshot.getPixels());
504 size_t snapshot_size = snapshot.getSize();
505 scoped_array<uint8_t> reordered_pixels(new uint8_t[snapshot_size]);
506 for (size_t i = 0; i < snapshot_size; i += 4) {
507 reordered_pixels[i] = raw_pixels[i + 2];
508 reordered_pixels[i + 1] = raw_pixels[i + 1];
509 reordered_pixels[i + 2] = raw_pixels[i];
510 reordered_pixels[i + 3] = raw_pixels[i + 3];
511 }
512 base::MD5Sum(reordered_pixels.get(), snapshot_size, &digest);
513#else
[email protected]0799da02012-06-27 10:58:51514 base::MD5Sum(snapshot.getPixels(), snapshot.getSize(), &digest);
[email protected]e225b922012-08-18 01:43:04515#endif
[email protected]0799da02012-06-27 10:58:51516 std::string actual_pixel_hash = base::MD5DigestToBase16(digest);
517
[email protected]0ac1a032013-02-12 12:53:37518 if (actual_pixel_hash == expected_pixel_hash_) {
[email protected]0799da02012-06-27 10:58:51519 SkBitmap empty_image;
520 Send(new ShellViewHostMsg_ImageDump(
521 routing_id(), actual_pixel_hash, empty_image));
[email protected]e225b922012-08-18 01:43:04522 return;
[email protected]0799da02012-06-27 10:58:51523 }
524 Send(new ShellViewHostMsg_ImageDump(
525 routing_id(), actual_pixel_hash, snapshot));
526}
527
[email protected]0ac1a032013-02-12 12:53:37528void WebKitTestRunner::OnSetTestConfiguration(
529 const base::FilePath& current_working_directory,
530 bool enable_pixel_dumping,
531 int layout_test_timeout,
532 bool allow_external_pages,
533 const std::string& expected_pixel_hash) {
[email protected]0d2dfb92d2012-11-05 10:26:45534 current_working_directory_ = current_working_directory;
[email protected]0ac1a032013-02-12 12:53:37535 enable_pixel_dumping_ = enable_pixel_dumping;
536 layout_test_timeout_ = layout_test_timeout;
537 allow_external_pages_ = allow_external_pages;
538 expected_pixel_hash_ = expected_pixel_hash;
[email protected]0d2dfb92d2012-11-05 10:26:45539}
540
[email protected]b9fad24c2012-11-15 08:22:10541SkCanvas* WebKitTestRunner::GetCanvas() {
542 WebView* view = render_view()->GetWebView();
543 const WebSize& size = view->size();
544 float device_scale_factor = view->deviceScaleFactor();
545 int width = std::ceil(device_scale_factor * size.width);
546 int height = std::ceil(device_scale_factor * size.height);
547
548 if (canvas_ &&
549 canvas_->getDeviceSize().width() == width &&
550 canvas_->getDeviceSize().height() == height) {
551 return canvas_.get();
552 }
553 canvas_.reset(skia::CreatePlatformCanvas(
554 size.width, size.height, true, 0, skia::RETURN_NULL_ON_FAILURE));
555 return canvas_.get();
556}
557
558void WebKitTestRunner::PaintRect(const WebRect& rect) {
559 WebView* view = render_view()->GetWebView();
560 float device_scale_factor = view->deviceScaleFactor();
561 int scaled_x = device_scale_factor * rect.x;
562 int scaled_y = device_scale_factor * rect.y;
563 int scaled_width = std::ceil(device_scale_factor * rect.width);
564 int scaled_height = std::ceil(device_scale_factor * rect.height);
565 // TODO(jochen): Verify that the scaling is correct once the HiDPI tests
566 // actually work.
567 WebRect device_rect(scaled_x, scaled_y, scaled_width, scaled_height);
568 view->paint(webkit_glue::ToWebCanvas(GetCanvas()), device_rect);
569}
570
571void WebKitTestRunner::PaintInvalidatedRegion() {
572 WebView* view = render_view()->GetWebView();
573 view->animate(0.0);
574 view->layout();
575 const WebSize& widget_size = view->size();
576 WebRect client_rect(0, 0, widget_size.width, widget_size.height);
577
578 // Paint the canvas if necessary. Allow painting to generate extra rects
579 // for the first two calls. This is necessary because some WebCore rendering
580 // objects update their layout only when painted.
581 for (int i = 0; i < 3; ++i) {
582 // Make sure that paint_rect is always inside the RenderView's visible
583 // area.
584 WebRect paint_rect = proxy_->paintRect();
585 int left = std::max(paint_rect.x, client_rect.x);
586 int top = std::max(paint_rect.y, client_rect.y);
587 int right = std::min(paint_rect.x + paint_rect.width,
588 client_rect.x + client_rect.width);
589 int bottom = std::min(paint_rect.y + paint_rect.height,
590 client_rect.y + client_rect.height);
591 WebRect rect;
592 if (left < right && top < bottom)
593 rect = WebRect(left, top, right - left, bottom - top);
594 proxy_->setPaintRect(WebRect());
595 if (rect.isEmpty())
596 continue;
597 PaintRect(rect);
598 }
599 CHECK(proxy_->paintRect().isEmpty());
600}
601
602void WebKitTestRunner::DisplayRepaintMask() {
603 GetCanvas()->drawARGB(167, 0, 0, 0);
604}
605
[email protected]31d71b02012-01-26 03:42:31606} // namespace content