WebKit/gtk/tests/testloading.c
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009, 2010 Gustavo Noronha Silva
       
     3  * Copyright (C) 2009 Igalia S.L.
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Library General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Library General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Library General Public License
       
    16  * along with this library; see the file COPYING.LIB.  If not, write to
       
    17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    18  * Boston, MA 02110-1301, USA.
       
    19  */
       
    20 
       
    21 #include <gtk/gtk.h>
       
    22 #include <libsoup/soup.h>
       
    23 #include <string.h>
       
    24 #include <webkit/webkit.h>
       
    25 
       
    26 #if GLIB_CHECK_VERSION(2, 16, 0) && GTK_CHECK_VERSION(2, 14, 0)
       
    27 
       
    28 /* This string has to be rather big because of the cancelled test - it
       
    29  * looks like soup refuses to send or receive a too small chunk */
       
    30 #define HTML_STRING "<html><body>Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>"
       
    31 
       
    32 SoupURI* base_uri;
       
    33 
       
    34 /* For real request testing */
       
    35 static void
       
    36 server_callback(SoupServer* server, SoupMessage* msg,
       
    37                 const char* path, GHashTable* query,
       
    38                 SoupClientContext* context, gpointer data)
       
    39 {
       
    40     if (msg->method != SOUP_METHOD_GET) {
       
    41         soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
       
    42         return;
       
    43     }
       
    44 
       
    45     soup_message_set_status(msg, SOUP_STATUS_OK);
       
    46 
       
    47     if (g_str_equal(path, "/test_loading_status") || g_str_equal(path, "/test_loading_status2"))
       
    48         soup_message_body_append(msg->response_body, SOUP_MEMORY_STATIC, HTML_STRING, strlen(HTML_STRING));
       
    49     else if (g_str_equal(path, "/test_load_error")) {
       
    50         soup_message_set_status(msg, SOUP_STATUS_CANT_CONNECT);
       
    51     } else if (g_str_equal(path, "/test_loading_cancelled")) {
       
    52         soup_message_headers_set_encoding(msg->response_headers, SOUP_ENCODING_CHUNKED);
       
    53         soup_message_body_append(msg->response_body, SOUP_MEMORY_STATIC, HTML_STRING, strlen(HTML_STRING));
       
    54         soup_server_unpause_message(server, msg);
       
    55         return;
       
    56     }
       
    57 
       
    58     soup_message_body_complete(msg->response_body);
       
    59 }
       
    60 
       
    61 typedef struct {
       
    62     WebKitWebView* webView;
       
    63     GMainLoop *loop;
       
    64     gboolean has_been_provisional;
       
    65     gboolean has_been_committed;
       
    66     gboolean has_been_first_visually_non_empty_layout;
       
    67     gboolean has_been_finished;
       
    68     gboolean has_been_failed;
       
    69     gboolean has_been_load_error;
       
    70 } WebLoadingFixture;
       
    71 
       
    72 static void web_loading_fixture_setup(WebLoadingFixture* fixture, gconstpointer data)
       
    73 {
       
    74     fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
       
    75     fixture->loop = g_main_loop_new(NULL, TRUE);
       
    76     g_object_ref_sink(fixture->webView);
       
    77     fixture->has_been_provisional = FALSE;
       
    78     fixture->has_been_committed = FALSE;
       
    79     fixture->has_been_first_visually_non_empty_layout = FALSE;
       
    80     fixture->has_been_finished = FALSE;
       
    81     fixture->has_been_failed = FALSE;
       
    82     fixture->has_been_load_error = FALSE;
       
    83 }
       
    84 
       
    85 static void web_loading_fixture_teardown(WebLoadingFixture* fixture, gconstpointer data)
       
    86 {
       
    87     g_object_unref(fixture->webView);
       
    88     g_main_loop_unref(fixture->loop);
       
    89 }
       
    90 
       
    91 static char* get_uri_for_path(const char* path)
       
    92 {
       
    93     SoupURI* uri;
       
    94     char* uri_string;
       
    95 
       
    96     uri = soup_uri_new_with_base(base_uri, path);
       
    97     uri_string = soup_uri_to_string(uri, FALSE);
       
    98     soup_uri_free (uri);
       
    99 
       
   100     return uri_string;
       
   101 }
       
   102 
       
   103 static void load_finished_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebLoadingFixture* fixture)
       
   104 {
       
   105     g_assert(fixture->has_been_provisional);
       
   106     g_assert(fixture->has_been_committed);
       
   107     g_assert(fixture->has_been_first_visually_non_empty_layout);
       
   108 
       
   109     g_main_loop_quit(fixture->loop);
       
   110 }
       
   111 
       
   112 
       
   113 static void status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
       
   114 {
       
   115     WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
       
   116 
       
   117     switch (status) {
       
   118     case WEBKIT_LOAD_PROVISIONAL:
       
   119         g_assert(!fixture->has_been_provisional);
       
   120         g_assert(!fixture->has_been_committed);
       
   121         g_assert(!fixture->has_been_first_visually_non_empty_layout);
       
   122         fixture->has_been_provisional = TRUE;
       
   123         break;
       
   124     case WEBKIT_LOAD_COMMITTED:
       
   125         g_assert(fixture->has_been_provisional);
       
   126         g_assert(!fixture->has_been_committed);
       
   127         g_assert(!fixture->has_been_first_visually_non_empty_layout);
       
   128         fixture->has_been_committed = TRUE;
       
   129         break;
       
   130     case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
       
   131         g_assert(fixture->has_been_provisional);
       
   132         g_assert(fixture->has_been_committed);
       
   133         g_assert(!fixture->has_been_first_visually_non_empty_layout);
       
   134         fixture->has_been_first_visually_non_empty_layout = TRUE;
       
   135         break;
       
   136     case WEBKIT_LOAD_FINISHED:
       
   137         g_assert(fixture->has_been_provisional);
       
   138         g_assert(fixture->has_been_committed);
       
   139         g_assert(fixture->has_been_first_visually_non_empty_layout);
       
   140         break;
       
   141     default:
       
   142         g_assert_not_reached();
       
   143     }
       
   144 }
       
   145 
       
   146 static void test_loading_status(WebLoadingFixture* fixture, gconstpointer data)
       
   147 {
       
   148     char* uri_string;
       
   149 
       
   150     g_assert_cmpint(webkit_web_view_get_load_status(fixture->webView), ==, WEBKIT_LOAD_PROVISIONAL);
       
   151 
       
   152     g_object_connect(G_OBJECT(fixture->webView),
       
   153                      "signal::notify::load-status", G_CALLBACK(status_changed_cb), fixture,
       
   154                      "signal::load-finished", G_CALLBACK(load_finished_cb), fixture,
       
   155                      NULL);
       
   156 
       
   157     uri_string = get_uri_for_path("/test_loading_status");
       
   158 
       
   159     /* load_uri will trigger the navigation-policy-decision-requested
       
   160      * signal emission;
       
   161      */
       
   162     webkit_web_view_load_uri(fixture->webView, uri_string);
       
   163     g_free(uri_string);
       
   164 
       
   165     g_main_loop_run(fixture->loop);
       
   166 }
       
   167 
       
   168 static void load_error_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
       
   169 {
       
   170     WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
       
   171 
       
   172     switch(status) {
       
   173     case WEBKIT_LOAD_PROVISIONAL:
       
   174         g_assert(!fixture->has_been_provisional);
       
   175         fixture->has_been_provisional = TRUE;
       
   176         break;
       
   177     case WEBKIT_LOAD_COMMITTED:
       
   178         g_assert(!fixture->has_been_committed);
       
   179         fixture->has_been_committed = TRUE;
       
   180         break;
       
   181     case WEBKIT_LOAD_FINISHED:
       
   182         g_assert(fixture->has_been_provisional);
       
   183         g_assert(fixture->has_been_load_error);
       
   184         g_assert(fixture->has_been_failed);
       
   185         g_assert(!fixture->has_been_finished);
       
   186         fixture->has_been_finished = TRUE;
       
   187         break;
       
   188     case WEBKIT_LOAD_FAILED:
       
   189         g_assert(!fixture->has_been_failed);
       
   190         fixture->has_been_failed = TRUE;
       
   191         g_main_loop_quit(fixture->loop);
       
   192         break;
       
   193     default:
       
   194         break;
       
   195     }
       
   196 }
       
   197 
       
   198 static gboolean load_error_cb(WebKitWebView* webView, WebKitWebFrame* frame, const char* uri, GError *error, WebLoadingFixture* fixture)
       
   199 {
       
   200     g_assert(fixture->has_been_provisional);
       
   201     g_assert(!fixture->has_been_load_error);
       
   202     fixture->has_been_load_error = TRUE;
       
   203 
       
   204     return FALSE;
       
   205 }
       
   206 
       
   207 static void test_loading_error(WebLoadingFixture* fixture, gconstpointer data)
       
   208 {
       
   209     char* uri_string;
       
   210 
       
   211     g_test_bug("28842");
       
   212 
       
   213     g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_error_cb), fixture);
       
   214     g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_error_status_changed_cb), fixture);
       
   215 
       
   216     uri_string = get_uri_for_path("/test_load_error");
       
   217     webkit_web_view_load_uri(fixture->webView, uri_string);
       
   218     g_free(uri_string);
       
   219 
       
   220     g_main_loop_run(fixture->loop);
       
   221 
       
   222     g_assert(fixture->has_been_provisional);
       
   223     g_assert(!fixture->has_been_committed);
       
   224     g_assert(fixture->has_been_load_error);
       
   225     g_assert(fixture->has_been_failed);
       
   226     g_assert(!fixture->has_been_finished);
       
   227 }
       
   228 
       
   229 /* Cancelled load */
       
   230 
       
   231 static gboolean load_cancelled_cb(WebKitWebView* webView, WebKitWebFrame* frame, const char* uri, GError *error, WebLoadingFixture* fixture)
       
   232 {
       
   233     g_assert(fixture->has_been_provisional);
       
   234     g_assert(fixture->has_been_failed);
       
   235     g_assert(!fixture->has_been_load_error);
       
   236     g_assert(error->code == WEBKIT_NETWORK_ERROR_CANCELLED);
       
   237     fixture->has_been_load_error = TRUE;
       
   238 
       
   239     return TRUE;
       
   240 }
       
   241 
       
   242 static gboolean stop_load (gpointer data)
       
   243 {
       
   244     webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(data));
       
   245     return FALSE;
       
   246 }
       
   247 
       
   248 static void load_cancelled_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
       
   249 {
       
   250     WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
       
   251 
       
   252     switch(status) {
       
   253     case WEBKIT_LOAD_PROVISIONAL:
       
   254         g_assert(!fixture->has_been_provisional);
       
   255         g_assert(!fixture->has_been_failed);
       
   256         fixture->has_been_provisional = TRUE;
       
   257         break;
       
   258     case WEBKIT_LOAD_COMMITTED:
       
   259         g_idle_add (stop_load, object);
       
   260         break;
       
   261     case WEBKIT_LOAD_FAILED:
       
   262         g_assert(fixture->has_been_provisional);
       
   263         g_assert(!fixture->has_been_failed);
       
   264         g_assert(!fixture->has_been_load_error);
       
   265         fixture->has_been_failed = TRUE;
       
   266         g_main_loop_quit(fixture->loop);
       
   267         break;
       
   268     case WEBKIT_LOAD_FINISHED:
       
   269         g_assert_not_reached();
       
   270         break;
       
   271     default:
       
   272         break;
       
   273     }
       
   274 }
       
   275 
       
   276 static void test_loading_cancelled(WebLoadingFixture* fixture, gconstpointer data)
       
   277 {
       
   278     char* uri_string;
       
   279 
       
   280     g_test_bug("29644");
       
   281 
       
   282     g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_cancelled_cb), fixture);
       
   283     g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_cancelled_status_changed_cb), fixture);
       
   284 
       
   285     uri_string = get_uri_for_path("/test_loading_cancelled");
       
   286     webkit_web_view_load_uri(fixture->webView, uri_string);
       
   287     g_free(uri_string);
       
   288 
       
   289     g_main_loop_run(fixture->loop);
       
   290 }
       
   291 
       
   292 static void load_goback_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
       
   293 {
       
   294     WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
       
   295 
       
   296     switch(status) {
       
   297     case WEBKIT_LOAD_PROVISIONAL:
       
   298         g_assert(!fixture->has_been_provisional);
       
   299         fixture->has_been_provisional = TRUE;
       
   300         break;
       
   301     case WEBKIT_LOAD_COMMITTED:
       
   302         g_assert(fixture->has_been_provisional);
       
   303         fixture->has_been_committed = TRUE;
       
   304         break;
       
   305     case WEBKIT_LOAD_FAILED:
       
   306         g_assert_not_reached();
       
   307         break;
       
   308     case WEBKIT_LOAD_FINISHED:
       
   309         g_assert(fixture->has_been_provisional);
       
   310         g_assert(fixture->has_been_committed);
       
   311         fixture->has_been_finished = TRUE;
       
   312         g_main_loop_quit(fixture->loop);
       
   313         break;
       
   314     default:
       
   315         break;
       
   316     }
       
   317 }
       
   318 
       
   319 static void load_wentback_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
       
   320 {
       
   321     WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
       
   322     char* uri_string;
       
   323     char* uri_string2;
       
   324 
       
   325     uri_string = get_uri_for_path("/test_loading_status");
       
   326     uri_string2 = get_uri_for_path("/test_loading_status2");
       
   327 
       
   328     switch(status) {
       
   329     case WEBKIT_LOAD_PROVISIONAL:
       
   330         g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string2);
       
   331         break;
       
   332     case WEBKIT_LOAD_COMMITTED:
       
   333         g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string);
       
   334         break;
       
   335     case WEBKIT_LOAD_FAILED:
       
   336         g_assert_not_reached();
       
   337         break;
       
   338     case WEBKIT_LOAD_FINISHED:
       
   339         g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string);
       
   340         g_main_loop_quit(fixture->loop);
       
   341         break;
       
   342     default:
       
   343         break;
       
   344     }
       
   345 
       
   346     g_free(uri_string);
       
   347     g_free(uri_string2);
       
   348 }
       
   349 
       
   350 static void load_error_test(WebKitWebView* webview, WebKitWebFrame* frame, const char* uri, GError* error)
       
   351 {
       
   352     g_debug("Error: %s", error->message);
       
   353 }
       
   354 
       
   355 static void test_loading_goback(WebLoadingFixture* fixture, gconstpointer data)
       
   356 {
       
   357     char* uri_string;
       
   358 
       
   359     g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_goback_status_changed_cb), fixture);
       
   360 
       
   361     g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_error_test), fixture);
       
   362 
       
   363     uri_string = get_uri_for_path("/test_loading_status");
       
   364     webkit_web_view_load_uri(fixture->webView, uri_string);
       
   365     g_free(uri_string);
       
   366 
       
   367     g_main_loop_run(fixture->loop);
       
   368 
       
   369     fixture->has_been_provisional = FALSE;
       
   370     fixture->has_been_committed = FALSE;
       
   371     fixture->has_been_first_visually_non_empty_layout = FALSE;
       
   372     fixture->has_been_finished = FALSE;
       
   373     fixture->has_been_failed = FALSE;
       
   374     fixture->has_been_load_error = FALSE;
       
   375 
       
   376     uri_string = get_uri_for_path("/test_loading_status2");
       
   377     webkit_web_view_load_uri(fixture->webView, uri_string);
       
   378     g_free(uri_string);
       
   379 
       
   380     g_main_loop_run(fixture->loop);
       
   381 
       
   382     g_signal_handlers_disconnect_by_func(fixture->webView, load_goback_status_changed_cb, fixture);
       
   383 
       
   384     fixture->has_been_provisional = FALSE;
       
   385     fixture->has_been_committed = FALSE;
       
   386     fixture->has_been_first_visually_non_empty_layout = FALSE;
       
   387     fixture->has_been_finished = FALSE;
       
   388     fixture->has_been_failed = FALSE;
       
   389     fixture->has_been_load_error = FALSE;
       
   390 
       
   391     g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_wentback_status_changed_cb), fixture);
       
   392     webkit_web_view_go_back(fixture->webView);
       
   393 
       
   394     g_main_loop_run(fixture->loop);
       
   395 
       
   396     g_signal_handlers_disconnect_by_func(fixture->webView, load_wentback_status_changed_cb, fixture);
       
   397 }
       
   398 
       
   399 int main(int argc, char** argv)
       
   400 {
       
   401     SoupServer* server;
       
   402 
       
   403     g_thread_init(NULL);
       
   404     gtk_test_init(&argc, &argv, NULL);
       
   405 
       
   406     server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
       
   407     soup_server_run_async(server);
       
   408 
       
   409     soup_server_add_handler(server, NULL, server_callback, NULL, NULL);
       
   410 
       
   411     base_uri = soup_uri_new("http://127.0.0.1/");
       
   412     soup_uri_set_port(base_uri, soup_server_get_port(server));
       
   413 
       
   414     g_test_bug_base("https://bugs.webkit.org/");
       
   415     g_test_add("/webkit/loading/status",
       
   416                WebLoadingFixture, NULL,
       
   417                web_loading_fixture_setup,
       
   418                test_loading_status,
       
   419                web_loading_fixture_teardown);
       
   420     g_test_add("/webkit/loading/error",
       
   421                WebLoadingFixture, NULL,
       
   422                web_loading_fixture_setup,
       
   423                test_loading_error,
       
   424                web_loading_fixture_teardown);
       
   425     g_test_add("/webkit/loading/cancelled",
       
   426                WebLoadingFixture, NULL,
       
   427                web_loading_fixture_setup,
       
   428                test_loading_cancelled,
       
   429                web_loading_fixture_teardown);
       
   430     g_test_add("/webkit/loading/goback",
       
   431                WebLoadingFixture, NULL,
       
   432                web_loading_fixture_setup,
       
   433                test_loading_goback,
       
   434                web_loading_fixture_teardown);
       
   435     return g_test_run();
       
   436 }
       
   437 
       
   438 #else
       
   439 int main(int argc, char** argv)
       
   440 {
       
   441     g_critical("You will need at least glib-2.16.0 and gtk-2.14.0 to run the unit tests. Doing nothing now.");
       
   442     return 0;
       
   443 }
       
   444 
       
   445 #endif