blob: c6394e98dfc8feda28b4817a5fd4c3ed289c5538 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_H_
#define WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_H_
#include <list>
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/string_piece.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNavigationPolicy.h"
#include "ui/gfx/native_widget_types.h"
#include "webkit/tools/test_shell/webview_host.h"
#include "webkit/tools/test_shell/webwidget_host.h"
typedef std::list<gfx::NativeWindow> WindowList;
#if defined(OS_WIN)
namespace ui {
class ScopedOleInitializer;
}
#endif
namespace webkit_glue {
struct WebPreferences;
}
class GURL;
class TestNavigationEntry;
class TestNavigationController;
class TestNotificationPresenter;
class TestShellDevToolsAgent;
class TestShellDevToolsClient;
class TestWebViewDelegate;
namespace WebKit {
class WebDeviceOrientationClientMock;
class WebGeolocationClientMock;
}
class TestShell : public base::SupportsWeakPtr<TestShell> {
public:
struct TestParams {
// Load the test defaults.
TestParams();
// The kind of output we want from this test.
bool dump_tree;
bool dump_pixels;
// Filename we dump pixels to (when pixel testing is enabled).
base::FilePath pixel_file_name;
// The md5 hash of the bitmap dump (when pixel testing is enabled).
std::string pixel_hash;
// URL of the test.
std::string test_url;
};
TestShell();
virtual ~TestShell();
// Initialization and clean up of logging.
static void InitLogging(bool suppress_error_dialogs,
bool running_layout_tests,
bool enable_gp_fault_error_box);
static void CleanupLogging();
// Initialization and clean up of a static member variable.
static void InitializeTestShell(bool layout_test_mode,
bool allow_external_pages);
static void ShutdownTestShell();
static bool layout_test_mode() { return layout_test_mode_; }
static bool allow_external_pages() { return allow_external_pages_; }
// Called from the destructor to let each platform do any necessary
// cleanup.
void PlatformCleanUp();
WebKit::WebView* webView() {
return m_webViewHost.get() ? m_webViewHost->webview() : NULL;
}
WebViewHost* webViewHost() { return m_webViewHost.get(); }
WebKit::WebWidget* popup() {
return m_popupHost ? m_popupHost->webwidget() : NULL;
}
WebWidgetHost* popupHost() { return m_popupHost; }
bool is_loading() const { return is_loading_; }
void set_is_loading(bool is_loading) { is_loading_ = is_loading; }
bool allow_images() const { return allow_images_; }
void set_allow_images(bool allow) { allow_images_ = allow; }
bool allow_plugins() const { return allow_plugins_; }
void set_allow_plugins(bool allow) { allow_plugins_ = allow; }
bool allow_scripts() const { return allow_scripts_; }
void set_allow_scripts(bool allow) { allow_scripts_ = allow; }
void UpdateNavigationControls();
// A new TestShell window will be opened with devtools url.
// DevTools window can be opened manually via menu or automatically when
// inspector's layout test url is passed from command line or console.
void ShowDevTools();
void CloseDevTools();
// Called to signal test completion.
void TestFinished();
// Called when a test hits the timeout, but does not cause a hang. We can
// avoid killing TestShell in this case and still dump the test results.
void TestTimedOut();
// Called to block the calling thread until TestFinished is called.
void WaitTestFinished();
void Show(WebKit::WebNavigationPolicy policy);
// We use this to avoid relying on Windows focus during layout test mode.
void SetFocus(WebWidgetHost* host, bool enable);
TestWebViewDelegate* delegate() { return delegate_.get(); }
TestWebViewDelegate* popup_delegate() { return popup_delegate_.get(); }
TestNavigationController* navigation_controller() {
return navigation_controller_.get();
}
TestNotificationPresenter* notification_presenter() {
return notification_presenter_.get();
}
// Resets TestWebViewDelegate. Should be called before loading a page,
// since some end-editing event notifications may arrive after the previous
// page has finished dumping its text and therefore end up in the next
// test's results if the messages are still enabled.
void ResetTestController();
bool AcceptsEditing() {
return true;
}
void LoadFile(const base::FilePath& file);
void LoadURL(const GURL& url);
void LoadURLForFrame(const GURL& url, const string16& frame_name);
void GoBackOrForward(int offset);
void Reload();
bool Navigate(const TestNavigationEntry& entry, bool reload);
bool PromptForSaveFile(const wchar_t* prompt_title, base::FilePath* result);
string16 GetDocumentText();
void DumpDocumentText();
void DumpRenderTree();
gfx::NativeWindow mainWnd() const { return m_mainWnd; }
gfx::NativeView webViewWnd() const { return m_webViewHost->view_handle(); }
gfx::NativeEditView editWnd() const { return m_editWnd; }
gfx::NativeView popupWnd() const { return m_popupHost->view_handle(); }
static WindowList* windowList() { return window_list_; }
// If shell is non-null, then *shell is assigned upon successful return
static bool CreateNewWindow(const GURL& starting_url,
TestShell** shell = NULL);
static void DestroyWindow(gfx::NativeWindow windowHandle);
// Remove the given window from window_list_, return true if it was in the
// list and was removed and false otherwise.
static bool RemoveWindowFromList(gfx::NativeWindow window);
// Implements CreateWebView for TestWebViewDelegate, which in turn
// is called as a WebViewDelegate.
WebKit::WebView* CreateWebView();
WebKit::WebWidget* CreatePopupWidget();
void ClosePopup();
#if defined(OS_WIN)
static ATOM RegisterWindowClass();
#endif
// Writes the back-forward list data for every open window into result.
// Should call DumpBackForwardListOfWindow on each TestShell window.
static void DumpAllBackForwardLists(string16* result);
// Writes the single back-forward entry into result.
void DumpBackForwardEntry(int index, string16* result);
// Writes the back-forward list data for this test shell into result.
void DumpBackForwardList(string16* result);
static void ResetWebPreferences();
static void SetAllowScriptsToCloseWindows();
static void SetAccelerated2dCanvasEnabled(bool enabled);
static void SetAcceleratedCompositingEnabled(bool enabled);
static webkit_glue::WebPreferences* GetWebPreferences();
// Some layout tests hardcode a file:///tmp/LayoutTests URL. We get around
// this by substituting "tmp" with the path to the LayoutTests parent dir.
static std::string RewriteLocalUrl(const std::string& url);
// Set the timeout for running a test.
static void SetFileTestTimeout(int timeout_ms) {
file_test_timeout_ms_ = timeout_ms;
}
// Get the timeout for running a test.
static int GetLayoutTestTimeout() { return file_test_timeout_ms_; }
// Get the timeout killing an unresponsive TestShell.
// Make it a bit longer than the regular timeout to avoid killing the
// TestShell process unless we really need to.
static int GetLayoutTestTimeoutForWatchDog() {
return (load_count_ * file_test_timeout_ms_) + 1000;
}
// Set the JavaScript flags to use. This is a vector as when multiple loads
// are specified each load can have different flags passed.
static void SetJavaScriptFlags(std::vector<std::string> js_flags) {
js_flags_ = js_flags;
}
// Set the number of times to load each URL.
static void SetMultipleLoad(int load_count) {
load_count_ = load_count;
}
// Get the number of times to load each URL.
static int GetLoadCount() { return load_count_; }
// Get the JavaScript flags for a specific load
static std::string GetJSFlagsForLoad(size_t load) {
if (load >= js_flags_.size()) return "";
return js_flags_[load];
}
#if defined(OS_WIN)
// Access to the finished event. Used by the static WatchDog
// thread.
HANDLE finished_event() { return finished_event_; }
#endif
// Have the shell print the StatsTable to stdout on teardown.
void DumpStatsTableOnExit() { dump_stats_table_on_exit_ = true; }
void CallJSGC();
void set_is_modal(bool value) { is_modal_ = value; }
bool is_modal() const { return is_modal_; }
const TestParams* test_params() { return test_params_; }
void set_test_params(const TestParams* test_params) {
test_params_ = test_params;
}
#if defined(OS_MACOSX)
// handle cleaning up a shell given the associated window
static void DestroyAssociatedShell(gfx::NativeWindow handle);
#endif
// Show the "attach to me" dialog, for debugging test shell startup.
static void ShowStartupDebuggingDialog();
// This is called indirectly by the modules that need access resources.
static base::StringPiece ResourceProvider(int key);
TestShellDevToolsAgent* dev_tools_agent() {
return dev_tools_agent_.get();
}
WebKit::WebDeviceOrientationClientMock* device_orientation_client_mock();
WebKit::WebGeolocationClientMock* geolocation_client_mock();
protected:
void CreateDevToolsClient(TestShellDevToolsAgent* agent);
bool Initialize(const GURL& starting_url);
bool IsSVGTestURL(const GURL& url);
void SizeToSVG();
void SizeToDefault();
void SizeTo(int width, int height);
void ResizeSubViews();
// Set the focus in interactive mode (pass through to relevant system call).
void InteractiveSetFocus(WebWidgetHost* host, bool enable);
enum UIControl {
BACK_BUTTON,
FORWARD_BUTTON,
STOP_BUTTON
};
void EnableUIControl(UIControl control, bool is_enabled);
#if defined(OS_WIN)
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);
#endif
static void PlatformShutdown();
gfx::NativeWindow m_mainWnd;
gfx::NativeEditView m_editWnd;
scoped_ptr<WebViewHost> m_webViewHost;
WebWidgetHost* m_popupHost;
#if defined(OS_WIN)
WNDPROC default_edit_wnd_proc_;
#endif
// Primitive focus controller for layout test mode.
WebWidgetHost* m_focusedWidgetHost;
private:
// A set of all our windows.
static WindowList* window_list_;
#if defined(OS_MACOSX)
typedef std::map<gfx::NativeWindow, TestShell *> WindowMap;
static base::LazyInstance<WindowMap> window_map_;
#endif
#if defined(OS_WIN)
static HINSTANCE instance_handle_;
static ui::ScopedOleInitializer* ole_initializer_;
#endif
// True if developer extras should be enabled.
static bool developer_extras_enabled_;
// True when the app is being run using the --layout-tests switch.
static bool layout_test_mode_;
// True when we wish to allow test shell to load external pages like
// www.google.com even when in --layout-test mode (used for QA to
// produce images of the rendered page)
static bool allow_external_pages_;
// Default timeout in ms for file page loads when in layout test mode.
static int file_test_timeout_ms_;
scoped_ptr<TestNavigationController> navigation_controller_;
scoped_ptr<TestNotificationPresenter> notification_presenter_;
scoped_ptr<TestWebViewDelegate> delegate_;
scoped_ptr<TestWebViewDelegate> popup_delegate_;
base::WeakPtr<TestShell> devtools_shell_;
scoped_ptr<TestShellDevToolsAgent> dev_tools_agent_;
scoped_ptr<TestShellDevToolsClient> dev_tools_client_;
scoped_ptr<WebKit::WebDeviceOrientationClientMock>
device_orientation_client_mock_;
scoped_ptr<WebKit::WebGeolocationClientMock> geolocation_client_mock_;
const TestParams* test_params_;
// True while a test is preparing to run
static bool test_is_preparing_;
// True while a test is running
static bool test_is_pending_;
// Number of times to load each URL.
static int load_count_;
// JavaScript flags. Each element in the vector contains a set of flags as
// a string (e.g. "--xxx --yyy"). Each flag set is used for separate loads
// of each URL.
static std::vector<std::string> js_flags_;
// True if we're testing the accelerated canvas 2d path.
static bool accelerated_2d_canvas_enabled_;
// True if we're testing the accelerated compositing.
static bool accelerated_compositing_enabled_;
// True if driven from a nested message loop.
bool is_modal_;
// True if the page is loading.
bool is_loading_;
bool allow_images_;
bool allow_plugins_;
bool allow_scripts_;
// The preferences for the test shell.
static webkit_glue::WebPreferences* web_prefs_;
#if defined(OS_WIN)
// Used by the watchdog to know when it's finished.
HANDLE finished_event_;
#endif
// Dump the stats table counters on exit.
bool dump_stats_table_on_exit_;
};
#endif // WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_H_