| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #undef LOG | |
| 6 | |
| 7 #include "webkit/tools/test_shell/test_shell.h" | |
| 8 | |
| 9 #include "base/base_paths.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/debug/debug_on_start_win.h" | |
| 12 #include "base/file_util.h" | |
| 13 #include "base/files/file_path.h" | |
| 14 #include "base/md5.h" | |
| 15 #include "base/message_loop.h" | |
| 16 #include "base/metrics/stats_table.h" | |
| 17 #include "base/path_service.h" | |
| 18 #include "base/string_util.h" | |
| 19 #include "base/utf_string_conversions.h" | |
| 20 #include "build/build_config.h" | |
| 21 #include "googleurl/src/url_util.h" | |
| 22 #include "grit/webkit_strings.h" | |
| 23 #include "net/base/mime_util.h" | |
| 24 #include "net/base/net_util.h" | |
| 25 #include "net/url_request/url_request.h" | |
| 26 #include "net/url_request/url_request_file_job.h" | |
| 27 #include "net/url_request/url_request_filter.h" | |
| 28 #include "skia/ext/bitmap_platform_device.h" | |
| 29 #include "testing/gtest/include/gtest/gtest.h" | |
| 30 #include "third_party/skia/include/core/SkBitmap.h" | |
| 31 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" | |
| 32 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" | |
| 33 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | |
| 34 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | |
| 35 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h" | |
| 36 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h" | |
| 37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec
t.h" | |
| 38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDeviceOrientationC
lientMock.h" | |
| 39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
| 40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationClientM
ock.h" | |
| 41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | |
| 42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h
" | |
| 43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
| 44 #include "ui/gfx/codec/png_codec.h" | |
| 45 #include "ui/gfx/size.h" | |
| 46 #include "webkit/glue/glue_serialize.h" | |
| 47 #include "webkit/glue/webkit_glue.h" | |
| 48 #include "webkit/glue/webpreferences.h" | |
| 49 #include "webkit/tools/test_shell/notification_presenter.h" | |
| 50 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" | |
| 51 #include "webkit/tools/test_shell/test_navigation_controller.h" | |
| 52 #include "webkit/tools/test_shell/test_shell_devtools_agent.h" | |
| 53 #include "webkit/tools/test_shell/test_shell_devtools_client.h" | |
| 54 #include "webkit/tools/test_shell/test_shell_request_context.h" | |
| 55 #include "webkit/tools/test_shell/test_shell_switches.h" | |
| 56 #include "webkit/tools/test_shell/test_webview_delegate.h" | |
| 57 #include "webkit/user_agent/user_agent.h" | |
| 58 #include "webkit/user_agent/user_agent_util.h" | |
| 59 | |
| 60 using WebKit::WebCanvas; | |
| 61 using WebKit::WebFrame; | |
| 62 using WebKit::WebNavigationPolicy; | |
| 63 using WebKit::WebRect; | |
| 64 using WebKit::WebScriptController; | |
| 65 using WebKit::WebSize; | |
| 66 using WebKit::WebURLRequest; | |
| 67 using WebKit::WebView; | |
| 68 | |
| 69 namespace { | |
| 70 | |
| 71 // Default timeout in ms for file page loads when in layout test mode. | |
| 72 const int kDefaultFileTestTimeoutMillisecs = 10 * 1000; | |
| 73 | |
| 74 // Content area size for newly created windows. | |
| 75 const int kTestWindowWidth = 800; | |
| 76 const int kTestWindowHeight = 600; | |
| 77 | |
| 78 // The W3C SVG layout tests use a different size than the other layout | |
| 79 // tests. | |
| 80 const int kSVGTestWindowWidth = 480; | |
| 81 const int kSVGTestWindowHeight = 360; | |
| 82 | |
| 83 // URLRequestTestShellFileJob is used to serve the inspector | |
| 84 class URLRequestTestShellFileJob : public net::URLRequestFileJob { | |
| 85 public: | |
| 86 static net::URLRequestJob* InspectorFactory( | |
| 87 net::URLRequest* request, | |
| 88 net::NetworkDelegate* network_delegate, | |
| 89 const std::string& scheme) { | |
| 90 base::FilePath path; | |
| 91 PathService::Get(base::DIR_EXE, &path); | |
| 92 path = path.AppendASCII("resources"); | |
| 93 path = path.AppendASCII("inspector"); | |
| 94 path = path.AppendASCII(request->url().path().substr(1)); | |
| 95 return new URLRequestTestShellFileJob(request, network_delegate, path); | |
| 96 } | |
| 97 | |
| 98 private: | |
| 99 URLRequestTestShellFileJob(net::URLRequest* request, | |
| 100 net::NetworkDelegate* network_delegate, | |
| 101 const base::FilePath& path) | |
| 102 : net::URLRequestFileJob(request, network_delegate, path) { | |
| 103 } | |
| 104 virtual ~URLRequestTestShellFileJob() { } | |
| 105 | |
| 106 DISALLOW_COPY_AND_ASSIGN(URLRequestTestShellFileJob); | |
| 107 }; | |
| 108 | |
| 109 | |
| 110 } // namespace | |
| 111 | |
| 112 // Initialize static member variable | |
| 113 WindowList* TestShell::window_list_; | |
| 114 WebPreferences* TestShell::web_prefs_ = NULL; | |
| 115 bool TestShell::layout_test_mode_ = false; | |
| 116 bool TestShell::allow_external_pages_ = false; | |
| 117 std::vector<std::string> TestShell::js_flags_; | |
| 118 bool TestShell::accelerated_2d_canvas_enabled_ = false; | |
| 119 bool TestShell::accelerated_compositing_enabled_ = false; | |
| 120 | |
| 121 TestShell::TestParams::TestParams() | |
| 122 : dump_tree(true), | |
| 123 dump_pixels(false) { | |
| 124 } | |
| 125 | |
| 126 TestShell::TestShell() | |
| 127 : m_mainWnd(NULL), | |
| 128 m_editWnd(NULL), | |
| 129 m_webViewHost(NULL), | |
| 130 m_popupHost(NULL), | |
| 131 m_focusedWidgetHost(NULL), | |
| 132 #if defined(OS_WIN) | |
| 133 default_edit_wnd_proc_(0), | |
| 134 #endif | |
| 135 test_params_(NULL), | |
| 136 is_modal_(false), | |
| 137 is_loading_(false), | |
| 138 allow_images_(true), | |
| 139 allow_plugins_(true), | |
| 140 allow_scripts_(true), | |
| 141 dump_stats_table_on_exit_(false) { | |
| 142 delegate_.reset(new TestWebViewDelegate(this)); | |
| 143 popup_delegate_.reset(new TestWebViewDelegate(this)); | |
| 144 navigation_controller_.reset(new TestNavigationController(this)); | |
| 145 notification_presenter_.reset(new TestNotificationPresenter(this)); | |
| 146 | |
| 147 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); | |
| 148 filter->AddHostnameHandler("test-shell-resource", "inspector", | |
| 149 &URLRequestTestShellFileJob::InspectorFactory); | |
| 150 url_util::AddStandardScheme("test-shell-resource"); | |
| 151 webkit_glue::SetUserAgent(webkit_glue::BuildUserAgentFromProduct( | |
| 152 "TestShell/0.0.0.0"), false); | |
| 153 } | |
| 154 | |
| 155 TestShell::~TestShell() { | |
| 156 delegate_->RevokeDragDrop(); | |
| 157 | |
| 158 // DevTools frontend page is supposed to be navigated only once and | |
| 159 // loading another URL in that Page is an error. | |
| 160 if (!dev_tools_client_.get()) { | |
| 161 // Navigate to an empty page to fire all the destruction logic for the | |
| 162 // current page. | |
| 163 LoadURL(GURL("about:blank")); | |
| 164 } | |
| 165 | |
| 166 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); | |
| 167 filter->RemoveHostnameHandler("test-shell-resource", "inspector"); | |
| 168 | |
| 169 // Call GC twice to clean up garbage. | |
| 170 CallJSGC(); | |
| 171 CallJSGC(); | |
| 172 | |
| 173 // Destroy the WebView before the TestWebViewDelegate. | |
| 174 m_webViewHost.reset(); | |
| 175 | |
| 176 CloseDevTools(); | |
| 177 | |
| 178 PlatformCleanUp(); | |
| 179 | |
| 180 base::StatsTable *table = base::StatsTable::current(); | |
| 181 if (dump_stats_table_on_exit_) { | |
| 182 // Dump the stats table. | |
| 183 printf("<stats>\n"); | |
| 184 if (table != NULL) { | |
| 185 int counter_max = table->GetMaxCounters(); | |
| 186 for (int index = 0; index < counter_max; index++) { | |
| 187 std::string name(table->GetRowName(index)); | |
| 188 if (name.length() > 0) { | |
| 189 int value = table->GetRowValue(index); | |
| 190 printf("%s:\t%d\n", name.c_str(), value); | |
| 191 } | |
| 192 } | |
| 193 } | |
| 194 printf("</stats>\n"); | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 void TestShell::UpdateNavigationControls() { | |
| 199 int current_index = navigation_controller()->GetCurrentEntryIndex(); | |
| 200 int max_index = navigation_controller()->GetEntryCount() - 1; | |
| 201 | |
| 202 EnableUIControl(BACK_BUTTON, current_index > 0); | |
| 203 EnableUIControl(FORWARD_BUTTON, current_index < max_index); | |
| 204 EnableUIControl(STOP_BUTTON, is_loading_); | |
| 205 } | |
| 206 | |
| 207 bool TestShell::CreateNewWindow(const GURL& starting_url, | |
| 208 TestShell** result) { | |
| 209 TestShell* shell = new TestShell(); | |
| 210 bool rv = shell->Initialize(starting_url); | |
| 211 if (rv) { | |
| 212 if (result) | |
| 213 *result = shell; | |
| 214 TestShell::windowList()->push_back(shell->m_mainWnd); | |
| 215 } | |
| 216 return rv; | |
| 217 } | |
| 218 | |
| 219 void TestShell::ShutdownTestShell() { | |
| 220 PlatformShutdown(); | |
| 221 SimpleResourceLoaderBridge::Shutdown(); | |
| 222 delete window_list_; | |
| 223 delete TestShell::web_prefs_; | |
| 224 } | |
| 225 | |
| 226 // All fatal log messages (e.g. DCHECK failures) imply unit test failures | |
| 227 static void UnitTestAssertHandler(const std::string& str) { | |
| 228 FAIL() << str; | |
| 229 } | |
| 230 | |
| 231 // static | |
| 232 void TestShell::InitLogging(bool suppress_error_dialogs, | |
| 233 bool layout_test_mode, | |
| 234 bool enable_gp_fault_error_box) { | |
| 235 if (suppress_error_dialogs) | |
| 236 logging::SetLogAssertHandler(UnitTestAssertHandler); | |
| 237 | |
| 238 #if defined(OS_WIN) | |
| 239 if (!IsDebuggerPresent()) { | |
| 240 UINT new_flags = SEM_FAILCRITICALERRORS | | |
| 241 SEM_NOOPENFILEERRORBOX; | |
| 242 if (!enable_gp_fault_error_box) | |
| 243 new_flags |= SEM_NOGPFAULTERRORBOX; | |
| 244 | |
| 245 // Preserve existing error mode, as discussed at | |
| 246 // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx | |
| 247 UINT existing_flags = SetErrorMode(new_flags); | |
| 248 SetErrorMode(existing_flags | new_flags); | |
| 249 } | |
| 250 #endif | |
| 251 | |
| 252 // Only log to a file if we're running layout tests. This prevents debugging | |
| 253 // output from disrupting whether or not we pass. | |
| 254 logging::LoggingDestination destination = | |
| 255 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG; | |
| 256 if (layout_test_mode) | |
| 257 destination = logging::LOG_ONLY_TO_FILE; | |
| 258 | |
| 259 // We might have multiple test_shell processes going at once | |
| 260 base::FilePath log_filename; | |
| 261 PathService::Get(base::DIR_EXE, &log_filename); | |
| 262 log_filename = log_filename.AppendASCII("test_shell.log"); | |
| 263 logging::InitLogging( | |
| 264 log_filename.value().c_str(), | |
| 265 destination, | |
| 266 logging::LOCK_LOG_FILE, | |
| 267 logging::DELETE_OLD_LOG_FILE, | |
| 268 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); | |
| 269 | |
| 270 // we want process and thread IDs because we may have multiple processes | |
| 271 logging::SetLogItems(true, true, false, true); | |
| 272 | |
| 273 // Turn on logging of notImplemented()s inside WebKit, but only if we're | |
| 274 // not running layout tests (because otherwise they'd corrupt the test | |
| 275 // output). | |
| 276 if (!layout_test_mode) | |
| 277 webkit_glue::EnableWebCoreLogChannels("NotYetImplemented"); | |
| 278 } | |
| 279 | |
| 280 // static | |
| 281 void TestShell::CleanupLogging() { | |
| 282 logging::CloseLogFile(); | |
| 283 } | |
| 284 | |
| 285 // static | |
| 286 void TestShell::SetAllowScriptsToCloseWindows() { | |
| 287 if (web_prefs_) | |
| 288 web_prefs_->allow_scripts_to_close_windows = true; | |
| 289 } | |
| 290 | |
| 291 // static | |
| 292 void TestShell::SetAccelerated2dCanvasEnabled(bool enabled) { | |
| 293 accelerated_2d_canvas_enabled_ = enabled; | |
| 294 } | |
| 295 | |
| 296 // static | |
| 297 void TestShell::SetAcceleratedCompositingEnabled(bool enabled) { | |
| 298 accelerated_compositing_enabled_ = enabled; | |
| 299 } | |
| 300 | |
| 301 // static | |
| 302 void TestShell::ResetWebPreferences() { | |
| 303 DCHECK(web_prefs_); | |
| 304 | |
| 305 // Match the settings used by Mac DumpRenderTree, with the exception of | |
| 306 // fonts. | |
| 307 if (web_prefs_) { | |
| 308 *web_prefs_ = WebPreferences(); | |
| 309 | |
| 310 #if defined(OS_MACOSX) | |
| 311 web_prefs_->serif_font_family_map[webkit_glue::kCommonScript] = | |
| 312 ASCIIToUTF16("Times"); | |
| 313 web_prefs_->cursive_font_family_map[webkit_glue::kCommonScript] = | |
| 314 ASCIIToUTF16("Apple Chancery"); | |
| 315 web_prefs_->fantasy_font_family_map[webkit_glue::kCommonScript] = | |
| 316 ASCIIToUTF16("Papyrus"); | |
| 317 #else | |
| 318 // NOTE: case matters here, this must be 'times new roman', else | |
| 319 // some layout tests fail. | |
| 320 web_prefs_->serif_font_family_map[webkit_glue::kCommonScript] = | |
| 321 ASCIIToUTF16("times new roman"); | |
| 322 | |
| 323 // These two fonts are picked from the intersection of | |
| 324 // Win XP font list and Vista font list : | |
| 325 // http://www.microsoft.com/typography/fonts/winxp.htm | |
| 326 // http://blogs.msdn.com/michkap/archive/2006/04/04/567881.aspx | |
| 327 // Some of them are installed only with CJK and complex script | |
| 328 // support enabled on Windows XP and are out of consideration here. | |
| 329 // (although we enabled both on our buildbots.) | |
| 330 // They (especially Impact for fantasy) are not typical cursive | |
| 331 // and fantasy fonts, but it should not matter for layout tests | |
| 332 // as long as they're available. | |
| 333 web_prefs_->cursive_font_family_map[webkit_glue::kCommonScript] = | |
| 334 ASCIIToUTF16("Comic Sans MS"); | |
| 335 web_prefs_->fantasy_font_family_map[webkit_glue::kCommonScript] = | |
| 336 ASCIIToUTF16("Impact"); | |
| 337 #endif | |
| 338 web_prefs_->standard_font_family_map[webkit_glue::kCommonScript] = | |
| 339 web_prefs_->serif_font_family_map[webkit_glue::kCommonScript]; | |
| 340 web_prefs_->fixed_font_family_map[webkit_glue::kCommonScript] = | |
| 341 ASCIIToUTF16("Courier"); | |
| 342 web_prefs_->sans_serif_font_family_map[webkit_glue::kCommonScript] = | |
| 343 ASCIIToUTF16("Helvetica"); | |
| 344 | |
| 345 web_prefs_->default_encoding = "ISO-8859-1"; | |
| 346 web_prefs_->default_font_size = 16; | |
| 347 web_prefs_->default_fixed_font_size = 13; | |
| 348 web_prefs_->minimum_font_size = 0; | |
| 349 web_prefs_->minimum_logical_font_size = 9; | |
| 350 web_prefs_->javascript_can_open_windows_automatically = true; | |
| 351 web_prefs_->dom_paste_enabled = true; | |
| 352 web_prefs_->site_specific_quirks_enabled = true; | |
| 353 web_prefs_->shrinks_standalone_images_to_fit = false; | |
| 354 web_prefs_->uses_universal_detector = false; | |
| 355 web_prefs_->java_enabled = false; | |
| 356 web_prefs_->allow_scripts_to_close_windows = false; | |
| 357 web_prefs_->javascript_can_access_clipboard = true; | |
| 358 web_prefs_->xss_auditor_enabled = false; | |
| 359 // It's off by default for Chrome, but we don't want to | |
| 360 // lose the coverage of dynamic font tests in webkit test. | |
| 361 web_prefs_->remote_fonts_enabled = true; | |
| 362 web_prefs_->local_storage_enabled = true; | |
| 363 web_prefs_->application_cache_enabled = true; | |
| 364 web_prefs_->databases_enabled = true; | |
| 365 web_prefs_->allow_file_access_from_file_urls = true; | |
| 366 // LayoutTests were written with Safari Mac in mind which does not allow | |
| 367 // tabbing to links by default. | |
| 368 web_prefs_->tabs_to_links = false; | |
| 369 web_prefs_->accelerated_2d_canvas_enabled = | |
| 370 accelerated_2d_canvas_enabled_; | |
| 371 web_prefs_->accelerated_compositing_enabled = | |
| 372 accelerated_compositing_enabled_; | |
| 373 // Allow those layout tests running as local files, i.e. under | |
| 374 // LayoutTests/http/tests/local, to access http server. | |
| 375 if (layout_test_mode_) | |
| 376 web_prefs_->allow_universal_access_from_file_urls = true; | |
| 377 web_prefs_->visual_word_movement_enabled = false; | |
| 378 } | |
| 379 } | |
| 380 | |
| 381 // static | |
| 382 WebPreferences* TestShell::GetWebPreferences() { | |
| 383 DCHECK(web_prefs_); | |
| 384 return web_prefs_; | |
| 385 } | |
| 386 | |
| 387 // static | |
| 388 bool TestShell::RemoveWindowFromList(gfx::NativeWindow window) { | |
| 389 WindowList::iterator entry = | |
| 390 std::find(TestShell::windowList()->begin(), | |
| 391 TestShell::windowList()->end(), | |
| 392 window); | |
| 393 if (entry != TestShell::windowList()->end()) { | |
| 394 TestShell::windowList()->erase(entry); | |
| 395 return true; | |
| 396 } | |
| 397 | |
| 398 return false; | |
| 399 } | |
| 400 | |
| 401 void TestShell::Show(WebNavigationPolicy policy) { | |
| 402 delegate_->show(policy); | |
| 403 } | |
| 404 | |
| 405 void TestShell::DumpBackForwardEntry(int index, base::string16* result) { | |
| 406 int current_index = navigation_controller_->GetLastCommittedEntryIndex(); | |
| 407 | |
| 408 std::string content_state = | |
| 409 navigation_controller_->GetEntryAtIndex(index)->GetContentState(); | |
| 410 if (content_state.empty()) { | |
| 411 content_state = webkit_glue::CreateHistoryStateForURL( | |
| 412 navigation_controller_->GetEntryAtIndex(index)->GetURL()); | |
| 413 } | |
| 414 | |
| 415 result->append( | |
| 416 webkit_glue::DumpHistoryState(content_state, 8, index == current_index)); | |
| 417 } | |
| 418 | |
| 419 void TestShell::DumpBackForwardList(base::string16* result) { | |
| 420 result->append(ASCIIToUTF16( | |
| 421 "\n============== Back Forward List ==============\n")); | |
| 422 | |
| 423 for (int i = 0; i < navigation_controller_->GetEntryCount(); ++i) | |
| 424 DumpBackForwardEntry(i, result); | |
| 425 | |
| 426 result->append(ASCIIToUTF16( | |
| 427 "===============================================\n")); | |
| 428 } | |
| 429 | |
| 430 void TestShell::CallJSGC() { | |
| 431 webView()->mainFrame()->collectGarbage(); | |
| 432 } | |
| 433 | |
| 434 WebView* TestShell::CreateWebView() { | |
| 435 // If we're running layout tests, only open a new window if the test has | |
| 436 // called testRunner.setCanOpenWindows() | |
| 437 if (layout_test_mode_) | |
| 438 return NULL; | |
| 439 | |
| 440 TestShell* new_win; | |
| 441 if (!CreateNewWindow(GURL(), &new_win)) | |
| 442 return NULL; | |
| 443 | |
| 444 return new_win->webView(); | |
| 445 } | |
| 446 | |
| 447 void TestShell::ShowDevTools() { | |
| 448 if (!devtools_shell_) { | |
| 449 base::FilePath dir_exe; | |
| 450 PathService::Get(base::DIR_EXE, &dir_exe); | |
| 451 base::FilePath devtools_path = | |
| 452 dir_exe.AppendASCII("resources/inspector/devtools.html"); | |
| 453 TestShell* devtools_shell; | |
| 454 TestShell::CreateNewWindow(GURL(devtools_path.value()), | |
| 455 &devtools_shell); | |
| 456 devtools_shell_ = devtools_shell->AsWeakPtr(); | |
| 457 devtools_shell_->CreateDevToolsClient(dev_tools_agent_.get()); | |
| 458 } | |
| 459 DCHECK(devtools_shell_); | |
| 460 devtools_shell_->Show(WebKit::WebNavigationPolicyNewWindow); | |
| 461 } | |
| 462 | |
| 463 void TestShell::CloseDevTools() { | |
| 464 if (devtools_shell_) | |
| 465 devtools_shell_->DestroyWindow(devtools_shell_->mainWnd()); | |
| 466 } | |
| 467 | |
| 468 void TestShell::CreateDevToolsClient(TestShellDevToolsAgent *agent) { | |
| 469 dev_tools_client_.reset(new TestShellDevToolsClient(agent, | |
| 470 webView())); | |
| 471 } | |
| 472 | |
| 473 bool TestShell::IsSVGTestURL(const GURL& url) { | |
| 474 return url.is_valid() && url.spec().find("W3C-SVG-1.1") != std::string::npos; | |
| 475 } | |
| 476 | |
| 477 void TestShell::SizeToSVG() { | |
| 478 SizeTo(kSVGTestWindowWidth, kSVGTestWindowHeight); | |
| 479 } | |
| 480 | |
| 481 void TestShell::SizeToDefault() { | |
| 482 SizeTo(kTestWindowWidth, kTestWindowHeight); | |
| 483 } | |
| 484 | |
| 485 void TestShell::ResetTestController() { | |
| 486 notification_presenter_->Reset(); | |
| 487 delegate_->Reset(); | |
| 488 if (geolocation_client_mock_.get()) | |
| 489 geolocation_client_mock_->resetMock(); | |
| 490 } | |
| 491 | |
| 492 void TestShell::LoadFile(const base::FilePath& file) { | |
| 493 LoadURLForFrame(net::FilePathToFileURL(file), base::string16()); | |
| 494 } | |
| 495 | |
| 496 void TestShell::LoadURL(const GURL& url) { | |
| 497 LoadURLForFrame(url, base::string16()); | |
| 498 } | |
| 499 | |
| 500 bool TestShell::Navigate(const TestNavigationEntry& entry, bool reload) { | |
| 501 // Get the right target frame for the entry. | |
| 502 WebFrame* frame = webView()->mainFrame(); | |
| 503 if (!entry.GetTargetFrame().empty()) | |
| 504 frame = webView()->findFrameByName(entry.GetTargetFrame()); | |
| 505 | |
| 506 // TODO(mpcomplete): should we clear the target frame, or should | |
| 507 // back/forward navigations maintain the target frame? | |
| 508 | |
| 509 // A navigation resulting from loading a javascript URL should not be | |
| 510 // treated as a browser initiated event. Instead, we want it to look as if | |
| 511 // the page initiated any load resulting from JS execution. | |
| 512 if (!entry.GetURL().SchemeIs("javascript")) { | |
| 513 delegate_->set_pending_extra_data( | |
| 514 new TestShellExtraData(entry.GetPageID())); | |
| 515 } | |
| 516 | |
| 517 // If we are reloading, then WebKit will use the state of the current page. | |
| 518 // Otherwise, we give it the state to navigate to. | |
| 519 if (reload) { | |
| 520 frame->reload(false); | |
| 521 } else if (!entry.GetContentState().empty()) { | |
| 522 DCHECK_NE(entry.GetPageID(), -1); | |
| 523 frame->loadHistoryItem( | |
| 524 webkit_glue::HistoryItemFromString(entry.GetContentState())); | |
| 525 } else { | |
| 526 DCHECK_EQ(entry.GetPageID(), -1); | |
| 527 frame->loadRequest(WebURLRequest(entry.GetURL())); | |
| 528 } | |
| 529 | |
| 530 // In case LoadRequest failed before DidCreateDataSource was called. | |
| 531 delegate_->set_pending_extra_data(NULL); | |
| 532 | |
| 533 // Restore focus to the main frame prior to loading new request. | |
| 534 // This makes sure that we don't have a focused iframe. Otherwise, that | |
| 535 // iframe would keep focus when the SetFocus called immediately after | |
| 536 // LoadRequest, thus making some tests fail (see http://b/issue?id=845337 | |
| 537 // for more details). | |
| 538 webView()->setFocusedFrame(frame); | |
| 539 SetFocus(webViewHost(), true); | |
| 540 | |
| 541 return true; | |
| 542 } | |
| 543 | |
| 544 void TestShell::GoBackOrForward(int offset) { | |
| 545 navigation_controller_->GoToOffset(offset); | |
| 546 } | |
| 547 | |
| 548 void TestShell::DumpDocumentText() { | |
| 549 base::FilePath file_path; | |
| 550 if (!PromptForSaveFile(L"Dump document text", &file_path)) | |
| 551 return; | |
| 552 | |
| 553 const std::string data = | |
| 554 UTF16ToUTF8(webkit_glue::DumpDocumentText(webView()->mainFrame())); | |
| 555 file_util::WriteFile(file_path, data.c_str(), data.length()); | |
| 556 } | |
| 557 | |
| 558 void TestShell::DumpRenderTree() { | |
| 559 base::FilePath file_path; | |
| 560 if (!PromptForSaveFile(L"Dump render tree", &file_path)) | |
| 561 return; | |
| 562 | |
| 563 const std::string data = | |
| 564 UTF16ToUTF8(webkit_glue::DumpRenderer(webView()->mainFrame())); | |
| 565 file_util::WriteFile(file_path, data.c_str(), data.length()); | |
| 566 } | |
| 567 | |
| 568 base::string16 TestShell::GetDocumentText() { | |
| 569 return webkit_glue::DumpDocumentText(webView()->mainFrame()); | |
| 570 } | |
| 571 | |
| 572 void TestShell::Reload() { | |
| 573 navigation_controller_->Reload(); | |
| 574 } | |
| 575 | |
| 576 void TestShell::SetFocus(WebWidgetHost* host, bool enable) { | |
| 577 if (!layout_test_mode_) { | |
| 578 InteractiveSetFocus(host, enable); | |
| 579 } else { | |
| 580 // Simulate the effects of InteractiveSetFocus(), which includes calling | |
| 581 // both setFocus() and setIsActive(). | |
| 582 if (enable) { | |
| 583 if (m_focusedWidgetHost != host) { | |
| 584 if (m_focusedWidgetHost) | |
| 585 m_focusedWidgetHost->webwidget()->setFocus(false); | |
| 586 webView()->setIsActive(enable); | |
| 587 host->webwidget()->setFocus(enable); | |
| 588 m_focusedWidgetHost = host; | |
| 589 } | |
| 590 } else { | |
| 591 if (m_focusedWidgetHost == host) { | |
| 592 host->webwidget()->setFocus(enable); | |
| 593 webView()->setIsActive(enable); | |
| 594 m_focusedWidgetHost = NULL; | |
| 595 } | |
| 596 } | |
| 597 } | |
| 598 } | |
| 599 | |
| 600 WebKit::WebDeviceOrientationClientMock* | |
| 601 TestShell::device_orientation_client_mock() { | |
| 602 if (!device_orientation_client_mock_.get()) { | |
| 603 device_orientation_client_mock_.reset( | |
| 604 WebKit::WebDeviceOrientationClientMock::create()); | |
| 605 } | |
| 606 return device_orientation_client_mock_.get(); | |
| 607 } | |
| 608 | |
| 609 WebKit::WebGeolocationClientMock* TestShell::geolocation_client_mock() { | |
| 610 if (!geolocation_client_mock_.get()) { | |
| 611 geolocation_client_mock_.reset( | |
| 612 WebKit::WebGeolocationClientMock::create()); | |
| 613 } | |
| 614 return geolocation_client_mock_.get(); | |
| 615 } | |
| OLD | NEW |