1/*
2 * Copyright (C) 2011 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 "config.h"
21#include "LoadTrackingTest.h"
22
23static void loadChangedCallback(WebKitWebView* webView, WebKitLoadEvent loadEvent, LoadTrackingTest* test)
24{
25 switch (loadEvent) {
26 case WEBKIT_LOAD_STARTED:
27 g_assert_true(webkit_web_view_is_loading(webView));
28 g_assert_cmpstr(test->m_activeURI.data(), ==, webkit_web_view_get_uri(webView));
29 test->provisionalLoadStarted();
30 break;
31 case WEBKIT_LOAD_REDIRECTED:
32 g_assert_true(webkit_web_view_is_loading(webView));
33 test->m_activeURI = webkit_web_view_get_uri(webView);
34 if (!test->m_redirectURI.isNull())
35 g_assert_cmpstr(test->m_redirectURI.data(), ==, test->m_activeURI.data());
36 test->provisionalLoadReceivedServerRedirect();
37 break;
38 case WEBKIT_LOAD_COMMITTED: {
39 g_assert_true(webkit_web_view_is_loading(webView));
40 test->m_activeURI = webkit_web_view_get_uri(webView);
41
42 // Check that on committed we always have a main resource with a response.
43 WebKitWebResource* resource = webkit_web_view_get_main_resource(webView);
44 g_assert_nonnull(resource);
45 g_assert_nonnull(webkit_web_resource_get_response(resource));
46
47 test->loadCommitted();
48 break;
49 }
50 case WEBKIT_LOAD_FINISHED:
51 if (!test->m_loadFailed) {
52 g_assert_false(webkit_web_view_is_loading(webView));
53 g_assert_cmpstr(test->m_activeURI.data(), ==, webkit_web_view_get_uri(webView));
54 } else if (!g_error_matches(test->m_error.get(), WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)) {
55 // When a new load is started before the previous one has finished, we receive the load-finished signal
56 // of the ongoing load while we already have a provisional URL for the new load. This is the only case
57 // where isloading is true when the load has finished.
58 g_assert_false(webkit_web_view_is_loading(webView));
59 }
60 test->loadFinished();
61 break;
62 default:
63 g_assert_not_reached();
64 }
65}
66
67static void loadFailedCallback(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError* error, LoadTrackingTest* test)
68{
69 test->m_loadFailed = true;
70
71 g_assert_nonnull(error);
72 test->m_error.reset(g_error_copy(error));
73
74 if (!g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)) {
75 // When a new load is started before the previous one has finished, we receive the load-failed signal
76 // of the ongoing load while we already have a provisional URL for the new load. This is the only case
77 // where is-loading is true when the load has failed.
78 g_assert_false(webkit_web_view_is_loading(webView));
79 }
80
81 switch (loadEvent) {
82 case WEBKIT_LOAD_STARTED:
83 g_assert_cmpstr(test->m_activeURI.data(), ==, failingURI);
84 test->provisionalLoadFailed(failingURI, error);
85 break;
86 case WEBKIT_LOAD_COMMITTED:
87 g_assert_cmpstr(test->m_activeURI.data(), ==, webkit_web_view_get_uri(webView));
88 test->loadFailed(failingURI, error);
89 break;
90 default:
91 g_assert_not_reached();
92 }
93}
94
95static gboolean loadFailedWithTLSErrorsCallback(WebKitWebView* webView, const char* failingURI, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors, LoadTrackingTest* test)
96{
97 test->m_loadFailed = true;
98 g_assert_false(webkit_web_view_is_loading(webView));
99 g_assert_cmpstr(test->m_activeURI.data(), ==, failingURI);
100 g_assert_true(G_IS_TLS_CERTIFICATE(certificate));
101 g_assert_cmpuint(tlsErrors, !=, 0);
102 return test->loadFailedWithTLSErrors(failingURI, certificate, tlsErrors);
103}
104
105static void estimatedProgressChangedCallback(GObject*, GParamSpec*, LoadTrackingTest* test)
106{
107 test->estimatedProgressChanged();
108}
109
110LoadTrackingTest::LoadTrackingTest()
111 : m_runLoadUntilCompletion(false)
112 , m_loadFailed(false)
113{
114 g_signal_connect(m_webView, "load-changed", G_CALLBACK(loadChangedCallback), this);
115 g_signal_connect(m_webView, "load-failed", G_CALLBACK(loadFailedCallback), this);
116 g_signal_connect(m_webView, "load-failed-with-tls-errors", G_CALLBACK(loadFailedWithTLSErrorsCallback), this);
117 g_signal_connect(m_webView, "notify::estimated-load-progress", G_CALLBACK(estimatedProgressChangedCallback), this);
118
119 g_assert_null(webkit_web_view_get_uri(m_webView));
120}
121
122LoadTrackingTest::~LoadTrackingTest()
123{
124 g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
125}
126
127void LoadTrackingTest::waitUntilLoadFinished()
128{
129 m_estimatedProgress = 0;
130 m_runLoadUntilCompletion = true;
131 g_main_loop_run(m_mainLoop);
132}
133
134void LoadTrackingTest::provisionalLoadStarted()
135{
136 m_loadEvents.append(ProvisionalLoadStarted);
137}
138
139void LoadTrackingTest::provisionalLoadReceivedServerRedirect()
140{
141 m_loadEvents.append(ProvisionalLoadReceivedServerRedirect);
142}
143
144void LoadTrackingTest::provisionalLoadFailed(const gchar* failingURI, GError* error)
145{
146 m_loadEvents.append(ProvisionalLoadFailed);
147}
148
149void LoadTrackingTest::loadCommitted()
150{
151 m_loadEvents.append(LoadCommitted);
152}
153
154void LoadTrackingTest::loadFinished()
155{
156 m_loadEvents.append(LoadFinished);
157 if (m_runLoadUntilCompletion)
158 g_main_loop_quit(m_mainLoop);
159}
160
161void LoadTrackingTest::loadFailed(const gchar* failingURI, GError* error)
162{
163 m_loadEvents.append(LoadFailed);
164}
165
166bool LoadTrackingTest::loadFailedWithTLSErrors(const gchar* /*failingURI*/, GTlsCertificate*, GTlsCertificateFlags)
167{
168 m_loadEvents.append(LoadFailedWithTLSErrors);
169 return false;
170}
171
172void LoadTrackingTest::estimatedProgressChanged()
173{
174 double progress = webkit_web_view_get_estimated_load_progress(m_webView);
175 g_assert_cmpfloat(m_estimatedProgress, <, progress);
176 m_estimatedProgress = progress;
177}
178
179void LoadTrackingTest::loadURI(const char* uri)
180{
181 reset();
182 WebViewTest::loadURI(uri);
183}
184
185void LoadTrackingTest::loadHtml(const char* html, const char* baseURI)
186{
187 reset();
188 WebViewTest::loadHtml(html, baseURI);
189}
190
191void LoadTrackingTest::loadPlainText(const char* plainText)
192{
193 reset();
194 WebViewTest::loadPlainText(plainText);
195}
196
197void LoadTrackingTest::loadBytes(GBytes* bytes, const char* mimeType, const char* encoding, const char* baseURI)
198{
199 reset();
200 WebViewTest::loadBytes(bytes, mimeType, encoding, baseURI);
201}
202
203void LoadTrackingTest::loadRequest(WebKitURIRequest* request)
204{
205 reset();
206 WebViewTest::loadRequest(request);
207}
208
209void LoadTrackingTest::reload()
210{
211 reset();
212 webkit_web_view_reload(m_webView);
213}
214
215void LoadTrackingTest::goBack()
216{
217 reset();
218 WebViewTest::goBack();
219}
220
221void LoadTrackingTest::goForward()
222{
223 reset();
224 WebViewTest::goForward();
225}
226
227void LoadTrackingTest::reset()
228{
229 m_runLoadUntilCompletion = false;
230 m_loadFailed = false;
231 m_loadEvents.clear();
232 m_estimatedProgress = 0;
233 m_error.reset();
234}
235