diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk/tests')
4 files changed, 350 insertions, 6 deletions
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am index 1db90a628..a8f9976fd 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am +++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am @@ -1,11 +1,13 @@ if ENABLE_WEBKIT2 TEST_PROGS += \ + Programs/WebKit2APITests/InspectorTestServer \ Programs/WebKit2APITests/TestBackForwardList \ Programs/WebKit2APITests/TestContextMenu \ Programs/WebKit2APITests/TestCookieManager \ Programs/WebKit2APITests/TestDownloads \ Programs/WebKit2APITests/TestInspector \ + Programs/WebKit2APITests/TestInspectorServer \ Programs/WebKit2APITests/TestLoaderClient \ Programs/WebKit2APITests/TestPrinting \ Programs/WebKit2APITests/TestResources \ @@ -106,6 +108,12 @@ Programs_WebKit2APITests_TestWebKitSettings_CPPFLAGS = $(webkit2_tests_cppflags) Programs_WebKit2APITests_TestWebKitSettings_LDADD = $(webkit2_tests_ldadd) Programs_WebKit2APITests_TestWebKitSettings_LDFLAGS = $(webkit2_tests_ldflags) +Programs_WebKit2APITests_InspectorTestServer_SOURCES = \ + Source/WebKit2/UIProcess/API/gtk/tests/InspectorTestServer.cpp +Programs_WebKit2APITests_InspectorTestServer_CPPFLAGS = $(webkit2_tests_cppflags) +Programs_WebKit2APITests_InspectorTestServer_LDADD = $(webkit2_tests_ldadd) +Programs_WebKit2APITests_InspectorTestServer_LDFLAGS = $(webkit2_tests_ldflags) + Programs_WebKit2APITests_TestBackForwardList_SOURCES = \ Source/WebKit2/UIProcess/API/gtk/tests/TestBackForwardList.cpp Programs_WebKit2APITests_TestBackForwardList_CPPFLAGS = $(webkit2_tests_cppflags) @@ -182,6 +190,12 @@ Programs_WebKit2APITests_TestInspector_CPPFLAGS = \ Programs_WebKit2APITests_TestInspector_LDADD = $(webkit2_tests_ldadd) Programs_WebKit2APITests_TestInspector_LDFLAGS = $(webkit2_tests_ldflags) +Programs_WebKit2APITests_TestInspectorServer_SOURCES = \ + Source/WebKit2/UIProcess/API/gtk/tests/TestInspectorServer.cpp +Programs_WebKit2APITests_TestInspectorServer_CPPFLAGS = $(webkit2_tests_cppflags) +Programs_WebKit2APITests_TestInspectorServer_LDADD = $(webkit2_tests_ldadd) +Programs_WebKit2APITests_TestInspectorServer_LDFLAGS = $(webkit2_tests_ldflags) + Programs_WebKit2APITests_TestWebKitVersion_SOURCES = \ Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitVersion.cpp Programs_WebKit2APITests_TestWebKitVersion_CPPFLAGS = $(webkit2_tests_cppflags) diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/InspectorTestServer.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/InspectorTestServer.cpp new file mode 100644 index 000000000..f13b043df --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/tests/InspectorTestServer.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 Samsung Electronics Ltd. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER 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. + */ + +#include "config.h" + +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void loadChangedCallback(WebKitWebView*, WebKitLoadEvent loadEvent, gpointer) +{ + // Send a message to the parent process when we're ready. + if (loadEvent == WEBKIT_LOAD_FINISHED) + g_print("OK"); +} + +int main(int argc, char** argv) +{ + gtk_init(&argc, &argv); + + // Overwrite WEBKIT_INSPECTOR_SERVER variable with default value. + g_setenv("WEBKIT_INSPECTOR_SERVER", "127.0.0.1:2999", TRUE); + + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + webkit_settings_set_enable_developer_extras(webkit_web_view_get_settings(webView), TRUE); + webkit_web_view_load_html(webView, + "<html><body><p>WebKitGTK+ Inspector Test Server</p></body></html>", + "http://127.0.0.1:2999/"); + + GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(webView)); + gtk_widget_show_all(window); + + g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), 0); + g_signal_connect(webView, "load-changed", G_CALLBACK(loadChangedCallback), 0); + + gtk_main(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestInspectorServer.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestInspectorServer.cpp new file mode 100644 index 000000000..30d8fac0c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestInspectorServer.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2012 Samsung Electronics Ltd. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER 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. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <wtf/gobject/GRefPtr.h> +#include <wtf/text/WTFString.h> + +// Name of the test server application creating the webView object. +static const char* gTestServerAppName = "InspectorTestServer"; + +// Max seconds to wait for the test server before inspecting it. +static const int gMaxWaitForChild = 5; + +// The PID for the test server running, so we can kill it if needed. +static GPid gChildProcessPid = 0; + +// Whether the child has replied and it's ready. +static bool gChildIsReady = false; + +static void stopTestServer() +{ + // Do nothing if there's no server running. + if (!gChildProcessPid) + return; + + g_spawn_close_pid(gChildProcessPid); + kill(gChildProcessPid, SIGTERM); + gChildProcessPid = 0; +} + +static void sigAbortHandler(int sigNum) +{ + // Just stop the test server if SIGABRT was received. + stopTestServer(); +} + +static gpointer testServerMonitorThreadFunc(gpointer) +{ + // Wait for the specified timeout to happen. + g_usleep(gMaxWaitForChild * G_USEC_PER_SEC); + + // Kill the child process if not ready yet. + if (!gChildIsReady) + stopTestServer(); + + g_thread_exit(0); + return 0; +} + +static void startTestServerMonitor() +{ + gChildIsReady = false; + +#if (!GLIB_CHECK_VERSION(2, 31, 0)) + g_thread_create(testServerMonitorThreadFunc, 0, FALSE, 0); +#else + g_thread_new("TestServerMonitor", testServerMonitorThreadFunc, 0); +#endif +} + +static void startTestServer() +{ + // Prepare argv[] for spawning the server process. + GOwnPtr<char> testServerPath(g_build_filename(WEBKIT_EXEC_PATH, "WebKit2APITests", gTestServerAppName, NULL)); + + // We install a handler to ensure that we kill the child process + // if the parent dies because of whatever the reason is. + signal(SIGABRT, sigAbortHandler); + + char* testServerArgv[2]; + testServerArgv[0] = testServerPath.get(); + testServerArgv[1] = 0; + + // Spawn the server, getting its stdout file descriptor to set a + // communication channel, so we know when it's ready. + int childStdout = 0; + g_assert(g_spawn_async_with_pipes(0, testServerArgv, 0, static_cast<GSpawnFlags>(0), 0, 0, + &gChildProcessPid, 0, &childStdout, 0, 0)); + + // Start monitoring the test server (in a separate thread) to + // ensure we don't block on the child process more than a timeout. + startTestServerMonitor(); + + char msg[2]; + GIOChannel* ioChannel = g_io_channel_unix_new(childStdout); + if (g_io_channel_read_chars(ioChannel, msg, 2, 0, 0) == G_IO_STATUS_NORMAL) { + // Check whether the server sent a message saying it's ready + // and store the result globally, so the monitor can see it. + gChildIsReady = msg[0] == 'O' && msg[1] == 'K'; + } + g_io_channel_unref(ioChannel); + close(childStdout); + + // The timeout was reached and the server is not ready yet, so + // stop it inmediately, and let the unit tests fail. + if (!gChildIsReady) + stopTestServer(); +} + +class InspectorServerTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(InspectorServerTest); + + InspectorServerTest() + : WebViewTest() + { + } + + bool getPageList() + { + loadHtml("<script type=\"text/javascript\">\n" + "var pages;\n" + "var xhr = new XMLHttpRequest;\n" + "xhr.open(\"GET\", \"/pagelist.json\");\n" + "xhr.onload = function(e) {\n" + "if (xhr.status == 200) {\n" + "pages = JSON.parse(xhr.responseText);\n" + "document.title = \"OK\";\n" + "} else \n" + "document.title = \"FAIL\";\n" + "}\n" + "xhr.send();\n" + "</script>\n", + "http://127.0.0.1:2999/"); + + waitUntilTitleChanged(); + + if (!strcmp(webkit_web_view_get_title(m_webView), "OK")) + return true; + + return false; + } + + ~InspectorServerTest() + { + } +}; + +// Test to get inspector server page list from the test server. +// Should contain only one entry pointing to http://127.0.0.1:2999/webinspector/inspector.html?page=1 +static void testInspectorServerPageList(InspectorServerTest* test, gconstpointer) +{ + GOwnPtr<GError> error; + + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + g_assert(test->getPageList()); + + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages.length;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert_cmpint(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 1); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].id;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + int pageId = WebViewTest::javascriptResultToNumber(javascriptResult); + + GOwnPtr<char> valueString; + javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].url;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.set(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "http://127.0.0.1:2999/"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].inspectorUrl;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.set(WebViewTest::javascriptResultToCString(javascriptResult)); + String validInspectorURL = String("/webinspector/inspector.html?page=") + String::number(pageId); + g_assert_cmpstr(valueString.get(), ==, validInspectorURL.utf8().data()); +} + +// Test sending a raw remote debugging message through our web socket server. +// For this specific message see: http://code.google.com/chrome/devtools/docs/protocol/tot/runtime.html#command-evaluate +static void testRemoteDebuggingMessage(InspectorServerTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + + test->loadHtml("<script type=\"text/javascript\">\n" + "var socket = new WebSocket('ws://127.0.0.1:2999/devtools/page/1');\n" + "socket.onmessage = function(message) {\n" + "var response = JSON.parse(message.data);\n" + "if (response.id === 1)\n" + "document.title = response.result.result.value;\n" + "else\n" + "document.title = \"FAIL\";\n" + "}\n" + "socket.onopen = function() {\n" + "socket.send('{\"id\": 1, \"method\": \"Runtime.evaluate\", \"params\": {\"expression\": \"2 + 2\" } }');\n" + "}\n" + "</script>", + "http://127.0.0.1:2999/"); + test->waitUntilTitleChanged(); + + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, "4"); +} + +static void openRemoteDebuggingSession(InspectorServerTest* test, gconstpointer) +{ + // To test the whole pipeline this exploits a behavior of the inspector front-end which won't provide any title unless the + // debugging session was established correctly through web socket. It should be something like "Web Inspector - <Page URL>". + // In our case page URL should be http://127.0.0.1:2999/ + // So this test case will fail if: + // - The page list didn't return a valid inspector URL + // - Or the front-end couldn't be loaded through the inspector HTTP server + // - Or the web socket connection couldn't be established between the front-end and the page through the inspector server + // Let's see if this test isn't raising too many false positives, in which case we should use a better predicate if available. + + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + + g_assert(test->getPageList()); + + GOwnPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].inspectorUrl;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + + String resolvedURL = String("http://127.0.0.1:2999/") + String::fromUTF8(WebViewTest::javascriptResultToCString(javascriptResult)); + test->loadURI(resolvedURL.utf8().data()); + test->waitUntilTitleChanged(); + + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, "Web Inspector - http://127.0.0.1:2999/"); +} + + +void beforeAll() +{ + // Overwrite WEBKIT_INSPECTOR_SERVER variable with default IP address but different port to avoid conflict with the test inspector server page. + g_setenv("WEBKIT_INSPECTOR_SERVER", "127.0.0.1:2998", TRUE); + + startTestServer(); + InspectorServerTest::add("WebKitWebInspectorServer", "test-page-list", testInspectorServerPageList); + InspectorServerTest::add("WebKitWebInspectorServer", "test-remote-debugging-message", testRemoteDebuggingMessage); + InspectorServerTest::add("WebKitWebInspectorServer", "test-open-debugging-session", openRemoteDebuggingSession); + +} + +void afterAll() +{ + stopTestServer(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp index 55350e6c2..08cdbe82a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp @@ -93,7 +93,8 @@ public: class WindowProperties { public: WindowProperties() - : m_toolbarVisible(true) + : m_isNull(true) + , m_toolbarVisible(true) , m_statusbarVisible(true) , m_scrollbarsVisible(true) , m_menubarVisible(true) @@ -105,7 +106,8 @@ public: } WindowProperties(WebKitWindowProperties* windowProperties) - : m_toolbarVisible(webkit_window_properties_get_toolbar_visible(windowProperties)) + : m_isNull(false) + , m_toolbarVisible(webkit_window_properties_get_toolbar_visible(windowProperties)) , m_statusbarVisible(webkit_window_properties_get_statusbar_visible(windowProperties)) , m_scrollbarsVisible(webkit_window_properties_get_scrollbars_visible(windowProperties)) , m_menubarVisible(webkit_window_properties_get_menubar_visible(windowProperties)) @@ -118,7 +120,8 @@ public: WindowProperties(GdkRectangle* geometry, bool toolbarVisible, bool statusbarVisible, bool scrollbarsVisible, bool menubarVisible, bool locationbarVisible, bool resizable, bool fullscreen) - : m_geometry(*geometry) + : m_isNull(false) + , m_geometry(*geometry) , m_toolbarVisible(toolbarVisible) , m_statusbarVisible(statusbarVisible) , m_scrollbarsVisible(scrollbarsVisible) @@ -129,10 +132,12 @@ public: { } + bool isNull() const { return m_isNull; } + void assertEqual(const WindowProperties& other) const { - // FIXME: We should assert x and y are equal, but we are getting an incorrect - // value from WebCore (280 instead of 150). + g_assert_cmpint(m_geometry.x, ==, other.m_geometry.x); + g_assert_cmpint(m_geometry.y, ==, other.m_geometry.y); g_assert_cmpint(m_geometry.width, ==, other.m_geometry.width); g_assert_cmpint(m_geometry.height, ==, other.m_geometry.height); g_assert_cmpint(static_cast<int>(m_toolbarVisible), ==, static_cast<int>(other.m_toolbarVisible)); @@ -145,6 +150,8 @@ public: } private: + bool m_isNull; + GdkRectangle m_geometry; bool m_toolbarVisible; @@ -312,7 +319,8 @@ public: WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(webView); g_assert(windowProperties); - WindowProperties(windowProperties).assertEqual(m_windowProperties); + if (!m_windowProperties.isNull()) + WindowProperties(windowProperties).assertEqual(m_windowProperties); m_webViewEvents.append(ReadyToShow); } |