| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/shell/webkit_test_runner_host.h" | 5 #include "content/shell/webkit_test_runner_host.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "content/public/browser/render_view_host.h" | 9 #include "content/public/browser/render_view_host.h" |
| 10 #include "content/public/browser/web_contents.h" |
| 11 #include "content/shell/shell.h" |
| 12 #include "content/shell/shell_browser_context.h" |
| 13 #include "content/shell/shell_content_browser_client.h" |
| 10 #include "content/shell/shell_messages.h" | 14 #include "content/shell/shell_messages.h" |
| 11 #include "content/shell/shell_switches.h" | 15 #include "content/shell/shell_switches.h" |
| 12 #include "webkit/support/webkit_support_gfx.h" | 16 #include "webkit/support/webkit_support_gfx.h" |
| 13 | 17 |
| 14 namespace content { | 18 namespace content { |
| 15 | 19 |
| 16 namespace { | 20 namespace { |
| 17 const int kTestTimeoutMilliseconds = 30 * 1000; | 21 const int kTestTimeoutMilliseconds = 30 * 1000; |
| 18 } // namespace | 22 } // namespace |
| 19 | 23 |
| 20 std::map<RenderViewHost*, WebKitTestRunnerHost*> | 24 WebKitTestController* WebKitTestController::instance_ = NULL; |
| 21 WebKitTestRunnerHost::controllers_; | |
| 22 std::string WebKitTestRunnerHost::expected_pixel_hash_; | |
| 23 | 25 |
| 24 // static | 26 // static |
| 25 WebKitTestRunnerHost* WebKitTestRunnerHost::FromRenderViewHost( | 27 WebKitTestController* WebKitTestController::Get() { |
| 26 RenderViewHost* render_view_host) { | 28 DCHECK(!instance_ || instance_->CalledOnValidThread()); |
| 27 const std::map<RenderViewHost*, WebKitTestRunnerHost*>::iterator it = | 29 return instance_; |
| 28 controllers_.find(render_view_host); | |
| 29 if (it == controllers_.end()) | |
| 30 return NULL; | |
| 31 return it->second; | |
| 32 } | 30 } |
| 33 | 31 |
| 34 // static | 32 WebKitTestController::WebKitTestController() { |
| 35 void WebKitTestRunnerHost::Init(const std::string& expected_pixel_hash) { | 33 CHECK(!instance_); |
| 36 // TODO(jochen): We should only dump the results for the "main window". | 34 instance_ = this; |
| 37 expected_pixel_hash_ = expected_pixel_hash; | 35 |
| 36 ResetAfterLayoutTest(); |
| 37 |
| 38 content::ShellBrowserContext* browser_context = |
| 39 static_cast<content::ShellContentBrowserClient*>( |
| 40 content::GetContentClient()->browser())->browser_context(); |
| 41 main_window_ = content::Shell::CreateNewWindow( |
| 42 browser_context, |
| 43 GURL("about:blank"), |
| 44 NULL, |
| 45 MSG_ROUTING_NONE, |
| 46 NULL); |
| 47 Observe(main_window_->web_contents()); |
| 38 } | 48 } |
| 39 | 49 |
| 40 WebKitTestRunnerHost::WebKitTestRunnerHost( | 50 WebKitTestController::~WebKitTestController() { |
| 41 RenderViewHost* render_view_host) | 51 DCHECK(CalledOnValidThread()); |
| 42 : RenderViewHostObserver(render_view_host), | 52 CHECK(instance_ == this); |
| 43 captured_dump_(false), | 53 if (main_window_) |
| 44 dump_as_text_(false), | 54 main_window_->Close(); |
| 45 dump_child_frames_(false), | 55 instance_ = NULL; |
| 46 is_printing_(false), | |
| 47 should_stay_on_page_after_handling_before_unload_(false), | |
| 48 wait_until_done_(false) { | |
| 49 controllers_[render_view_host] = this; | |
| 50 } | 56 } |
| 51 | 57 |
| 52 WebKitTestRunnerHost::~WebKitTestRunnerHost() { | 58 void WebKitTestController::PrepareForLayoutTest( |
| 53 controllers_.erase(render_view_host()); | 59 const GURL& test_url, const std::string& expected_pixel_hash) { |
| 54 watchdog_.Cancel(); | 60 DCHECK(CalledOnValidThread()); |
| 61 DCHECK(main_window_); |
| 62 expected_pixel_hash_ = expected_pixel_hash; |
| 63 main_window_->LoadURL(test_url); |
| 55 } | 64 } |
| 56 | 65 |
| 57 void WebKitTestRunnerHost::CaptureDump() { | 66 bool WebKitTestController::ResetAfterLayoutTest() { |
| 67 DCHECK(CalledOnValidThread()); |
| 68 expected_pixel_hash_.clear(); |
| 69 captured_dump_ = false; |
| 70 dump_as_text_ = false; |
| 71 dump_child_frames_ = false; |
| 72 is_printing_ = false; |
| 73 should_stay_on_page_after_handling_before_unload_ = false; |
| 74 wait_until_done_ = false; |
| 75 watchdog_.Cancel(); |
| 76 return main_window_ != NULL; |
| 77 } |
| 78 |
| 79 void WebKitTestController::LoadFinished(Shell* window) { |
| 80 if (wait_until_done_) |
| 81 return; |
| 82 |
| 83 if (window == main_window_) |
| 84 CaptureDump(); |
| 85 } |
| 86 |
| 87 void WebKitTestController::NotifyDone() { |
| 88 if (!wait_until_done_) |
| 89 return; |
| 90 watchdog_.Cancel(); |
| 91 CaptureDump(); |
| 92 } |
| 93 |
| 94 void WebKitTestController::WaitUntilDone() { |
| 95 if (wait_until_done_) |
| 96 return; |
| 97 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoTimeout)) { |
| 98 watchdog_.Reset(base::Bind(&WebKitTestController::TimeoutHandler, |
| 99 base::Unretained(this))); |
| 100 MessageLoop::current()->PostDelayedTask( |
| 101 FROM_HERE, |
| 102 watchdog_.callback(), |
| 103 base::TimeDelta::FromMilliseconds(kTestTimeoutMilliseconds)); |
| 104 } |
| 105 wait_until_done_ = true; |
| 106 } |
| 107 |
| 108 void WebKitTestController::NotImplemented( |
| 109 const std::string& object_name, |
| 110 const std::string& property_name) { |
| 58 if (captured_dump_) | 111 if (captured_dump_) |
| 59 return; | 112 return; |
| 113 printf("FAIL: NOT IMPLEMENTED: %s.%s\n", |
| 114 object_name.c_str(), property_name.c_str()); |
| 115 fprintf(stderr, "FAIL: NOT IMPLEMENTED: %s.%s\n", |
| 116 object_name.c_str(), property_name.c_str()); |
| 117 watchdog_.Cancel(); |
| 118 CaptureDump(); |
| 119 } |
| 120 |
| 121 void WebKitTestController::WebContentsDestroyed(WebContents* web_contents) { |
| 122 main_window_ = NULL; |
| 123 printf("FAIL: main window was destroyed\n"); |
| 124 fprintf(stderr, "FAIL: main window was destroyed\n"); |
| 125 watchdog_.Cancel(); |
| 126 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 127 } |
| 128 |
| 129 void WebKitTestController::CaptureDump() { |
| 130 if (captured_dump_ || !main_window_) |
| 131 return; |
| 60 captured_dump_ = true; | 132 captured_dump_ = true; |
| 61 | 133 |
| 62 render_view_host()->Send( | 134 RenderViewHost* render_view_host = |
| 63 new ShellViewMsg_CaptureTextDump(render_view_host()->GetRoutingID(), | 135 main_window_->web_contents()->GetRenderViewHost(); |
| 64 dump_as_text_, | 136 |
| 65 is_printing_, | 137 render_view_host->Send(new ShellViewMsg_CaptureTextDump( |
| 66 dump_child_frames_)); | 138 render_view_host->GetRoutingID(), |
| 139 dump_as_text_, |
| 140 is_printing_, |
| 141 dump_child_frames_)); |
| 67 if (!dump_as_text_) { | 142 if (!dump_as_text_) { |
| 68 render_view_host()->Send( | 143 render_view_host->Send(new ShellViewMsg_CaptureImageDump( |
| 69 new ShellViewMsg_CaptureImageDump(render_view_host()->GetRoutingID(), | 144 render_view_host->GetRoutingID(), |
| 70 expected_pixel_hash_)); | 145 expected_pixel_hash_)); |
| 71 } | 146 } |
| 72 } | 147 } |
| 73 | 148 |
| 74 void WebKitTestRunnerHost::TimeoutHandler() { | 149 void WebKitTestController::TimeoutHandler() { |
| 75 printf("FAIL: Timed out waiting for notifyDone to be called\n"); | 150 printf("FAIL: Timed out waiting for notifyDone to be called\n"); |
| 76 fprintf(stderr, "FAIL: Timed out waiting for notifyDone to be called\n"); | 151 fprintf(stderr, "FAIL: Timed out waiting for notifyDone to be called\n"); |
| 77 CaptureDump(); | 152 CaptureDump(); |
| 78 } | 153 } |
| 79 | 154 |
| 155 WebKitTestRunnerHost::WebKitTestRunnerHost( |
| 156 RenderViewHost* render_view_host) |
| 157 : RenderViewHostObserver(render_view_host) { |
| 158 } |
| 159 |
| 160 WebKitTestRunnerHost::~WebKitTestRunnerHost() { |
| 161 } |
| 162 |
| 80 bool WebKitTestRunnerHost::OnMessageReceived( | 163 bool WebKitTestRunnerHost::OnMessageReceived( |
| 81 const IPC::Message& message) { | 164 const IPC::Message& message) { |
| 82 bool handled = true; | 165 bool handled = true; |
| 83 IPC_BEGIN_MESSAGE_MAP(WebKitTestRunnerHost, message) | 166 IPC_BEGIN_MESSAGE_MAP(WebKitTestRunnerHost, message) |
| 84 IPC_MESSAGE_HANDLER(ShellViewHostMsg_DidFinishLoad, OnDidFinishLoad) | 167 IPC_MESSAGE_HANDLER(ShellViewHostMsg_DidFinishLoad, OnDidFinishLoad) |
| 85 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TextDump, OnTextDump) | 168 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TextDump, OnTextDump) |
| 86 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ImageDump, OnImageDump) | 169 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ImageDump, OnImageDump) |
| 87 IPC_MESSAGE_HANDLER(ShellViewHostMsg_NotifyDone, OnNotifyDone) | 170 IPC_MESSAGE_HANDLER(ShellViewHostMsg_NotifyDone, OnNotifyDone) |
| 88 IPC_MESSAGE_HANDLER(ShellViewHostMsg_DumpAsText, OnDumpAsText) | 171 IPC_MESSAGE_HANDLER(ShellViewHostMsg_DumpAsText, OnDumpAsText) |
| 89 IPC_MESSAGE_HANDLER(ShellViewHostMsg_DumpChildFramesAsText, | 172 IPC_MESSAGE_HANDLER(ShellViewHostMsg_DumpChildFramesAsText, |
| 90 OnDumpChildFramesAsText) | 173 OnDumpChildFramesAsText) |
| 91 IPC_MESSAGE_HANDLER(ShellViewHostMsg_SetPrinting, OnSetPrinting) | 174 IPC_MESSAGE_HANDLER(ShellViewHostMsg_SetPrinting, OnSetPrinting) |
| 92 IPC_MESSAGE_HANDLER( | 175 IPC_MESSAGE_HANDLER( |
| 93 ShellViewHostMsg_SetShouldStayOnPageAfterHandlingBeforeUnload, | 176 ShellViewHostMsg_SetShouldStayOnPageAfterHandlingBeforeUnload, |
| 94 OnSetShouldStayOnPageAfterHandlingBeforeUnload) | 177 OnSetShouldStayOnPageAfterHandlingBeforeUnload) |
| 95 IPC_MESSAGE_HANDLER(ShellViewHostMsg_WaitUntilDone, OnWaitUntilDone) | 178 IPC_MESSAGE_HANDLER(ShellViewHostMsg_WaitUntilDone, OnWaitUntilDone) |
| 96 IPC_MESSAGE_HANDLER(ShellViewHostMsg_NotImplemented, OnNotImplemented) | 179 IPC_MESSAGE_HANDLER(ShellViewHostMsg_NotImplemented, OnNotImplemented) |
| 97 IPC_MESSAGE_UNHANDLED(handled = false) | 180 IPC_MESSAGE_UNHANDLED(handled = false) |
| 98 IPC_END_MESSAGE_MAP() | 181 IPC_END_MESSAGE_MAP() |
| 99 | 182 |
| 100 return handled; | 183 return handled; |
| 101 } | 184 } |
| 102 | 185 |
| 103 void WebKitTestRunnerHost::OnDidFinishLoad() { | 186 void WebKitTestRunnerHost::OnDidFinishLoad() { |
| 104 if (wait_until_done_) | 187 WebKitTestController::Get()->LoadFinished( |
| 105 return; | 188 Shell::FromRenderViewHost(render_view_host())); |
| 106 | |
| 107 CaptureDump(); | |
| 108 } | 189 } |
| 109 | 190 |
| 110 void WebKitTestRunnerHost::OnTextDump(const std::string& dump) { | 191 void WebKitTestRunnerHost::OnTextDump(const std::string& dump) { |
| 111 printf("%s#EOF\n", dump.c_str()); | 192 printf("%s#EOF\n", dump.c_str()); |
| 112 fprintf(stderr, "#EOF\n"); | 193 fprintf(stderr, "#EOF\n"); |
| 113 | 194 |
| 114 if (dump_as_text_) | 195 if (WebKitTestController::Get()->dump_as_text()) |
| 115 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 196 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 116 } | 197 } |
| 117 | 198 |
| 118 void WebKitTestRunnerHost::OnImageDump( | 199 void WebKitTestRunnerHost::OnImageDump( |
| 119 const std::string& actual_pixel_hash, | 200 const std::string& actual_pixel_hash, |
| 120 const SkBitmap& image) { | 201 const SkBitmap& image) { |
| 121 SkAutoLockPixels image_lock(image); | 202 SkAutoLockPixels image_lock(image); |
| 122 | 203 |
| 123 printf("\nActualHash: %s\n", actual_pixel_hash.c_str()); | 204 printf("\nActualHash: %s\n", actual_pixel_hash.c_str()); |
| 124 if (!expected_pixel_hash_.empty()) | 205 std::string expected_pixel_hash = |
| 125 printf("\nExpectedHash: %s\n", expected_pixel_hash_.c_str()); | 206 WebKitTestController::Get()->expected_pixel_hash(); |
| 207 if (!expected_pixel_hash.empty()) |
| 208 printf("\nExpectedHash: %s\n", expected_pixel_hash.c_str()); |
| 126 | 209 |
| 127 // Only encode and dump the png if the hashes don't match. Encoding the | 210 // Only encode and dump the png if the hashes don't match. Encoding the |
| 128 // image is really expensive. | 211 // image is really expensive. |
| 129 if (actual_pixel_hash != expected_pixel_hash_) { | 212 if (actual_pixel_hash != expected_pixel_hash) { |
| 130 std::vector<unsigned char> png; | 213 std::vector<unsigned char> png; |
| 131 | 214 |
| 132 // Only the expected PNGs for Mac have a valid alpha channel. | 215 // Only the expected PNGs for Mac have a valid alpha channel. |
| 133 #if defined(OS_MACOSX) | 216 #if defined(OS_MACOSX) |
| 134 bool discard_transparency = false; | 217 bool discard_transparency = false; |
| 135 #else | 218 #else |
| 136 bool discard_transparency = true; | 219 bool discard_transparency = true; |
| 137 #endif | 220 #endif |
| 138 | 221 |
| 139 bool success = false; | 222 bool success = false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 160 printf("Content-Type: image/png\n"); | 243 printf("Content-Type: image/png\n"); |
| 161 printf("Content-Length: %u\n", static_cast<unsigned>(png.size())); | 244 printf("Content-Length: %u\n", static_cast<unsigned>(png.size())); |
| 162 fwrite(&png[0], 1, png.size(), stdout); | 245 fwrite(&png[0], 1, png.size(), stdout); |
| 163 } | 246 } |
| 164 } | 247 } |
| 165 | 248 |
| 166 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 249 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 167 } | 250 } |
| 168 | 251 |
| 169 void WebKitTestRunnerHost::OnNotifyDone() { | 252 void WebKitTestRunnerHost::OnNotifyDone() { |
| 170 if (!wait_until_done_) | 253 WebKitTestController::Get()->NotifyDone(); |
| 171 return; | |
| 172 watchdog_.Cancel(); | |
| 173 CaptureDump(); | |
| 174 } | 254 } |
| 175 | 255 |
| 176 void WebKitTestRunnerHost::OnDumpAsText() { | 256 void WebKitTestRunnerHost::OnDumpAsText() { |
| 177 dump_as_text_ = true; | 257 WebKitTestController::Get()->set_dump_as_text(true); |
| 178 } | 258 } |
| 179 | 259 |
| 180 void WebKitTestRunnerHost::OnSetPrinting() { | 260 void WebKitTestRunnerHost::OnSetPrinting() { |
| 181 is_printing_ = true; | 261 WebKitTestController::Get()->set_is_printing(true); |
| 182 } | 262 } |
| 183 | 263 |
| 184 void WebKitTestRunnerHost::OnSetShouldStayOnPageAfterHandlingBeforeUnload( | 264 void WebKitTestRunnerHost::OnSetShouldStayOnPageAfterHandlingBeforeUnload( |
| 185 bool should_stay_on_page) { | 265 bool should_stay_on_page) { |
| 186 should_stay_on_page_after_handling_before_unload_ = should_stay_on_page; | 266 WebKitTestController* controller = WebKitTestController::Get(); |
| 267 controller->set_should_stay_on_page_after_handling_before_unload( |
| 268 should_stay_on_page); |
| 187 } | 269 } |
| 188 | 270 |
| 189 void WebKitTestRunnerHost::OnDumpChildFramesAsText() { | 271 void WebKitTestRunnerHost::OnDumpChildFramesAsText() { |
| 190 dump_child_frames_ = true; | 272 WebKitTestController::Get()->set_dump_child_frames(true); |
| 191 } | 273 } |
| 192 | 274 |
| 193 void WebKitTestRunnerHost::OnWaitUntilDone() { | 275 void WebKitTestRunnerHost::OnWaitUntilDone() { |
| 194 if (wait_until_done_) | 276 WebKitTestController::Get()->WaitUntilDone(); |
| 195 return; | |
| 196 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoTimeout)) { | |
| 197 watchdog_.Reset(base::Bind(&WebKitTestRunnerHost::TimeoutHandler, | |
| 198 base::Unretained(this))); | |
| 199 MessageLoop::current()->PostDelayedTask( | |
| 200 FROM_HERE, | |
| 201 watchdog_.callback(), | |
| 202 base::TimeDelta::FromMilliseconds(kTestTimeoutMilliseconds)); | |
| 203 } | |
| 204 wait_until_done_ = true; | |
| 205 } | 277 } |
| 206 | 278 |
| 207 void WebKitTestRunnerHost::OnNotImplemented( | 279 void WebKitTestRunnerHost::OnNotImplemented( |
| 208 const std::string& object_name, | 280 const std::string& object_name, |
| 209 const std::string& property_name) { | 281 const std::string& property_name) { |
| 210 if (captured_dump_) | 282 WebKitTestController::Get()->NotImplemented(object_name, property_name); |
| 211 return; | |
| 212 printf("FAIL: NOT IMPLEMENTED: %s.%s\n", | |
| 213 object_name.c_str(), property_name.c_str()); | |
| 214 fprintf(stderr, "FAIL: NOT IMPLEMENTED: %s.%s\n", | |
| 215 object_name.c_str(), property_name.c_str()); | |
| 216 watchdog_.Cancel(); | |
| 217 CaptureDump(); | |
| 218 } | 283 } |
| 219 | 284 |
| 220 } // namespace content | 285 } // namespace content |
| OLD | NEW |