summaryrefslogtreecommitdiffstats
path: root/webkit/tools/test_shell/test_shell.h
blob: 3bca820d06b01482d7b2e3449df290c9e19e42bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_H_
#define WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_H_

#pragma once

#include <string>
#include <list>
#include <vector>

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/memory/scoped_temp_dir.h"
#if defined(OS_MACOSX)
#include "base/lazy_instance.h"
#endif
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNavigationPolicy.h"
#include "ui/gfx/native_widget_types.h"
#include "webkit/tools/test_shell/layout_test_controller.h"
#include "webkit/tools/test_shell/webview_host.h"
#include "webkit/tools/test_shell/webwidget_host.h"

typedef std::list<gfx::NativeWindow> WindowList;

struct WebPreferences;
class GURL;
class TestNavigationEntry;
class TestNavigationController;
class TestNotificationPresenter;
class TestShellDevToolsAgent;
class TestShellDevToolsClient;
class TestWebViewDelegate;

namespace base {
class StringPiece;
}

namespace WebKit {
class WebDeviceOrientationClientMock;
class WebGeolocationClientMock;
class WebSpeechInputControllerMock;
class WebSpeechInputListener;
}

class TestShell : public base::SupportsWeakPtr<TestShell>  {
public:
    struct TestParams {
      // Load the test defaults.
      TestParams() : dump_tree(true), dump_pixels(false) {
      }

      // 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).
      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 by the LayoutTestController to signal test completion.
    void TestFinished();

    // Called by LayoutTestController 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);

    LayoutTestController* layout_test_controller() {
      return layout_test_controller_.get();
    }
    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 the LayoutTestController and EventSendingController.  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();

    // Passes options from LayoutTestController through to the delegate (or
    // any other caller).
    bool AcceptsEditing() {
      return layout_test_controller_->AcceptsEditing();
    }

    void LoadFile(const FilePath& file);
    void LoadURL(const GURL& url);
    void LoadURLForFrame(const GURL& url, const std::wstring& frame_name);
    void GoBackOrForward(int offset);
    void Reload();
    bool Navigate(const TestNavigationEntry& entry, bool reload);

    bool PromptForSaveFile(const wchar_t* prompt_title, 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

    // Called by the WebView delegate WindowObjectCleared() method, this
    // binds the layout_test_controller_ and other C++ controller classes to
    // window JavaScript objects so they can be accessed by layout tests.
    virtual void BindJSObjectsToWindow(WebKit::WebFrame* frame);

    // 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);

    WebPreferences* GetWebPreferences() { return web_prefs_; }

    // 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::WebSpeechInputControllerMock* CreateSpeechInputControllerMock(
        WebKit::WebSpeechInputListener* listener);
    WebKit::WebSpeechInputControllerMock* speech_input_controller_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();

protected:
    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_;
#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<LayoutTestController> layout_test_controller_;
    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::WebSpeechInputControllerMock>
        speech_input_controller_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 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_