diff options
Diffstat (limited to 'Tools/DumpRenderTree/gtk/DumpRenderTree.cpp')
-rw-r--r-- | Tools/DumpRenderTree/gtk/DumpRenderTree.cpp | 1557 |
1 files changed, 0 insertions, 1557 deletions
diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp deleted file mode 100644 index 73d710a04..000000000 --- a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ /dev/null @@ -1,1557 +0,0 @@ -/* - * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * Copyright (C) 2008 Alp Toker <alp@nuanti.com> - * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com> - * Copyright (C) 2010, 2011 Igalia S.L. - * - * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#include "config.h" -#include "DumpRenderTree.h" - -#include "AccessibilityController.h" -#include "EditingCallbacks.h" -#include "EventSender.h" -#include "GCController.h" -#include "PixelDumpSupport.h" -#include "SelfScrollingWebKitWebView.h" -#include "TestRunner.h" -#include "TextInputController.h" -#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" -#include "WebCoreTestSupport.h" -#include "WorkQueue.h" -#include "WorkQueueItem.h" -#include <JavaScriptCore/JavaScript.h> -#include <WebCore/platform/network/soup/GUniquePtrSoup.h> -#include <cassert> -#include <cstdlib> -#include <cstring> -#include <getopt.h> -#include <gtk/gtk.h> -#include <locale.h> -#include <webkit/webkit.h> -#include <wtf/Assertions.h> -#include <wtf/gobject/GlibUtilities.h> -#include <wtf/text/WTFString.h> - -#if PLATFORM(X11) -#include <fontconfig/fontconfig.h> -#endif - - -using namespace std; - -extern "C" { -// This API is not yet public. -extern gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem*); -extern gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem*); -extern GList* webkit_web_history_item_get_children(WebKitWebHistoryItem*); -extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory); -extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame); -} - -volatile bool done; -static bool printSeparators; -static int dumpPixelsForAllTests = false; -static bool dumpPixelsForCurrentTest; -static int dumpTree = 1; -static int useTimeoutWatchdog = 1; - -#if HAVE(ACCESSIBILITY) -AccessibilityController* axController = 0; -#endif -RefPtr<TestRunner> gTestRunner; -static GCController* gcController = 0; -static WebKitWebView* webView; -static GtkWidget* window; -static GtkWidget* container; -static GtkWidget* webInspectorWindow; -WebKitWebFrame* mainFrame = 0; -WebKitWebFrame* topLoadingFrame = 0; -guint waitToDumpWatchdog = 0; -bool waitForPolicy = false; - -// This is a list of opened webviews -GSList* webViewList = 0; - -// current b/f item at the end of the previous test -static WebKitWebHistoryItem* prevTestBFItem = NULL; - -const unsigned historyItemIndent = 8; - -static void runTest(const string& inputLine); - -static void didRunInsecureContent(WebKitWebFrame*, WebKitSecurityOrigin*, const char* url); - -static bool shouldLogFrameLoadDelegates(const string& pathOrURL) -{ - return pathOrURL.find("loading/") != string::npos; -} - -static bool shouldOpenWebInspector(const string& pathOrURL) -{ - return pathOrURL.find("inspector/") != string::npos; -} - -static bool shouldDumpAsText(const string& pathOrURL) -{ - return pathOrURL.find("dumpAsText/") != string::npos; -} - -static bool shouldEnableDeveloperExtras(const string& pathOrURL) -{ - return true; -} - -void dumpFrameScrollPosition(WebKitWebFrame* frame) -{ - WebKitDOMDocument* document = webkit_web_frame_get_dom_document(frame); - if (!document) - return; - - WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document); - if (!domWindow) - return; - - glong x = webkit_dom_dom_window_get_page_x_offset(domWindow); - glong y = webkit_dom_dom_window_get_page_y_offset(domWindow); - - if (abs(x) > 0 || abs(y) > 0) { - if (webkit_web_frame_get_parent(frame)) - printf("frame '%s' ", webkit_web_frame_get_name(frame)); - printf("scrolled to %ld,%ld\n", x, y); - } - - if (gTestRunner->dumpChildFrameScrollPositions()) { - GSList* children = DumpRenderTreeSupportGtk::getFrameChildren(frame); - for (GSList* child = children; child; child = g_slist_next(child)) - dumpFrameScrollPosition(static_cast<WebKitWebFrame*>(child->data)); - g_slist_free(children); - } -} - -void displayWebView() -{ - DumpRenderTreeSupportGtk::forceWebViewPaint(webView); - DumpRenderTreeSupportGtk::setTracksRepaints(mainFrame, true); - DumpRenderTreeSupportGtk::resetTrackedRepaints(mainFrame); -} - -static void appendString(gchar*& target, const gchar* string) -{ - gchar* oldString = target; - target = g_strconcat(target, string, NULL); - g_free(oldString); -} - -static void initializeGtkFontSettings(const char* testURL) -{ - GtkSettings* settings = gtk_settings_get_default(); - if (!settings) - return; - g_object_set(settings, - "gtk-xft-dpi", 98304, // This is 96 * 1024 or 96 DPI according to the GTK+ docs. - "gtk-xft-antialias", 1, - "gtk-xft-hinting", 0, - "gtk-font-name", "Liberation Sans 12", - "gtk-icon-theme-name", "gnome", - NULL); - gdk_screen_set_resolution(gdk_screen_get_default(), 96.0); - - // One test needs subpixel anti-aliasing turned on, but generally we - // want all text in other tests to use to grayscale anti-aliasing. - if (testURL && strstr(testURL, "xsettings_antialias_settings.html")) - g_object_set(settings, "gtk-xft-rgba", "rgb", NULL); - else - g_object_set(settings, "gtk-xft-rgba", "none", NULL); -} - -CString getTopLevelPath() -{ - if (const gchar* topLevel = g_getenv("WEBKIT_TOP_LEVEL")) - return topLevel; - - g_setenv("WEBKIT_TOP_LEVEL", TOP_LEVEL_DIR, FALSE); - return TOP_LEVEL_DIR; -} - -CString getOutputDir() -{ - const char* webkitOutputDir = g_getenv("WEBKIT_OUTPUTDIR"); - if (webkitOutputDir) - return webkitOutputDir; - - CString topLevelPath = getTopLevelPath(); - GUniquePtr<char> outputDir(g_build_filename(topLevelPath.data(), "WebKitBuild", NULL)); - return outputDir.get(); -} - -static CString getFontsPath() -{ - CString webkitOutputDir = getOutputDir(); - GUniquePtr<char> fontsPath(g_build_filename(webkitOutputDir.data(), "Dependencies", "Root", "webkitgtk-test-fonts", NULL)); - if (g_file_test(fontsPath.get(), static_cast<GFileTest>(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - return fontsPath.get(); - - // Try alternative fonts path. - fontsPath.reset(g_build_filename(webkitOutputDir.data(), "webkitgtk-test-fonts", NULL)); - if (g_file_test(fontsPath.get(), static_cast<GFileTest>(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - return fontsPath.get(); - - return CString(); -} - -static void initializeFonts(const char* testURL = 0) -{ -#if PLATFORM(X11) - initializeGtkFontSettings(testURL); - - FcInit(); - - // If a test resulted a font being added or removed via the @font-face rule, then - // we want to reset the FontConfig configuration to prevent it from affecting other tests. - static int numFonts = 0; - FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); - if (appFontSet && numFonts && appFontSet->nfont == numFonts) - return; - - // Load our configuration file, which sets up proper aliases for family - // names like sans, serif and monospace. - FcConfig* config = FcConfigCreate(); - GUniquePtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", nullptr)); - if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true)) - g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get()); - - CString fontsPath = getFontsPath(); - if (fontsPath.isNull()) - g_error("Could not locate test fonts at $WEBKIT_TOP_LEVEL/WebKitBuild/Dependencies/Root/webkitgtk-test-fonts. " - "WEBKIT_TOP_LEVEL is your WebKit checkout by default, and can be overridden by setting it as an environment variable."); - - GUniquePtr<GDir> fontsDirectory(g_dir_open(fontsPath.data(), 0, nullptr)); - while (const char* directoryEntry = g_dir_read_name(fontsDirectory.get())) { - if (!g_str_has_suffix(directoryEntry, ".ttf") && !g_str_has_suffix(directoryEntry, ".otf")) - continue; - GUniquePtr<gchar> fontPath(g_build_filename(fontsPath.data(), directoryEntry, nullptr)); - if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fontPath.get()))) - g_error("Could not load font at %s!", fontPath.get()); - - } - - // Ahem is used by many layout tests. - GUniquePtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", nullptr)); - if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get()))) - g_error("Could not load font at %s!", ahemFontFilename.get()); - - for (int i = 1; i <= 9; i++) { - GUniquePtr<gchar> fontFilename(g_strdup_printf("WebKitWeightWatcher%i00.ttf", i)); - GUniquePtr<gchar> fontPath(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilename.get(), nullptr)); - if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontPath.get()))) - g_error("Could not load font at %s!", fontPath.get()); - } - - // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452 - GUniquePtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", nullptr)); - if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get()))) - g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get()); - - if (!FcConfigSetCurrent(config)) - g_error("Could not set the current font configuration!"); - - numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont; -#endif -} - -static gchar* dumpFramesAsText(WebKitWebFrame* frame) -{ - gchar* result = 0; - - // Add header for all but the main frame. - bool isMainFrame = (webkit_web_view_get_main_frame(webView) == frame); - - CString innerText = DumpRenderTreeSupportGtk::getInnerText(frame); - if (isMainFrame) - result = g_strdup_printf("%s\n", innerText.data()); - else { - const gchar* frameName = webkit_web_frame_get_name(frame); - result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText.data()); - } - - if (gTestRunner->dumpChildFramesAsText()) { - GSList* children = DumpRenderTreeSupportGtk::getFrameChildren(frame); - for (GSList* child = children; child; child = g_slist_next(child)) { - GUniquePtr<gchar> childData(dumpFramesAsText(static_cast<WebKitWebFrame*>(child->data))); - appendString(result, childData.get()); - } - g_slist_free(children); - } - - return result; -} - -static gint compareHistoryItems(gpointer* item1, gpointer* item2) -{ - GUniquePtr<gchar> firstItemTarget(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item1))); - GUniquePtr<gchar> secondItemTarget(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item2))); - return g_ascii_strcasecmp(firstItemTarget.get(), secondItemTarget.get()); -} - -static void dumpHistoryItem(WebKitWebHistoryItem* item, int indent, bool current) -{ - ASSERT(item != NULL); - int start = 0; - g_object_ref(item); - if (current) { - printf("curr->"); - start = 6; - } - for (int i = start; i < indent; i++) - putchar(' '); - - // normalize file URLs. - const gchar* uri = webkit_web_history_item_get_uri(item); - gchar* uriScheme = g_uri_parse_scheme(uri); - if (g_strcmp0(uriScheme, "file") == 0) { - gchar* pos = g_strstr_len(uri, -1, "/LayoutTests/"); - if (!pos) { - g_free(uriScheme); - return; - } - - GString* result = g_string_sized_new(strlen(uri)); - result = g_string_append(result, "(file test):"); - result = g_string_append(result, pos + strlen("/LayoutTests/")); - printf("%s", result->str); - g_string_free(result, TRUE); - } else - printf("%s", uri); - - g_free(uriScheme); - - GUniquePtr<gchar> target(webkit_web_history_item_get_target(item)); - if (target.get() && strlen(target.get()) > 0) - printf(" (in frame \"%s\")", target.get()); - if (webkit_web_history_item_is_target_item(item)) - printf(" **nav target**"); - putchar('\n'); - - if (GList* kids = webkit_web_history_item_get_children(item)) { - // must sort to eliminate arbitrary result ordering which defeats reproducible testing - for (GList* kid = g_list_sort(kids, (GCompareFunc) compareHistoryItems); kid; kid = g_list_next(kid)) { - WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(kid->data); - dumpHistoryItem(item, indent + 4, FALSE); - g_object_unref(item); - } - g_list_free(kids); - } - g_object_unref(item); -} - -static void dumpBackForwardListForWebView(WebKitWebView* view) -{ - printf("\n============== Back Forward List ==============\n"); - WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(view); - - // Print out all items in the list after prevTestBFItem, which was from the previous test - // Gather items from the end of the list, the print them out from oldest to newest - GList* itemsToPrint = NULL; - gint forwardListCount = webkit_web_back_forward_list_get_forward_length(bfList); - for (int i = forwardListCount; i > 0; i--) { - WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i); - // something is wrong if the item from the last test is in the forward part of the b/f list - ASSERT(item != prevTestBFItem); - g_object_ref(item); - itemsToPrint = g_list_prepend(itemsToPrint, item); - } - - WebKitWebHistoryItem* currentItem = webkit_web_back_forward_list_get_current_item(bfList); - g_object_ref(currentItem); - itemsToPrint = g_list_prepend(itemsToPrint, currentItem); - - gint backListCount = webkit_web_back_forward_list_get_back_length(bfList); - for (int i = -1; i >= -(backListCount); i--) { - WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i); - if (item == prevTestBFItem) - break; - g_object_ref(item); - itemsToPrint = g_list_prepend(itemsToPrint, item); - } - - for (GList* itemToPrint = itemsToPrint; itemToPrint; itemToPrint = g_list_next(itemToPrint)) { - WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(itemToPrint->data); - dumpHistoryItem(item, historyItemIndent, item == currentItem); - g_object_unref(item); - } - - g_list_free(itemsToPrint); - printf("===============================================\n"); -} - -static void dumpBackForwardListForAllWebViews() -{ - // Dump the back forward list of the main WebView first - dumpBackForwardListForWebView(webView); - - // The view list is prepended. Reverse the list so we get the order right. - for (GSList* currentView = g_slist_reverse(webViewList); currentView; currentView = g_slist_next(currentView)) - dumpBackForwardListForWebView(WEBKIT_WEB_VIEW(currentView->data)); -} - -void setWaitToDumpWatchdog(guint timer) -{ - waitToDumpWatchdog = timer; -} - -bool shouldSetWaitToDumpWatchdog() -{ - return !waitToDumpWatchdog && useTimeoutWatchdog; -} - -CString soupURIToStringPreservingPassword(SoupURI* soupURI) -{ - if (!soupURI->password) { - GUniquePtr<char> uriString(soup_uri_to_string(soupURI, FALSE)); - return uriString.get(); - } - - // soup_uri_to_string does not insert the password into the string, so we need to create the - // URI string and then reinsert any credentials that were present in the SoupURI. All tests that - // use URL-embedded credentials use HTTP, so it's safe here. - GUniquePtr<char> password(soupURI->password); - GUniquePtr<char> user(soupURI->user); - soupURI->password = 0; - soupURI->user = 0; - - GUniquePtr<char> uriString(soup_uri_to_string(soupURI, FALSE)); - String absoluteURIWithoutCredentialString = String::fromUTF8(uriString.get()); - String protocolAndCredential = String::format("http://%s:%s@", user ? user.get() : "", password.get()); - return absoluteURIWithoutCredentialString.replace("http://", protocolAndCredential).utf8(); -} - -static void invalidateAnyPreviousWaitToDumpWatchdog() -{ - if (waitToDumpWatchdog) { - g_source_remove(waitToDumpWatchdog); - waitToDumpWatchdog = 0; - } - - waitForPolicy = false; -} - -static void resetDefaultsToConsistentValues() -{ - WebKitWebSettings* settings = webkit_web_view_get_settings(webView); - GUniquePtr<gchar> localStoragePath(g_build_filename(g_get_user_data_dir(), "DumpRenderTreeGtk", "databases", nullptr)); - g_object_set(G_OBJECT(settings), - "enable-accelerated-compositing", FALSE, - "enable-private-browsing", FALSE, - "enable-developer-extras", FALSE, - "enable-spell-checking", TRUE, - "enable-html5-database", TRUE, - "enable-html5-local-storage", TRUE, - "html5-local-storage-database-path", localStoragePath.get(), - "enable-xss-auditor", FALSE, - "enable-spatial-navigation", FALSE, - "javascript-can-access-clipboard", TRUE, - "javascript-can-open-windows-automatically", TRUE, - "enable-offline-web-application-cache", TRUE, - "enable-universal-access-from-file-uris", TRUE, - "enable-file-access-from-file-uris", TRUE, - "enable-scripts", TRUE, - "enable-dom-paste", TRUE, - "default-font-family", "Times", - "monospace-font-family", "Courier", - "serif-font-family", "Times", - "sans-serif-font-family", "Helvetica", - "cursive-font-family", "cursive", - "fantasy-font-family", "fantasy", - "default-font-size", 12, - "default-monospace-font-size", 10, - "minimum-font-size", 0, - "enable-caret-browsing", FALSE, - "enable-page-cache", FALSE, - "auto-resize-window", TRUE, - "auto-load-images", TRUE, - "enable-java-applet", FALSE, - "enable-plugins", TRUE, - "enable-hyperlink-auditing", FALSE, - "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX, - "enable-fullscreen", TRUE, - "enable-mediasource", TRUE, - NULL); - webkit_web_view_set_settings(webView, settings); - webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); - - DumpRenderTreeSupportGtk::clearMainFrameName(mainFrame); - DumpRenderTreeSupportGtk::scalePageBy(webView, 1, 0, 0); - - WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView); - g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", FALSE, NULL); - - webkit_web_view_set_zoom_level(webView, 1.0); - - DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists(); - - WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView); - webkit_web_back_forward_list_clear(list); - - SoupSession* session = webkit_get_default_session(); - SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); - - // We only create the jar when the soup backend needs to do - // HTTP. Should we initialize it earlier, perhaps? - if (jar) - g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY, NULL); - - setlocale(LC_ALL, ""); - - DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(true); - webkit_icon_database_set_path(webkit_get_icon_database(), 0); - DumpRenderTreeSupportGtk::setDefersLoading(webView, false); - DumpRenderTreeSupportGtk::setSerializeHTTPLoads(false); - -#if HAVE(ACCESSIBILITY) - if (axController) - axController->resetToConsistentState(); -#endif - - DumpRenderTreeSupportGtk::clearOpener(mainFrame); - DumpRenderTreeSupportGtk::setTracksRepaints(mainFrame, false); - - DumpRenderTreeSupportGtk::resetGeolocationClientMock(webView); - - DumpRenderTreeSupportGtk::setCSSGridLayoutEnabled(webView, false); - DumpRenderTreeSupportGtk::setCSSRegionsEnabled(webView, true); - DumpRenderTreeSupportGtk::setExperimentalContentSecurityPolicyFeaturesEnabled(true); - DumpRenderTreeSupportGtk::setSeamlessIFramesEnabled(true); - DumpRenderTreeSupportGtk::setShadowDOMEnabled(true); - - if (gTestRunner) { - gTestRunner->setAuthenticationPassword(""); - gTestRunner->setAuthenticationUsername(""); - gTestRunner->setHandlesAuthenticationChallenges(false); - } - - gtk_widget_set_direction(GTK_WIDGET(webView), GTK_TEXT_DIR_NONE); -} - -static bool useLongRunningServerMode(int argc, char *argv[]) -{ - // This assumes you've already called getopt_long - return (argc == optind+1 && !strcmp(argv[optind], "-")); -} - -static void runTestingServerLoop() -{ - // When DumpRenderTree runs in server mode, we just wait around for file names - // to be passed to us and read each in turn, passing the results back to the client - char filenameBuffer[2048]; - while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) { - char* newLineCharacter = strchr(filenameBuffer, '\n'); - if (newLineCharacter) - *newLineCharacter = '\0'; - - if (!strlen(filenameBuffer)) - continue; - - runTest(filenameBuffer); - } -} - -static void initializeGlobalsFromCommandLineOptions(int argc, char *argv[]) -{ - struct option options[] = { - {"notree", no_argument, &dumpTree, false}, - {"pixel-tests", no_argument, &dumpPixelsForAllTests, true}, - {"tree", no_argument, &dumpTree, true}, - {"no-timeout", no_argument, &useTimeoutWatchdog, false}, - {NULL, 0, NULL, 0} - }; - - int option; - while ((option = getopt_long(argc, (char * const *)argv, "", options, NULL)) != -1) { - switch (option) { - case '?': // unknown or ambiguous option - case ':': // missing argument - exit(1); - break; - } - } -} - - -void dump() -{ - invalidateAnyPreviousWaitToDumpWatchdog(); - - // Grab widget focus before dumping the contents of a widget, in - // case it was lost in the course of the test. - gtk_widget_grab_focus(GTK_WIDGET(webView)); - - if (dumpTree) { - char* result = 0; - gchar* responseMimeType = webkit_web_frame_get_response_mime_type(mainFrame); - - if (g_str_equal(responseMimeType, "text/plain")) { - gTestRunner->setDumpAsText(true); - gTestRunner->setGeneratePixelResults(false); - } - g_free(responseMimeType); - - if (gTestRunner->dumpAsText()) - result = dumpFramesAsText(mainFrame); - else { - // Widget resizing is done asynchronously in GTK+. We pump the main - // loop here, to flush any pending resize requests. This prevents - // timing issues which affect the size of elements in the output. - // We only enable this workaround for tests that print the render tree - // because this seems to break some dumpAsText tests: see bug 39988 - // After fixing that test, we should apply this approach to all dumps. - while (gtk_events_pending()) - gtk_main_iteration(); - - result = g_strdup(DumpRenderTreeSupportGtk::dumpRenderTree(mainFrame).data()); - } - - if (!result) { - const char* errorMessage; - if (gTestRunner->dumpAsText()) - errorMessage = "[documentElement innerText]"; - else if (gTestRunner->dumpDOMAsWebArchive()) - errorMessage = "[[mainFrame DOMDocument] webArchive]"; - else if (gTestRunner->dumpSourceAsWebArchive()) - errorMessage = "[[mainFrame dataSource] webArchive]"; - else - errorMessage = "[mainFrame renderTreeAsExternalRepresentation]"; - printf("ERROR: nil result from %s", errorMessage); - } else { - printf("%s", result); - g_free(result); - if (!gTestRunner->dumpAsText() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive()) - dumpFrameScrollPosition(mainFrame); - - if (gTestRunner->dumpBackForwardList()) - dumpBackForwardListForAllWebViews(); - } - - if (printSeparators) { - puts("#EOF"); // terminate the content block - fputs("#EOF\n", stderr); - fflush(stdout); - fflush(stderr); - } - } - - if (dumpPixelsForCurrentTest - && gTestRunner->generatePixelResults() - && !gTestRunner->dumpDOMAsWebArchive() - && !gTestRunner->dumpSourceAsWebArchive()) { - DumpRenderTreeSupportGtk::forceWebViewPaint(webView); - dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash()); - } - - // FIXME: call displayWebView here when we support --paint - - done = true; - gtk_main_quit(); -} - -static CString temporaryDatabaseDirectory() -{ - const char* directoryFromEnvironment = g_getenv("DUMPRENDERTREE_TEMP"); - if (directoryFromEnvironment) - return directoryFromEnvironment; - GUniquePtr<char> fallback(g_build_filename(g_get_user_data_dir(), "gtkwebkitdrt", "databases", NULL)); - return fallback.get(); -} - -static void setDefaultsToConsistentStateValuesForTesting() -{ - resetDefaultsToConsistentValues(); - -#if PLATFORM(X11) - webkit_web_settings_add_extra_plugin_directory(webView, TEST_PLUGIN_DIR); -#endif - - webkit_set_web_database_directory_path(temporaryDatabaseDirectory().data()); - -#if defined(GTK_API_VERSION_2) - gtk_rc_parse_string("style \"nix_scrollbar_spacing\" " - "{ " - " GtkScrolledWindow::scrollbar-spacing = 0 " - "} " - "class \"GtkWidget\" style \"nix_scrollbar_spacing\""); - -#else - GtkCssProvider* cssProvider = gtk_css_provider_new(); - gtk_css_provider_load_from_data(cssProvider, - "@binding-set NoKeyboardNavigation { " - " unbind \"<shift>F10\"; " - "} " - " * { " - " -GtkScrolledWindow-scrollbar-spacing: 0;" - " gtk-key-bindings: NoKeyboardNavigation; " - "} ", - -1, 0); - gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()), - GTK_STYLE_PROVIDER(cssProvider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - g_object_unref(cssProvider); -#endif -} - -static void sendPixelResultsEOF() -{ - puts("#EOF"); - - fflush(stdout); - fflush(stderr); -} - -static void runTest(const string& inputLine) -{ - ASSERT(!inputLine.empty()); - - TestCommand command = parseInputLine(inputLine); - string& testURL = command.pathOrURL; - dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests; - - // Convert the path into a full file URL if it does not look - // like an HTTP/S URL (doesn't start with http:// or https://). - if (testURL.find("http://") && testURL.find("https://")) { - GFile* testFile = g_file_new_for_path(testURL.c_str()); - gchar* testURLCString = g_file_get_uri(testFile); - testURL = testURLCString; - g_free(testURLCString); - g_object_unref(testFile); - } - - resetDefaultsToConsistentValues(); - - gTestRunner = TestRunner::create(testURL, command.expectedPixelHash); - topLoadingFrame = 0; - done = false; - - gTestRunner->setIconDatabaseEnabled(false); - - if (shouldLogFrameLoadDelegates(testURL)) - gTestRunner->setDumpFrameLoadCallbacks(true); - - if (shouldEnableDeveloperExtras(testURL)) { - gTestRunner->setDeveloperExtrasEnabled(true); - if (shouldOpenWebInspector(testURL)) - gTestRunner->showWebInspector(); - if (shouldDumpAsText(testURL)) { - gTestRunner->setDumpAsText(true); - gTestRunner->setGeneratePixelResults(false); - } - } - - WorkQueue::shared()->clear(); - WorkQueue::shared()->setFrozen(false); - - bool isSVGW3CTest = (testURL.find("svg/W3C-SVG-1.1") != string::npos); - GtkAllocation size; - size.x = size.y = 0; - size.width = isSVGW3CTest ? TestRunner::w3cSVGViewWidth : TestRunner::viewWidth; - size.height = isSVGW3CTest ? TestRunner::w3cSVGViewHeight : TestRunner::viewHeight; - gtk_window_resize(GTK_WINDOW(window), size.width, size.height); - gtk_widget_size_allocate(container, &size); - - if (prevTestBFItem) - g_object_unref(prevTestBFItem); - WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(webView); - prevTestBFItem = webkit_web_back_forward_list_get_current_item(bfList); - if (prevTestBFItem) - g_object_ref(prevTestBFItem); - - initializeFonts(testURL.c_str()); - - // Focus the web view before loading the test to avoid focusing problems - gtk_widget_grab_focus(GTK_WIDGET(webView)); - webkit_web_view_open(webView, testURL.c_str()); - - gtk_main(); - - // If developer extras enabled Web Inspector may have been open by the test. - if (shouldEnableDeveloperExtras(testURL)) { - gTestRunner->closeWebInspector(); - gTestRunner->setDeveloperExtrasEnabled(false); - } - - // Also check if we still have opened webViews and free them. - if (gTestRunner->closeRemainingWindowsWhenComplete() || webViewList) { - while (webViewList) { - g_object_unref(WEBKIT_WEB_VIEW(webViewList->data)); - webViewList = g_slist_next(webViewList); - } - g_slist_free(webViewList); - webViewList = 0; - } - - WebCoreTestSupport::resetInternalsObject(webkit_web_frame_get_global_context(mainFrame)); - DumpRenderTreeSupportGtk::clearMemoryCache(); - DumpRenderTreeSupportGtk::clearApplicationCache(); - - // A blank load seems to be necessary to reset state after certain tests. - webkit_web_view_open(webView, "about:blank"); - - gTestRunner.clear(); - - // terminate the (possibly empty) pixels block after all the state reset - sendPixelResultsEOF(); -} - -void webViewLoadStarted(WebKitWebView* view, WebKitWebFrame* frame, void*) -{ - // Make sure we only set this once per test. If it gets cleared, and then set again, we might - // end up doing two dumps for one test. - if (!topLoadingFrame && !done) - topLoadingFrame = frame; -} - -static gboolean processWork(void* data) -{ - // if we finish all the commands, we're ready to dump state - if (WorkQueue::shared()->processWork() && !gTestRunner->waitToDump()) - dump(); - - return FALSE; -} - -static char* getFrameNameSuitableForTestResult(WebKitWebView* view, WebKitWebFrame* frame) -{ - char* frameName = g_strdup(webkit_web_frame_get_name(frame)); - - if (frame == webkit_web_view_get_main_frame(view)) { - // This is a bit strange. Shouldn't web_frame_get_name return NULL? - if (frameName && (frameName[0] != '\0')) { - char* tmp = g_strdup_printf("main frame \"%s\"", frameName); - g_free(frameName); - frameName = tmp; - } else { - g_free(frameName); - frameName = g_strdup("main frame"); - } - } else if (!frameName || (frameName[0] == '\0')) { - g_free(frameName); - frameName = g_strdup("frame (anonymous)"); - } else { - char* tmp = g_strdup_printf("frame \"%s\"", frameName); - g_free(frameName); - frameName = tmp; - } - - return frameName; -} - -static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*) -{ - // The deprecated "load-finished" signal is triggered by postProgressFinishedNotification(), - // so we can use it here in the DRT to provide the correct dump. - if (frame != topLoadingFrame) - return; - if (gTestRunner->dumpProgressFinishedCallback()) - printf("postProgressFinishedNotification\n"); -} - -static gboolean webViewLoadError(WebKitWebView*, WebKitWebFrame*, gchar*, gpointer, gpointer) -{ - return TRUE; // Return true here to disable the default error page. -} - -static void webViewDocumentLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*) -{ - if (!done && gTestRunner->dumpFrameLoadCallbacks()) { - char* frameName = getFrameNameSuitableForTestResult(view, frame); - printf("%s - didFinishDocumentLoadForFrame\n", frameName); - g_free(frameName); - } else if (!done) { - guint pendingFrameUnloadEvents = DumpRenderTreeSupportGtk::getPendingUnloadEventCount(frame); - if (pendingFrameUnloadEvents) { - char* frameName = getFrameNameSuitableForTestResult(view, frame); - printf("%s - has %u onunload handler(s)\n", frameName, pendingFrameUnloadEvents); - g_free(frameName); - } - } -} - -static void webViewOnloadEvent(WebKitWebView* view, WebKitWebFrame* frame, void*) -{ - if (!done && gTestRunner->dumpFrameLoadCallbacks()) { - char* frameName = getFrameNameSuitableForTestResult(view, frame); - printf("%s - didHandleOnloadEventsForFrame\n", frameName); - g_free(frameName); - } -} - -static void addControllerToWindow(JSContextRef context, JSObjectRef windowObject, const char* controllerName, JSValueRef controller) -{ - JSStringRef controllerNameStr = JSStringCreateWithUTF8CString(controllerName); - JSObjectSetProperty(context, windowObject, controllerNameStr, controller, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); - JSStringRelease(controllerNameStr); -} - -static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data) -{ - JSValueRef exception = 0; - ASSERT(gTestRunner); - - gTestRunner->makeWindowObject(context, windowObject, &exception); - ASSERT(!exception); - - gcController->makeWindowObject(context, windowObject, &exception); - ASSERT(!exception); - -#if HAVE(ACCESSIBILITY) - axController->makeWindowObject(context, windowObject, &exception); - ASSERT(!exception); -#endif - - addControllerToWindow(context, windowObject, "eventSender", makeEventSender(context, !webkit_web_frame_get_parent(frame))); - addControllerToWindow(context, windowObject, "textInputController", makeTextInputController(context)); - WebCoreTestSupport::injectInternalsObject(context); -} - -static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data) -{ - gchar* testMessage = 0; - const gchar* uriScheme; - - // Tests expect only the filename part of local URIs - uriScheme = g_strstr_len(message, -1, "file://"); - if (uriScheme) { - GString* tempString = g_string_sized_new(strlen(message)); - gchar* filename = g_strrstr(uriScheme, G_DIR_SEPARATOR_S); - - if (filename) { - // If the path is a lone slash, keep it to avoid empty output. - if (strlen(filename) > 1) - filename += strlen(G_DIR_SEPARATOR_S); - tempString = g_string_append_len(tempString, message, (uriScheme - message)); - tempString = g_string_append_len(tempString, filename, strlen(filename)); - testMessage = g_string_free(tempString, FALSE); - } - } - - fprintf(stdout, "CONSOLE MESSAGE: "); - if (line) - fprintf(stdout, "line %d: ", line); - fprintf(stdout, "%s\n", testMessage ? testMessage : message); - g_free(testMessage); - - return TRUE; -} - - -static gboolean webViewScriptAlert(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gpointer data) -{ - fprintf(stdout, "ALERT: %s\n", message); - fflush(stdout); - return TRUE; -} - -static gboolean webViewScriptPrompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value, gpointer data) -{ - fprintf(stdout, "PROMPT: %s, default text: %s\n", message, defaultValue); - *value = g_strdup(defaultValue); - return TRUE; -} - -static gboolean webViewScriptConfirm(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm, gpointer data) -{ - fprintf(stdout, "CONFIRM: %s\n", message); - *didConfirm = TRUE; - return TRUE; -} - -static void webViewTitleChanged(WebKitWebView* view, WebKitWebFrame* frame, const gchar* title, gpointer data) -{ - if (gTestRunner->dumpFrameLoadCallbacks() && !done) { - GUniquePtr<char> frameName(getFrameNameSuitableForTestResult(view, frame)); - printf("%s - didReceiveTitle: %s\n", frameName.get(), title ? title : ""); - } - - if (gTestRunner->dumpTitleChanges() && !done) - printf("TITLE CHANGED: '%s'\n", title ? title : ""); -} - -static bool webViewNavigationPolicyDecisionRequested(WebKitWebView* view, WebKitWebFrame* frame, - WebKitNetworkRequest* request, - WebKitWebNavigationAction* navAction, - WebKitWebPolicyDecision* policyDecision) -{ - // Use the default handler if we're not waiting for policy, - // i.e., TestRunner::waitForPolicyDelegate - if (!waitForPolicy) - return FALSE; - - gchar* typeDescription; - WebKitWebNavigationReason reason; - g_object_get(G_OBJECT(navAction), "reason", &reason, NULL); - - switch(reason) { - case WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED: - typeDescription = g_strdup("link clicked"); - break; - case WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED: - typeDescription = g_strdup("form submitted"); - break; - case WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD: - typeDescription = g_strdup("back/forward"); - break; - case WEBKIT_WEB_NAVIGATION_REASON_RELOAD: - typeDescription = g_strdup("reload"); - break; - case WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED: - typeDescription = g_strdup("form resubmitted"); - break; - case WEBKIT_WEB_NAVIGATION_REASON_OTHER: - typeDescription = g_strdup("other"); - break; - default: - typeDescription = g_strdup("illegal value"); - } - - printf("Policy delegate: attempt to load %s with navigation type '%s'\n", webkit_network_request_get_uri(request), typeDescription); - g_free(typeDescription); - - webkit_web_policy_decision_ignore(policyDecision); - gTestRunner->notifyDone(); - - return TRUE; -} - -static void webViewStatusBarTextChanged(WebKitWebView* view, const gchar* message, gpointer data) -{ - // Are we doing anything wrong? One test that does not call - // dumpStatusCallbacks gets true here - if (gTestRunner->dumpStatusCallbacks()) - printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message); -} - -static gboolean webViewClose(WebKitWebView* view) -{ - ASSERT(view); - - webViewList = g_slist_remove(webViewList, view); - g_object_unref(view); - - return TRUE; -} - -static void databaseQuotaExceeded(WebKitWebView* view, WebKitWebFrame* frame, WebKitWebDatabase *database) -{ - ASSERT(view); - ASSERT(frame); - ASSERT(database); - - WebKitSecurityOrigin* origin = webkit_web_database_get_security_origin(database); - if (gTestRunner->dumpDatabaseCallbacks()) { - printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n", - webkit_security_origin_get_protocol(origin), - webkit_security_origin_get_host(origin), - webkit_security_origin_get_port(origin), - webkit_web_database_get_name(database)); - } - webkit_security_origin_set_web_database_quota(origin, 5 * 1024 * 1024); -} - -static bool -geolocationPolicyDecisionRequested(WebKitWebView*, WebKitWebFrame*, WebKitGeolocationPolicyDecision* decision) -{ - if (!gTestRunner->isGeolocationPermissionSet()) - return FALSE; - if (gTestRunner->geolocationPermission()) - webkit_geolocation_policy_allow(decision); - else - webkit_geolocation_policy_deny(decision); - - return TRUE; -} - - -static WebKitWebView* webViewCreate(WebKitWebView*, WebKitWebFrame*); - -static gboolean webInspectorShowWindow(WebKitWebInspector*, gpointer data) -{ - gtk_window_set_default_size(GTK_WINDOW(webInspectorWindow), TestRunner::viewWidth, TestRunner::viewHeight); - gtk_widget_show_all(webInspectorWindow); - return TRUE; -} - -static gboolean webInspectorCloseWindow(WebKitWebInspector*, gpointer data) -{ - gtk_widget_destroy(webInspectorWindow); - webInspectorWindow = 0; - return TRUE; -} - -static WebKitWebView* webInspectorInspectWebView(WebKitWebInspector*, gpointer data) -{ - webInspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - GtkWidget* webView = self_scrolling_webkit_web_view_new(); - gtk_container_add(GTK_CONTAINER(webInspectorWindow), - webView); - - return WEBKIT_WEB_VIEW(webView); -} - -static void topLoadingFrameLoadFinished() -{ - topLoadingFrame = 0; - WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test - if (gTestRunner->waitToDump()) - return; - - if (WorkQueue::shared()->count()) - g_idle_add_full(G_PRIORITY_DEFAULT, processWork, 0, 0); - else - dump(); -} - -static void webFrameLoadStatusNotified(WebKitWebFrame* frame, gpointer user_data) -{ - WebKitLoadStatus loadStatus = webkit_web_frame_get_load_status(frame); - - if (gTestRunner->dumpFrameLoadCallbacks()) { - GUniquePtr<char> frameName(getFrameNameSuitableForTestResult(webkit_web_frame_get_web_view(frame), frame)); - - switch (loadStatus) { - case WEBKIT_LOAD_PROVISIONAL: - if (!done) - printf("%s - didStartProvisionalLoadForFrame\n", frameName.get()); - break; - case WEBKIT_LOAD_COMMITTED: - if (!done) - printf("%s - didCommitLoadForFrame\n", frameName.get()); - break; - case WEBKIT_LOAD_FINISHED: - if (!done) - printf("%s - didFinishLoadForFrame\n", frameName.get()); - break; - case WEBKIT_LOAD_FAILED: - if (!done) - printf("%s - didFailLoadWithError\n", frameName.get()); - break; - default: - break; - } - } - - if ((loadStatus == WEBKIT_LOAD_FINISHED || loadStatus == WEBKIT_LOAD_FAILED) - && frame == topLoadingFrame) - topLoadingFrameLoadFinished(); -} - -static void frameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* webFrame, gpointer user_data) -{ - g_signal_connect(webFrame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL); - g_signal_connect(webFrame, "insecure-content-run", G_CALLBACK(didRunInsecureContent), NULL); -} - -static String pathFromSoupURI(SoupURI* uri) -{ - if (!uri) - return "(null)"; - - if (!g_str_equal(uri->scheme, "file")) - return soupURIToStringPreservingPassword(uri).data(); - - String pathString = uri->path; - GUniquePtr<gchar> pathBasename(g_path_get_basename(pathString.utf8().data())); - - WebKitWebFrame* mainFrame = webkit_web_view_get_main_frame(webView); - GUniquePtr<SoupURI> mainFrameUri(soup_uri_new(webkit_web_frame_get_uri(mainFrame))); - - String mainFrameUriPathString = mainFrameUri.get()->path; - String basePath = mainFrameUriPathString.substring(0, mainFrameUriPathString.reverseFind('/') + 1); - - if (!basePath.isEmpty() && pathString.startsWith(basePath)) - return pathString.substring(basePath.length()); - - return pathBasename.get(); -} - -static CString convertSoupMessageToURLPath(SoupMessage* soupMessage) -{ - if (!soupMessage) - return CString("(null)"); - if (SoupURI* requestURI = soup_message_get_uri(soupMessage)) - return pathFromSoupURI(requestURI).utf8(); - return CString("(null)"); -} - -static CString convertNetworkRequestToURLPath(WebKitNetworkRequest* request) -{ - return convertSoupMessageToURLPath(webkit_network_request_get_message(request)); -} - -static CString convertWebResourceToURLPath(WebKitWebResource* webResource) -{ - GUniquePtr<SoupURI> uri(soup_uri_new(webkit_web_resource_get_uri(webResource))); - return pathFromSoupURI(uri.get()).utf8(); -} - -static CString urlSuitableForTestResult(const char* uriString) -{ - if (!g_str_has_prefix(uriString, "file://")) - return CString(uriString); - - GUniquePtr<gchar> basename(g_path_get_basename(uriString)); - return CString(basename.get()); -} - -static CString descriptionSuitableForTestResult(SoupURI* uri) -{ - if (!uri) - return CString("(null)"); - - GUniquePtr<char> uriString(soup_uri_to_string(uri, false)); - return urlSuitableForTestResult(uriString.get()); -} - -static CString descriptionSuitableForTestResult(GError* error, WebKitWebResource* webResource) -{ - const gchar* errorDomain = g_quark_to_string(error->domain); - CString resourceURIString(urlSuitableForTestResult(webkit_web_resource_get_uri(webResource))); - - if (g_str_equal(errorDomain, "webkit-network-error-quark") || g_str_equal(errorDomain, "soup_http_error_quark")) - errorDomain = "NSURLErrorDomain"; - - if (g_str_equal(errorDomain, "WebKitPolicyError")) - errorDomain = "WebKitErrorDomain"; - - // TODO: the other ports get the failingURL from the ResourceError - GUniquePtr<char> errorString(g_strdup_printf("<NSError domain %s, code %d, failing URL \"%s\">", - errorDomain, error->code, resourceURIString.data())); - return CString(errorString.get()); -} - -static CString descriptionSuitableForTestResult(WebKitNetworkRequest* request) -{ - SoupMessage* soupMessage = webkit_network_request_get_message(request); - - if (!soupMessage) - return CString("(null)"); - - SoupURI* mainDocumentURI = soup_message_get_first_party(soupMessage); - CString mainDocumentURIString(descriptionSuitableForTestResult(mainDocumentURI)); - CString path(convertNetworkRequestToURLPath(request)); - GUniquePtr<char> description(g_strdup_printf("<NSURLRequest URL %s, main document URL %s, http method %s>", - path.data(), mainDocumentURIString.data(), soupMessage->method)); - return CString(description.get()); -} - -static CString descriptionSuitableForTestResult(WebKitNetworkResponse* response) -{ - if (!response) - return CString("(null)"); - - int statusCode = 0; - CString responseURIString(urlSuitableForTestResult(webkit_network_response_get_uri(response))); - SoupMessage* soupMessage = webkit_network_response_get_message(response); - CString path; - - if (soupMessage) { - statusCode = soupMessage->status_code; - path = convertSoupMessageToURLPath(soupMessage); - } else - path = CString("(null)"); - - GUniquePtr<char> description(g_strdup_printf("<NSURLResponse %s, http status code %d>", path.data(), statusCode)); - return CString(description.get()); -} - -static void willSendRequestCallback(WebKitWebView* webView, WebKitWebFrame* webFrame, WebKitWebResource* resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response) -{ - - - if (!done && gTestRunner->willSendRequestReturnsNull()) { - // As requested by the TestRunner, don't perform the request. - webkit_network_request_set_uri(request, "about:blank"); - return; - } - - if (!done && gTestRunner->dumpResourceLoadCallbacks()) - printf("%s - willSendRequest %s redirectResponse %s\n", - convertNetworkRequestToURLPath(request).data(), - descriptionSuitableForTestResult(request).data(), - descriptionSuitableForTestResult(response).data()); - - SoupMessage* soupMessage = webkit_network_request_get_message(request); - SoupURI* uri = soup_uri_new(webkit_network_request_get_uri(request)); - - if (SOUP_URI_IS_VALID(uri)) { - GUniquePtr<char> uriString(soup_uri_to_string(uri, FALSE)); - - if (SOUP_URI_VALID_FOR_HTTP(uri) && g_strcmp0(uri->host, "127.0.0.1") - && g_strcmp0(uri->host, "255.255.255.255") - && g_ascii_strncasecmp(uri->host, "localhost", 9)) { - printf("Blocked access to external URL %s\n", uriString.get()); - // Cancel load of blocked resource to avoid potential - // network-related timeouts in tests. - webkit_network_request_set_uri(request, "about:blank"); - soup_uri_free(uri); - return; - } - - const string& destination = gTestRunner->redirectionDestinationForURL(uriString.get()); - if (!destination.empty()) - webkit_network_request_set_uri(request, destination.c_str()); - } - - if (uri) - soup_uri_free(uri); - - if (soupMessage) { - const set<string>& clearHeaders = gTestRunner->willSendRequestClearHeaders(); - for (set<string>::const_iterator header = clearHeaders.begin(); header != clearHeaders.end(); ++header) - soup_message_headers_remove(soupMessage->request_headers, header->c_str()); - } -} - - -static void didReceiveResponse(WebKitWebView* webView, WebKitWebFrame*, WebKitWebResource* webResource, WebKitNetworkResponse* response) -{ - if (!done && gTestRunner->dumpResourceLoadCallbacks()) { - CString responseDescription(descriptionSuitableForTestResult(response)); - CString path(convertWebResourceToURLPath(webResource)); - printf("%s - didReceiveResponse %s\n", path.data(), responseDescription.data()); - } - - // TODO: add "has MIME type" whenever dumpResourceResponseMIMETypes() is supported. - // See https://bugs.webkit.org/show_bug.cgi?id=58222. -} - -static void didFinishLoading(WebKitWebView* webView, WebKitWebFrame* webFrame, WebKitWebResource* webResource) -{ - if (!done && gTestRunner->dumpResourceLoadCallbacks()) - printf("%s - didFinishLoading\n", convertWebResourceToURLPath(webResource).data()); -} - -static void didFailLoadingWithError(WebKitWebView* webView, WebKitWebFrame* webFrame, WebKitWebResource* webResource, GError* webError) -{ - if (!done && gTestRunner->dumpResourceLoadCallbacks()) { - CString webErrorString(descriptionSuitableForTestResult(webError, webResource)); - printf("%s - didFailLoadingWithError: %s\n", convertWebResourceToURLPath(webResource).data(), - webErrorString.data()); - } -} - -static void didRunInsecureContent(WebKitWebFrame*, WebKitSecurityOrigin*, const char* url) -{ - if (!done && gTestRunner->dumpFrameLoadCallbacks()) - printf("didRunInsecureContent\n"); -} - -static gboolean webViewRunFileChooser(WebKitWebView*, WebKitFileChooserRequest*) -{ - // We return TRUE to not propagate the event further so the - // default file chooser dialog is not shown. - return TRUE; -} - -static void frameLoadEventCallback(WebKitWebFrame* frame, DumpRenderTreeSupportGtk::FrameLoadEvent event, const char* url) -{ - if (done || !gTestRunner->dumpFrameLoadCallbacks()) - return; - - GUniquePtr<char> frameName(getFrameNameSuitableForTestResult(webkit_web_frame_get_web_view(frame), frame)); - switch (event) { - case DumpRenderTreeSupportGtk::WillPerformClientRedirectToURL: - ASSERT(url); - printf("%s - willPerformClientRedirectToURL: %s \n", frameName.get(), url); - break; - case DumpRenderTreeSupportGtk::DidCancelClientRedirect: - printf("%s - didCancelClientRedirectForFrame\n", frameName.get()); - break; - case DumpRenderTreeSupportGtk::DidReceiveServerRedirectForProvisionalLoad: - printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", frameName.get()); - break; - case DumpRenderTreeSupportGtk::DidDisplayInsecureContent: - printf ("didDisplayInsecureContent\n"); - break; - case DumpRenderTreeSupportGtk::DidDetectXSS: - printf ("didDetectXSS\n"); - break; - default: - ASSERT_NOT_REACHED(); - } -} - -static bool authenticationCallback(CString& username, CString& password, WebKitWebResource* webResource) -{ - CString description(convertWebResourceToURLPath(webResource)); - - if (!gTestRunner->handlesAuthenticationChallenges()) { - printf("%s - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet\n", description.data()); - return false; - } - - username = gTestRunner->authenticationUsername().c_str(); - password = gTestRunner->authenticationPassword().c_str(); - printf("%s - didReceiveAuthenticationChallenge - Responding with %s:%s\n", description.data(), username.data(), password.data()); - return true; -} - -static WebKitWebView* createWebView() -{ - // It is important to declare DRT is running early so when creating - // web view mock clients are used instead of proper ones. - DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(true); - - DumpRenderTreeSupportGtk::setFrameLoadEventCallback(frameLoadEventCallback); - DumpRenderTreeSupportGtk::setAuthenticationCallback(authenticationCallback); - - WebKitWebView* view = WEBKIT_WEB_VIEW(self_scrolling_webkit_web_view_new()); - - g_object_connect(G_OBJECT(view), - "signal::load-started", webViewLoadStarted, 0, - "signal::load-finished", webViewLoadFinished, 0, - "signal::load-error", webViewLoadError, 0, - "signal::window-object-cleared", webViewWindowObjectCleared, 0, - "signal::console-message", webViewConsoleMessage, 0, - "signal::script-alert", webViewScriptAlert, 0, - "signal::script-prompt", webViewScriptPrompt, 0, - "signal::script-confirm", webViewScriptConfirm, 0, - "signal::title-changed", webViewTitleChanged, 0, - "signal::navigation-policy-decision-requested", webViewNavigationPolicyDecisionRequested, 0, - "signal::status-bar-text-changed", webViewStatusBarTextChanged, 0, - "signal::create-web-view", webViewCreate, 0, - "signal::close-web-view", webViewClose, 0, - "signal::database-quota-exceeded", databaseQuotaExceeded, 0, - "signal::document-load-finished", webViewDocumentLoadFinished, 0, - "signal::geolocation-policy-decision-requested", geolocationPolicyDecisionRequested, 0, - "signal::onload-event", webViewOnloadEvent, 0, - "signal::drag-begin", dragBeginCallback, 0, - "signal::drag-end", dragEndCallback, 0, - "signal::drag-failed", dragFailedCallback, 0, - "signal::frame-created", frameCreatedCallback, 0, - "signal::resource-request-starting", willSendRequestCallback, 0, - "signal::resource-response-received", didReceiveResponse, 0, - "signal::resource-load-finished", didFinishLoading, 0, - "signal::resource-load-failed", didFailLoadingWithError, 0, - "signal::run-file-chooser", webViewRunFileChooser, 0, - NULL); - connectEditingCallbacks(view); - - WebKitWebInspector* inspector = webkit_web_view_get_inspector(view); - g_object_connect(G_OBJECT(inspector), - "signal::inspect-web-view", webInspectorInspectWebView, 0, - "signal::show-window", webInspectorShowWindow, 0, - "signal::close-window", webInspectorCloseWindow, 0, - NULL); - - if (webView) { - WebKitWebSettings* settings = webkit_web_view_get_settings(webView); - webkit_web_view_set_settings(view, settings); - } - - // frame-created is not issued for main frame. That's why we must do this here - WebKitWebFrame* frame = webkit_web_view_get_main_frame(view); - g_signal_connect(frame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL); - g_signal_connect(frame, "insecure-content-run", G_CALLBACK(didRunInsecureContent), NULL); - - return view; -} - -static WebKitWebView* webViewCreate(WebKitWebView* view, WebKitWebFrame* frame) -{ - if (!gTestRunner->canOpenWindows()) - return 0; - - // Make sure that waitUntilDone has been called. - ASSERT(gTestRunner->waitToDump()); - - WebKitWebView* newWebView = createWebView(); - g_object_ref_sink(G_OBJECT(newWebView)); - webViewList = g_slist_prepend(webViewList, newWebView); - return newWebView; -} - -static void logHandler(const gchar* domain, GLogLevelFlags level, const gchar* message, gpointer data) -{ - if (level < G_LOG_LEVEL_DEBUG) - fprintf(stderr, "%s\n", message); -} - -int main(int argc, char* argv[]) -{ - gtk_init(&argc, &argv); - - // Some plugins might try to use the GLib logger for printing debug - // messages. This will cause tests to fail because of unexpected output. - // We squelch all debug messages sent to the logger. - g_log_set_default_handler(logHandler, 0); - - initializeGlobalsFromCommandLineOptions(argc, argv); - initializeFonts(); - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); -#ifdef GTK_API_VERSION_2 - container = gtk_hbox_new(TRUE, 0); -#else - container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous(GTK_BOX(container), TRUE); -#endif - gtk_container_add(GTK_CONTAINER(window), container); - gtk_widget_show_all(window); - - webView = createWebView(); - gtk_box_pack_start(GTK_BOX(container), GTK_WIDGET(webView), TRUE, TRUE, 0); - gtk_widget_realize(GTK_WIDGET(webView)); - gtk_widget_show_all(container); - mainFrame = webkit_web_view_get_main_frame(webView); - - setDefaultsToConsistentStateValuesForTesting(); - - gcController = new GCController(); -#if HAVE(ACCESSIBILITY) - axController = new AccessibilityController(); -#endif - - if (useLongRunningServerMode(argc, argv)) { - printSeparators = true; - runTestingServerLoop(); - } else { - printSeparators = (optind < argc-1 || (dumpPixelsForCurrentTest && dumpTree)); - for (int i = optind; i != argc; ++i) - runTest(argv[i]); - } - - delete gcController; - gcController = 0; - -#if HAVE(ACCESSIBILITY) - delete axController; - axController = 0; -#endif - - gtk_widget_destroy(window); - - return 0; -} |