2 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3 * Copyright (C) 2008 Alp Toker <alp@nuanti.com>
4 * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "DumpRenderTree.h"
34 #include "AccessibilityController.h"
35 #include "EventSender.h"
36 #include "GCController.h"
37 #include "LayoutTestController.h"
38 #include "WorkQueue.h"
39 #include "WorkQueueItem.h"
42 #include <webkit/webkit.h>
43 #include <JavaScriptCore/JavaScript.h>
45 #include <wtf/Assertions.h>
48 #include <fontconfig/fontconfig.h>
59 // This API is not yet public.
60 extern G_CONST_RETURN gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem*);
61 extern gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem*);
62 extern GList* webkit_web_history_item_get_children(WebKitWebHistoryItem*);
63 extern GSList* webkit_web_frame_get_children(WebKitWebFrame* frame);
64 extern gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame);
65 extern gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame);
66 extern guint webkit_web_frame_get_pending_unload_event_count(WebKitWebFrame* frame);
67 extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory);
68 extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame);
69 extern void webkit_web_frame_clear_main_frame_name(WebKitWebFrame* frame);
70 extern void webkit_web_view_set_group_name(WebKitWebView* view, const gchar* groupName);
71 extern void webkit_reset_origin_access_white_lists();
75 static bool printSeparators;
76 static int dumpPixels;
77 static int dumpTree = 1;
79 AccessibilityController* axController = 0;
80 LayoutTestController* gLayoutTestController = 0;
81 static GCController* gcController = 0;
82 static WebKitWebView* webView;
83 static GtkWidget* window;
84 static GtkWidget* container;
85 static GtkWidget* webInspectorWindow;
86 WebKitWebFrame* mainFrame = 0;
87 WebKitWebFrame* topLoadingFrame = 0;
88 guint waitToDumpWatchdog = 0;
89 bool waitForPolicy = false;
91 // This is a list of opened webviews
92 GSList* webViewList = 0;
94 // current b/f item at the end of the previous test
95 static WebKitWebHistoryItem* prevTestBFItem = NULL;
97 const unsigned historyItemIndent = 8;
99 static gchar* autocorrectURL(const gchar* url)
101 if (strncmp("http://", url, 7) != 0 && strncmp("https://", url, 8) != 0) {
102 GString* string = g_string_new("file://");
103 g_string_append(string, url);
104 return g_string_free(string, FALSE);
107 return g_strdup(url);
110 static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
112 return strstr(pathOrURL, "loading/");
115 static bool shouldOpenWebInspector(const char* pathOrURL)
117 return strstr(pathOrURL, "inspector/");
120 void dumpFrameScrollPosition(WebKitWebFrame* frame)
125 void displayWebView()
127 gtk_widget_queue_draw(GTK_WIDGET(webView));
130 static void appendString(gchar*& target, gchar* string)
132 gchar* oldString = target;
133 target = g_strconcat(target, string, NULL);
138 static void initializeFonts()
140 static int numFonts = -1;
142 // Some tests may add or remove fonts via the @font-face rule.
143 // If that happens, font config should be re-created to suppress any unwanted change.
144 FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication);
145 if (appFontSet && numFonts >= 0 && appFontSet->nfont == numFonts)
148 const char* fontDirEnv = g_getenv("WEBKIT_TESTFONTS");
150 g_error("WEBKIT_TESTFONTS environment variable is not set, but it should point to the directory "
151 "containing the fonts you can clone from git://gitorious.org/qtwebkit/testfonts.git\n");
153 GFile* fontDir = g_file_new_for_path(fontDirEnv);
154 if (!fontDir || !g_file_query_exists(fontDir, NULL))
155 g_error("WEBKIT_TESTFONTS environment variable is not set correctly - it should point to the directory "
156 "containing the fonts you can clone from git://gitorious.org/qtwebkit/testfonts.git\n");
158 FcConfig *config = FcConfigCreate();
159 if (!FcConfigParseAndLoad (config, (FcChar8*) FONTS_CONF_FILE, true))
160 g_error("Couldn't load font configuration file");
161 if (!FcConfigAppFontAddDir (config, (FcChar8*) g_file_get_path(fontDir)))
162 g_error("Couldn't add font dir!");
163 FcConfigSetCurrent(config);
165 g_object_unref(fontDir);
167 appFontSet = FcConfigGetFonts(config, FcSetApplication);
168 numFonts = appFontSet->nfont;
172 static gchar* dumpFramesAsText(WebKitWebFrame* frame)
176 // Add header for all but the main frame.
177 bool isMainFrame = (webkit_web_view_get_main_frame(webView) == frame);
179 gchar* innerText = webkit_web_frame_get_inner_text(frame);
181 result = g_strdup_printf("%s\n", innerText);
183 const gchar* frameName = webkit_web_frame_get_name(frame);
184 result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText);
188 if (gLayoutTestController->dumpChildFramesAsText()) {
189 GSList* children = webkit_web_frame_get_children(frame);
190 for (GSList* child = children; child; child = g_slist_next(child))
191 appendString(result, dumpFramesAsText(static_cast<WebKitWebFrame* >(child->data)));
192 g_slist_free(children);
198 static gint compareHistoryItems(gpointer* item1, gpointer* item2)
200 return g_ascii_strcasecmp(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item1)),
201 webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item2)));
204 static void dumpHistoryItem(WebKitWebHistoryItem* item, int indent, bool current)
206 ASSERT(item != NULL);
213 for (int i = start; i < indent; i++)
216 // normalize file URLs.
217 const gchar* uri = webkit_web_history_item_get_uri(item);
218 gchar* uriScheme = g_uri_parse_scheme(uri);
219 if (g_strcmp0(uriScheme, "file") == 0) {
220 gchar* pos = g_strstr_len(uri, -1, "/LayoutTests/");
224 GString* result = g_string_sized_new(strlen(uri));
225 result = g_string_append(result, "(file test):");
226 result = g_string_append(result, pos + strlen("/LayoutTests/"));
227 printf("%s", result->str);
228 g_string_free(result, TRUE);
234 const gchar* target = webkit_web_history_item_get_target(item);
235 if (target && strlen(target) > 0)
236 printf(" (in frame \"%s\")", target);
237 if (webkit_web_history_item_is_target_item(item))
238 printf(" **nav target**");
240 GList* kids = webkit_web_history_item_get_children(item);
242 // must sort to eliminate arbitrary result ordering which defeats reproducible testing
243 kids = g_list_sort(kids, (GCompareFunc) compareHistoryItems);
244 for (unsigned i = 0; i < g_list_length(kids); i++)
245 dumpHistoryItem(WEBKIT_WEB_HISTORY_ITEM(g_list_nth_data(kids, i)), indent+4, FALSE);
247 g_object_unref(item);
250 static void dumpBackForwardListForWebView(WebKitWebView* view)
252 printf("\n============== Back Forward List ==============\n");
253 WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(view);
255 // Print out all items in the list after prevTestBFItem, which was from the previous test
256 // Gather items from the end of the list, the print them out from oldest to newest
257 GList* itemsToPrint = NULL;
258 gint forwardListCount = webkit_web_back_forward_list_get_forward_length(bfList);
259 for (int i = forwardListCount; i > 0; i--) {
260 WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i);
261 // something is wrong if the item from the last test is in the forward part of the b/f list
262 ASSERT(item != prevTestBFItem);
264 itemsToPrint = g_list_append(itemsToPrint, item);
267 WebKitWebHistoryItem* currentItem = webkit_web_back_forward_list_get_current_item(bfList);
269 g_object_ref(currentItem);
270 itemsToPrint = g_list_append(itemsToPrint, currentItem);
272 gint currentItemIndex = g_list_length(itemsToPrint) - 1;
273 gint backListCount = webkit_web_back_forward_list_get_back_length(bfList);
274 for (int i = -1; i >= -(backListCount); i--) {
275 WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i);
276 if (item == prevTestBFItem)
279 itemsToPrint = g_list_append(itemsToPrint, item);
282 for (int i = g_list_length(itemsToPrint) - 1; i >= 0; i--) {
283 WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(g_list_nth_data(itemsToPrint, i));
284 dumpHistoryItem(item, historyItemIndent, i == currentItemIndex);
285 g_object_unref(item);
287 g_list_free(itemsToPrint);
288 printf("===============================================\n");
291 static void dumpBackForwardListForAllWebViews()
293 // Dump the back forward list of the main WebView first
294 dumpBackForwardListForWebView(webView);
296 // The view list is prepended. Reverse the list so we get the order right.
297 GSList* viewList = g_slist_reverse(webViewList);
298 for (unsigned i = 0; i < g_slist_length(viewList); ++i)
299 dumpBackForwardListForWebView(WEBKIT_WEB_VIEW(g_slist_nth_data(viewList, i)));
302 static void invalidateAnyPreviousWaitToDumpWatchdog()
304 if (waitToDumpWatchdog) {
305 g_source_remove(waitToDumpWatchdog);
306 waitToDumpWatchdog = 0;
309 waitForPolicy = false;
312 static void resetDefaultsToConsistentValues()
314 WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
315 g_object_set(G_OBJECT(settings),
316 "enable-private-browsing", FALSE,
317 "enable-developer-extras", FALSE,
318 "enable-spell-checking", TRUE,
319 "enable-html5-database", TRUE,
320 "enable-html5-local-storage", TRUE,
321 "enable-xss-auditor", FALSE,
322 "javascript-can-open-windows-automatically", TRUE,
323 "enable-offline-web-application-cache", TRUE,
324 "enable-universal-access-from-file-uris", TRUE,
325 "enable-scripts", TRUE,
326 "enable-dom-paste", TRUE,
327 "default-font-family", "Times",
328 "monospace-font-family", "Courier",
329 "serif-font-family", "Times",
330 "sans-serif-font-family", "Helvetica",
331 "default-font-size", 16,
332 "default-monospace-font-size", 13,
333 "minimum-font-size", 1,
334 "enable-caret-browsing", FALSE,
335 "enable-page-cache", FALSE,
336 "auto-resize-window", TRUE,
337 "enable-java-applet", FALSE,
340 webkit_web_frame_clear_main_frame_name(mainFrame);
342 WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView);
343 g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", FALSE, NULL);
345 webkit_web_view_set_zoom_level(webView, 1.0);
347 webkit_reset_origin_access_white_lists();
349 setlocale(LC_ALL, "");
354 invalidateAnyPreviousWaitToDumpWatchdog();
356 bool dumpAsText = gLayoutTestController->dumpAsText();
359 gchar* responseMimeType = webkit_web_frame_get_response_mime_type(mainFrame);
361 dumpAsText = g_str_equal(responseMimeType, "text/plain");
362 g_free(responseMimeType);
364 // Test can request controller to be dumped as text even
365 // while test's response mime type is not text/plain.
366 // Overriding this behavior with dumpAsText being false is a bad idea.
368 gLayoutTestController->setDumpAsText(dumpAsText);
370 if (gLayoutTestController->dumpAsText())
371 result = dumpFramesAsText(mainFrame);
373 result = webkit_web_frame_dump_render_tree(mainFrame);
376 const char* errorMessage;
377 if (gLayoutTestController->dumpAsText())
378 errorMessage = "[documentElement innerText]";
379 else if (gLayoutTestController->dumpDOMAsWebArchive())
380 errorMessage = "[[mainFrame DOMDocument] webArchive]";
381 else if (gLayoutTestController->dumpSourceAsWebArchive())
382 errorMessage = "[[mainFrame dataSource] webArchive]";
384 errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
385 printf("ERROR: nil result from %s", errorMessage);
387 printf("%s", result);
389 if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive())
390 dumpFrameScrollPosition(mainFrame);
392 if (gLayoutTestController->dumpBackForwardList())
393 dumpBackForwardListForAllWebViews();
396 if (printSeparators) {
397 puts("#EOF"); // terminate the content block
398 fputs("#EOF\n", stderr);
405 if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive()) {
406 // FIXME: Add support for dumping pixels
410 // FIXME: call displayWebView here when we support --paint
416 static void setDefaultsToConsistentStateValuesForTesting()
418 gdk_screen_set_resolution(gdk_screen_get_default(), 72.0);
420 resetDefaultsToConsistentValues();
422 /* Disable the default auth dialog for testing */
423 SoupSession* session = webkit_get_default_session();
424 soup_session_remove_feature_by_type(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG);
427 webkit_web_settings_add_extra_plugin_directory(webView, TEST_PLUGIN_DIR);
430 gchar* databaseDirectory = g_build_filename(g_get_user_data_dir(), "gtkwebkitdrt", "databases", NULL);
431 webkit_set_web_database_directory_path(databaseDirectory);
432 g_free(databaseDirectory);
435 static void sendPixelResultsEOF()
443 static void runTest(const string& testPathOrURL)
445 ASSERT(!testPathOrURL.empty());
447 // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows.
448 string pathOrURL(testPathOrURL);
449 string expectedPixelHash;
451 size_t separatorPos = pathOrURL.find("'");
452 if (separatorPos != string::npos) {
453 pathOrURL = string(testPathOrURL, 0, separatorPos);
454 expectedPixelHash = string(testPathOrURL, separatorPos + 1);
457 gchar* url = autocorrectURL(pathOrURL.c_str());
458 const string testURL(url);
460 resetDefaultsToConsistentValues();
462 gLayoutTestController = new LayoutTestController(testURL, expectedPixelHash);
466 gLayoutTestController->setIconDatabaseEnabled(false);
468 if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
469 gLayoutTestController->setDumpFrameLoadCallbacks(true);
471 if (shouldOpenWebInspector(pathOrURL.c_str()))
472 gLayoutTestController->showWebInspector();
474 WorkQueue::shared()->clear();
475 WorkQueue::shared()->setFrozen(false);
477 bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg/W3C-SVG-1.1") != string::npos);
480 size.width = isSVGW3CTest ? 480 : LayoutTestController::maxViewWidth;
481 size.height = isSVGW3CTest ? 360 : LayoutTestController::maxViewHeight;
482 gtk_window_resize(GTK_WINDOW(window), size.width, size.height);
483 gtk_widget_size_allocate(container, &size);
486 g_object_unref(prevTestBFItem);
487 WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(webView);
488 prevTestBFItem = webkit_web_back_forward_list_get_current_item(bfList);
490 g_object_ref(prevTestBFItem);
496 // Focus the web view before loading the test to avoid focusing problems
497 gtk_widget_grab_focus(GTK_WIDGET(webView));
498 webkit_web_view_open(webView, url);
505 if (shouldOpenWebInspector(pathOrURL.c_str()))
506 gLayoutTestController->closeWebInspector();
508 // Also check if we still have opened webViews and free them.
509 if (gLayoutTestController->closeRemainingWindowsWhenComplete() || webViewList) {
510 while (webViewList) {
511 g_object_unref(WEBKIT_WEB_VIEW(webViewList->data));
512 webViewList = g_slist_next(webViewList);
514 g_slist_free(webViewList);
518 // A blank load seems to be necessary to reset state after certain tests.
519 webkit_web_view_open(webView, "about:blank");
521 gLayoutTestController->deref();
522 gLayoutTestController = 0;
524 // terminate the (possibly empty) pixels block after all the state reset
525 sendPixelResultsEOF();
528 void webViewLoadStarted(WebKitWebView* view, WebKitWebFrame* frame, void*)
530 // Make sure we only set this once per test. If it gets cleared, and then set again, we might
531 // end up doing two dumps for one test.
532 if (!topLoadingFrame && !done)
533 topLoadingFrame = frame;
536 static gboolean processWork(void* data)
538 // if we finish all the commands, we're ready to dump state
539 if (WorkQueue::shared()->processWork() && !gLayoutTestController->waitToDump())
545 static char* getFrameNameSuitableForTestResult(WebKitWebView* view, WebKitWebFrame* frame)
547 char* frameName = g_strdup(webkit_web_frame_get_name(frame));
549 if (frame == webkit_web_view_get_main_frame(view)) {
550 // This is a bit strange. Shouldn't web_frame_get_name return NULL?
551 if (frameName && (frameName[0] != '\0')) {
552 char* tmp = g_strdup_printf("main frame \"%s\"", frameName);
557 frameName = g_strdup("main frame");
559 } else if (!frameName || (frameName[0] == '\0')) {
561 frameName = g_strdup("frame (anonymous)");
563 char* tmp = g_strdup_printf("frame \"%s\"", frameName);
571 static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
573 if (frame != topLoadingFrame)
577 WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
578 if (gLayoutTestController->waitToDump())
581 if (WorkQueue::shared()->count())
582 g_timeout_add(0, processWork, 0);
587 static void webViewDocumentLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
589 if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
590 char* frameName = getFrameNameSuitableForTestResult(view, frame);
591 printf("%s - didFinishDocumentLoadForFrame", frameName);
594 guint pendingFrameUnloadEvents = webkit_web_frame_get_pending_unload_event_count(frame);
595 if (pendingFrameUnloadEvents) {
596 char* frameName = getFrameNameSuitableForTestResult(view, frame);
597 printf("%s - has %u onunload handler(s)\n", frameName, pendingFrameUnloadEvents);
603 static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data)
605 JSValueRef exception = 0;
606 ASSERT(gLayoutTestController);
608 gLayoutTestController->makeWindowObject(context, windowObject, &exception);
611 gcController->makeWindowObject(context, windowObject, &exception);
614 axController->makeWindowObject(context, windowObject, &exception);
617 JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender");
618 JSValueRef eventSender = makeEventSender(context);
619 JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
620 JSStringRelease(eventSenderStr);
623 static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data)
625 fprintf(stdout, "CONSOLE MESSAGE: line %d: %s\n", line, message);
630 static gboolean webViewScriptAlert(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gpointer data)
632 fprintf(stdout, "ALERT: %s\n", message);
636 static gboolean webViewScriptPrompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value, gpointer data)
638 fprintf(stdout, "PROMPT: %s, default text: %s\n", message, defaultValue);
639 *value = g_strdup(defaultValue);
643 static gboolean webViewScriptConfirm(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm, gpointer data)
645 fprintf(stdout, "CONFIRM: %s\n", message);
650 static void webViewTitleChanged(WebKitWebView* view, WebKitWebFrame* frame, const gchar* title, gpointer data)
652 if (gLayoutTestController->dumpTitleChanges() && !done)
653 printf("TITLE CHANGED: %s\n", title ? title : "");
656 static bool webViewNavigationPolicyDecisionRequested(WebKitWebView* view, WebKitWebFrame* frame,
657 WebKitNetworkRequest* request,
658 WebKitWebNavigationAction* navAction,
659 WebKitWebPolicyDecision* policyDecision)
661 // Use the default handler if we're not waiting for policy,
662 // i.e., LayoutTestController::waitForPolicyDelegate
666 gchar* typeDescription;
667 WebKitWebNavigationReason reason;
668 g_object_get(G_OBJECT(navAction), "reason", &reason, NULL);
671 case WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED:
672 typeDescription = g_strdup("link clicked");
674 case WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED:
675 typeDescription = g_strdup("form submitted");
677 case WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD:
678 typeDescription = g_strdup("back/forward");
680 case WEBKIT_WEB_NAVIGATION_REASON_RELOAD:
681 typeDescription = g_strdup("reload");
683 case WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED:
684 typeDescription = g_strdup("form resubmitted");
686 case WEBKIT_WEB_NAVIGATION_REASON_OTHER:
687 typeDescription = g_strdup("other");
690 typeDescription = g_strdup("illegal value");
693 printf("Policy delegate: attempt to load %s with navigation type '%s'\n", webkit_network_request_get_uri(request), typeDescription);
694 g_free(typeDescription);
696 webkit_web_policy_decision_ignore(policyDecision);
697 gLayoutTestController->notifyDone();
702 static void webViewStatusBarTextChanged(WebKitWebView* view, const gchar* message, gpointer data)
704 // Are we doing anything wrong? One test that does not call
705 // dumpStatusCallbacks gets true here
706 if (gLayoutTestController->dumpStatusCallbacks()) {
707 if (message && strcmp(message, ""))
708 printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message);
712 static gboolean webViewClose(WebKitWebView* view)
716 webViewList = g_slist_remove(webViewList, view);
717 g_object_unref(view);
722 static void databaseQuotaExceeded(WebKitWebView* view, WebKitWebFrame* frame, WebKitWebDatabase *database)
728 WebKitSecurityOrigin* origin = webkit_web_database_get_security_origin(database);
729 if (gLayoutTestController->dumpDatabaseCallbacks()) {
730 printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n",
731 webkit_security_origin_get_protocol(origin),
732 webkit_security_origin_get_host(origin),
733 webkit_security_origin_get_port(origin),
734 webkit_web_database_get_name(database));
736 webkit_security_origin_set_web_database_quota(origin, 5 * 1024 * 1024);
740 static WebKitWebView* webViewCreate(WebKitWebView*, WebKitWebFrame*);
742 static gboolean webInspectorShowWindow(WebKitWebInspector*, gpointer data)
744 gtk_window_set_default_size(GTK_WINDOW(webInspectorWindow), 800, 600);
745 gtk_widget_show_all(webInspectorWindow);
749 static gboolean webInspectorCloseWindow(WebKitWebInspector*, gpointer data)
751 gtk_widget_destroy(webInspectorWindow);
752 webInspectorWindow = 0;
756 static WebKitWebView* webInspectorInspectWebView(WebKitWebInspector*, gpointer data)
758 webInspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
760 GtkWidget* webView = webkit_web_view_new();
761 gtk_container_add(GTK_CONTAINER(webInspectorWindow),
764 return WEBKIT_WEB_VIEW(webView);
767 static WebKitWebView* createWebView()
769 WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
771 // From bug 11756: Use a frame group name for all WebViews created by
772 // DumpRenderTree to allow testing of cross-page frame lookup.
773 webkit_web_view_set_group_name(view, "org.webkit.gtk.DumpRenderTree");
775 g_object_connect(G_OBJECT(view),
776 "signal::load-started", webViewLoadStarted, 0,
777 "signal::load-finished", webViewLoadFinished, 0,
778 "signal::window-object-cleared", webViewWindowObjectCleared, 0,
779 "signal::console-message", webViewConsoleMessage, 0,
780 "signal::script-alert", webViewScriptAlert, 0,
781 "signal::script-prompt", webViewScriptPrompt, 0,
782 "signal::script-confirm", webViewScriptConfirm, 0,
783 "signal::title-changed", webViewTitleChanged, 0,
784 "signal::navigation-policy-decision-requested", webViewNavigationPolicyDecisionRequested, 0,
785 "signal::status-bar-text-changed", webViewStatusBarTextChanged, 0,
786 "signal::create-web-view", webViewCreate, 0,
787 "signal::close-web-view", webViewClose, 0,
788 "signal::database-quota-exceeded", databaseQuotaExceeded, 0,
789 "signal::document-load-finished", webViewDocumentLoadFinished, 0,
792 WebKitWebInspector* inspector = webkit_web_view_get_inspector(view);
793 g_object_connect(G_OBJECT(inspector),
794 "signal::inspect-web-view", webInspectorInspectWebView, 0,
795 "signal::show-window", webInspectorShowWindow, 0,
796 "signal::close-window", webInspectorCloseWindow, 0,
800 WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
801 webkit_web_view_set_settings(view, settings);
807 static WebKitWebView* webViewCreate(WebKitWebView* view, WebKitWebFrame* frame)
809 if (!gLayoutTestController->canOpenWindows())
812 // Make sure that waitUntilDone has been called.
813 ASSERT(gLayoutTestController->waitToDump());
815 WebKitWebView* newWebView = createWebView();
816 g_object_ref_sink(G_OBJECT(newWebView));
817 webViewList = g_slist_prepend(webViewList, newWebView);
821 int main(int argc, char* argv[])
824 gtk_init(&argc, &argv);
831 struct option options[] = {
832 {"notree", no_argument, &dumpTree, false},
833 {"pixel-tests", no_argument, &dumpPixels, true},
834 {"tree", no_argument, &dumpTree, true},
839 while ((option = getopt_long(argc, (char* const*)argv, "", options, NULL)) != -1)
841 case '?': // unknown or ambiguous option
842 case ':': // missing argument
847 window = gtk_window_new(GTK_WINDOW_POPUP);
848 container = GTK_WIDGET(gtk_scrolled_window_new(NULL, NULL));
849 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
850 gtk_container_add(GTK_CONTAINER(window), container);
851 gtk_widget_show_all(window);
853 webView = createWebView();
854 gtk_container_add(GTK_CONTAINER(container), GTK_WIDGET(webView));
855 gtk_widget_realize(GTK_WIDGET(webView));
856 gtk_widget_show_all(container);
857 gtk_widget_grab_focus(GTK_WIDGET(webView));
858 mainFrame = webkit_web_view_get_main_frame(webView);
860 setDefaultsToConsistentStateValuesForTesting();
862 gcController = new GCController();
863 axController = new AccessibilityController();
865 if (argc == optind+1 && strcmp(argv[optind], "-") == 0) {
866 char filenameBuffer[2048];
867 printSeparators = true;
868 while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
869 char* newLineCharacter = strchr(filenameBuffer, '\n');
870 if (newLineCharacter)
871 *newLineCharacter = '\0';
873 if (strlen(filenameBuffer) == 0)
876 runTest(filenameBuffer);
879 printSeparators = (optind < argc-1 || (dumpPixels && dumpTree));
880 for (int i = optind; i != argc; ++i)
890 gtk_widget_destroy(window);