| /* |
| * Copyright (C) 2017 Igalia S.L. |
| * 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/glib/GRefPtr.h> |
| #include <wtf/text/WTFString.h> |
| |
| static GPid gChildProcessPid; |
| static bool gServerIsReady; |
| |
| 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 void connectToInspectorServer(GMainLoop* mainLoop) |
| { |
| g_dbus_connection_new_for_address("tcp:host=127.0.0.1,port=2999", G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, nullptr, nullptr, |
| [](GObject* , GAsyncResult* result, gpointer userData) { |
| auto* mainLoop = static_cast<GMainLoop*>(userData); |
| GUniqueOutPtr<GError> error; |
| GRefPtr<GDBusConnection> connection = adoptGRef(g_dbus_connection_new_for_address_finish(result, &error.outPtr())); |
| if (!connection) { |
| if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED)) { |
| g_timeout_add(100, [](gpointer userData) { |
| connectToInspectorServer(static_cast<GMainLoop*>(userData)); |
| return G_SOURCE_REMOVE; |
| }, userData); |
| return; |
| } |
| |
| g_printerr("Failed to connect to inspector server"); |
| g_assert_not_reached(); |
| } |
| gServerIsReady = true; |
| g_main_loop_quit(mainLoop); |
| }, mainLoop); |
| } |
| |
| static void waitUntilInspectorServerIsReady() |
| { |
| GRefPtr<GMainLoop> mainLoop = adoptGRef(g_main_loop_new(nullptr, FALSE)); |
| unsigned timeoutID = g_timeout_add(25000, [](gpointer userData) { |
| g_main_loop_quit(static_cast<GMainLoop*>(userData)); |
| return G_SOURCE_REMOVE; |
| }, mainLoop.get()); |
| connectToInspectorServer(mainLoop.get()); |
| g_main_loop_run(mainLoop.get()); |
| if (gServerIsReady) |
| g_source_remove(timeoutID); |
| } |
| |
| static void startTestServer() |
| { |
| // Prepare argv[] for spawning the server process. |
| GUniquePtr<char> testServerPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", "InspectorTestServer", nullptr)); |
| |
| // 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] = nullptr; |
| |
| g_assert(g_spawn_async(nullptr, testServerArgv, nullptr, G_SPAWN_DEFAULT, nullptr, nullptr, &gChildProcessPid, nullptr)); |
| |
| waitUntilInspectorServerIsReady(); |
| if (!gServerIsReady) |
| stopTestServer(); |
| } |
| |
| class InspectorServerTest: public WebViewTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE(InspectorServerTest); |
| |
| bool getPageList() |
| { |
| loadURI("inspector://127.0.0.1:2999"); |
| waitUntilLoadFinished(); |
| for (unsigned i = 0; i < 5; ++i) { |
| size_t mainResourceDataSize = 0; |
| const char* mainResourceData = this->mainResourceData(mainResourceDataSize); |
| g_assert(mainResourceData); |
| if (g_strrstr_len(mainResourceData, mainResourceDataSize, "No targets found")) |
| wait(0.1); |
| else if (g_strrstr_len(mainResourceData, mainResourceDataSize, "Inspectable targets")) |
| return true; |
| } |
| |
| return false; |
| } |
| }; |
| |
| // Test to get inspector server page list from the test server. |
| // Should contain only one entry pointing to http://127.0.0.1:2999. |
| static void testInspectorServerPageList(InspectorServerTest* test, gconstpointer) |
| { |
| GUniqueOutPtr<GError> error; |
| |
| test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); |
| g_assert(test->getPageList()); |
| |
| WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByClassName('targetname').length;", &error.outPtr()); |
| g_assert(javascriptResult); |
| g_assert(!error.get()); |
| g_assert_cmpint(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 1); |
| |
| GUniquePtr<char> valueString; |
| javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByClassName('targeturl')[0].innerText;", &error.outPtr()); |
| g_assert(javascriptResult); |
| g_assert(!error.get()); |
| valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); |
| g_assert_cmpstr(valueString.get(), ==, "http://127.0.0.1:2999/"); |
| } |
| |
| void beforeAll() |
| { |
| startTestServer(); |
| InspectorServerTest::add("WebKitWebInspectorServer", "test-page-list", testInspectorServerPageList); |
| } |
| |
| void afterAll() |
| { |
| stopTestServer(); |
| } |