Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2010 Igalia S.L.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "test_utils.h"
     21 
     22 #include <glib.h>
     23 #include <glib/gstdio.h>
     24 #include <gtk/gtk.h>
     25 #include <webkit/webkit.h>
     26 
     27 #if GTK_CHECK_VERSION(2, 14, 0)
     28 
     29 #define HTML_DOCUMENT "<html><head><title>This is the title</title></head><body><p id='test'>test</p></body></html>"
     30 
     31 typedef struct {
     32     GtkWidget* webView;
     33     GtkWidget* window;
     34     WebKitDOMDOMWindow* domWindow;
     35     GMainLoop* loop;
     36 
     37     gboolean loaded;
     38     gboolean clicked;
     39     gconstpointer data;
     40 } DomDomviewFixture;
     41 
     42 static gboolean finish_loading(DomDomviewFixture* fixture)
     43 {
     44     if (g_main_loop_is_running(fixture->loop))
     45         g_main_loop_quit(fixture->loop);
     46 
     47     return FALSE;
     48 }
     49 
     50 static void dom_domview_fixture_setup(DomDomviewFixture* fixture, gconstpointer data)
     51 {
     52     fixture->loop = g_main_loop_new(NULL, TRUE);
     53     fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     54     fixture->webView = webkit_web_view_new();
     55     fixture->data = data;
     56 
     57     gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView));
     58 }
     59 
     60 static void dom_domview_fixture_teardown(DomDomviewFixture* fixture, gconstpointer data)
     61 {
     62     gtk_widget_destroy(fixture->window);
     63     g_main_loop_unref(fixture->loop);
     64 }
     65 
     66 static gboolean loadedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, DomDomviewFixture* fixture)
     67 {
     68     g_assert(fixture->loaded == FALSE);
     69     fixture->loaded = TRUE;
     70 
     71     return FALSE;
     72 }
     73 
     74 static gboolean clickedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, DomDomviewFixture* fixture)
     75 {
     76     WebKitDOMEventTarget* target;
     77     gushort phase;
     78 
     79     g_assert(event);
     80     g_assert(WEBKIT_DOM_IS_EVENT(event));
     81 
     82     // We should catch this in the bubbling up phase, since we are connecting to the toplevel object
     83     phase = webkit_dom_event_get_event_phase(event);
     84     g_assert_cmpint(phase, ==, 3);
     85 
     86     target = webkit_dom_event_get_current_target(event);
     87     g_assert(target == WEBKIT_DOM_EVENT_TARGET(view));
     88 
     89     g_assert(fixture->clicked == FALSE);
     90     fixture->clicked = TRUE;
     91 
     92     finish_loading(fixture);
     93 
     94     return FALSE;
     95 }
     96 
     97 gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, DomDomviewFixture* fixture)
     98 {
     99     webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*)fixture->data, NULL, NULL, NULL);
    100 
    101     return FALSE;
    102 }
    103 
    104 static void load_event_callback(WebKitWebView* webView, GParamSpec* spec, DomDomviewFixture* fixture)
    105 {
    106     WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
    107     if (status == WEBKIT_LOAD_FINISHED) {
    108         webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(fixture->domWindow), "click", G_CALLBACK(clickedCallback), false, fixture);
    109 
    110         g_assert(fixture->clicked == FALSE);
    111         gtk_test_widget_click(GTK_WIDGET(fixture->webView), 1, 0);
    112     }
    113 
    114 }
    115 
    116 static void test_dom_domview_signals(DomDomviewFixture* fixture, gconstpointer data)
    117 {
    118     g_assert(fixture);
    119     WebKitWebView* view = (WebKitWebView*)fixture->webView;
    120     g_assert(view);
    121     WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
    122     g_assert(document);
    123     WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document);
    124     g_assert(domWindow);
    125 
    126     fixture->domWindow = domWindow;
    127 
    128     webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(fixture->domWindow), "load", G_CALLBACK(loadedCallback), false, fixture);
    129     g_signal_connect(fixture->window, "map-event", G_CALLBACK(map_event_cb), fixture);
    130     g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_event_callback), fixture);
    131 
    132     gtk_widget_show_all(fixture->window);
    133     gtk_window_present(GTK_WINDOW(fixture->window));
    134 
    135     g_main_loop_run(fixture->loop);
    136 
    137     g_assert(fixture->loaded);
    138     g_assert(fixture->clicked);
    139 }
    140 
    141 static gboolean
    142 clicked_cb(WebKitDOMEventTarget* target, WebKitDOMEvent* event, DomDomviewFixture* fixture)
    143 {
    144     g_assert(fixture->clicked == FALSE);
    145     fixture->clicked = TRUE;
    146     finish_loading(fixture);
    147     return FALSE;
    148 }
    149 
    150 static void load_status_callback(WebKitWebView* webView, GParamSpec* spec, DomDomviewFixture* fixture)
    151 {
    152     WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
    153     if (status == WEBKIT_LOAD_FINISHED) {
    154         WebKitDOMDocument* document;
    155         WebKitDOMDOMWindow* domWindow;
    156         WebKitDOMElement* element;
    157         WebKitDOMEvent* event;
    158         glong clientX, clientY;
    159 
    160         document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView));
    161         g_assert(document);
    162         domWindow = webkit_dom_document_get_default_view(document);
    163         g_assert(domWindow);
    164         fixture->domWindow = domWindow;
    165 
    166         element = webkit_dom_document_get_element_by_id(document, "test");
    167         g_assert(element);
    168         event = webkit_dom_document_create_event(document, "MouseEvent", NULL);
    169         g_assert(event);
    170         g_assert(WEBKIT_DOM_IS_EVENT(event));
    171         g_assert(WEBKIT_DOM_IS_MOUSE_EVENT(event));
    172         clientX = webkit_dom_element_get_client_left(element);
    173         clientY = webkit_dom_element_get_client_top(element);
    174         webkit_dom_mouse_event_init_mouse_event(WEBKIT_DOM_MOUSE_EVENT(event),
    175                                                 "click", TRUE, TRUE,
    176                                                 fixture->domWindow, 0, 0, 0, clientX, clientY,
    177                                                 FALSE, FALSE, FALSE, FALSE,
    178                                                 1, WEBKIT_DOM_EVENT_TARGET(element));
    179         webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(element), "click", G_CALLBACK(clicked_cb), false, fixture);
    180         g_assert(fixture->clicked == FALSE);
    181         webkit_dom_event_target_dispatch_event(WEBKIT_DOM_EVENT_TARGET(element), event, NULL);
    182     }
    183 
    184 }
    185 
    186 static void test_dom_domview_dispatch_event(DomDomviewFixture* fixture, gconstpointer data)
    187 {
    188     g_signal_connect(fixture->window, "map-event", G_CALLBACK(map_event_cb), fixture);
    189     g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_status_callback), fixture);
    190 
    191     gtk_widget_show_all(fixture->window);
    192     gtk_window_present(GTK_WINDOW(fixture->window));
    193 
    194     g_main_loop_run (fixture->loop);
    195     g_assert(fixture->clicked);
    196 }
    197 
    198 int main(int argc, char** argv)
    199 {
    200     if (!g_thread_supported())
    201         g_thread_init(NULL);
    202 
    203     gtk_test_init(&argc, &argv, NULL);
    204 
    205     g_test_bug_base("https://bugs.webkit.org/");
    206 
    207     g_test_add("/webkit/domdomview/signals",
    208                DomDomviewFixture, HTML_DOCUMENT,
    209                dom_domview_fixture_setup,
    210                test_dom_domview_signals,
    211                dom_domview_fixture_teardown);
    212 
    213     g_test_add("/webkit/domdomview/dispatch_event",
    214                DomDomviewFixture, HTML_DOCUMENT,
    215                dom_domview_fixture_setup,
    216                test_dom_domview_dispatch_event,
    217                dom_domview_fixture_teardown);
    218 
    219     return g_test_run();
    220 }
    221 
    222 #else
    223 int main(int argc, char** argv)
    224 {
    225     g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
    226     return 0;
    227 }
    228 
    229 #endif
    230