1/*
2 * Copyright (C) 2015 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 Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2,1 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
22#include "WebViewTest.h"
23
24class ConsoleMessageTest : public WebViewTest {
25public:
26 MAKE_GLIB_TEST_FIXTURE(ConsoleMessageTest);
27
28 // This should be keep in sync with the public enums in WebKitConsoleMessage.h.
29 enum class MessageSource { JavaScript, Network, ConsoleAPI, Security, Other };
30 enum class MessageLevel { Info, Log, Warning, Error, Debug };
31 struct ConsoleMessage {
32 bool operator==(const ConsoleMessage& other)
33 {
34 return source == other.source
35 && level == other.level
36 && message == other.message
37 && lineNumber == other.lineNumber
38 && sourceID == other.sourceID;
39 }
40
41 MessageSource source;
42 MessageLevel level;
43 CString message;
44 unsigned lineNumber;
45 CString sourceID;
46 };
47
48 static void consoleMessageReceivedCallback(WebKitUserContentManager*, WebKitJavascriptResult* message, ConsoleMessageTest* test)
49 {
50 g_assert_nonnull(message);
51 GUniquePtr<char> messageString(WebViewTest::javascriptResultToCString(message));
52 GRefPtr<GVariant> variant = g_variant_parse(G_VARIANT_TYPE("(uusus)"), messageString.get(), nullptr, nullptr, nullptr);
53 g_assert_nonnull(variant.get());
54
55 unsigned source, level, lineNumber;
56 const char* messageText;
57 const char* sourceID;
58 g_variant_get(variant.get(), "(uu&su&s)", &source, &level, &messageText, &lineNumber, &sourceID);
59 test->m_consoleMessage = { static_cast<ConsoleMessageTest::MessageSource>(source), static_cast<ConsoleMessageTest::MessageLevel>(level), messageText, lineNumber, sourceID };
60
61 g_main_loop_quit(test->m_mainLoop);
62 }
63
64 ConsoleMessageTest()
65 {
66 webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), "console");
67 g_signal_connect(m_userContentManager.get(), "script-message-received::console", G_CALLBACK(consoleMessageReceivedCallback), this);
68 }
69
70 ~ConsoleMessageTest()
71 {
72 g_signal_handlers_disconnect_matched(m_userContentManager.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
73 webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), "console");
74 }
75
76 void waitUntilConsoleMessageReceived()
77 {
78 g_main_loop_run(m_mainLoop);
79 }
80
81 ConsoleMessage m_consoleMessage;
82};
83
84static void testWebKitConsoleMessageConsoleAPI(ConsoleMessageTest* test, gconstpointer)
85{
86 ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::ConsoleAPI, ConsoleMessageTest::MessageLevel::Log, "Log Console Message", 1, "http://foo.com/bar" };
87 test->loadHtml("<html><body onload='console.log(\"Log Console Message\");'></body></html>", "http://foo.com/bar");
88 test->waitUntilConsoleMessageReceived();
89 g_assert_true(test->m_consoleMessage == referenceMessage);
90
91 referenceMessage.level = ConsoleMessageTest::MessageLevel::Info;
92 referenceMessage.message = "Info Console Message";
93 test->loadHtml("<html><body onload='console.info(\"Info Console Message\");'></body></html>", "http://foo.com/bar");
94 test->waitUntilConsoleMessageReceived();
95 g_assert_true(test->m_consoleMessage == referenceMessage);
96
97 referenceMessage.level = ConsoleMessageTest::MessageLevel::Warning;
98 referenceMessage.message = "Warning Console Message";
99 test->loadHtml("<html><body onload='console.warn(\"Warning Console Message\");'></body></html>", "http://foo.com/bar");
100 test->waitUntilConsoleMessageReceived();
101 g_assert_true(test->m_consoleMessage == referenceMessage);
102
103 referenceMessage.level = ConsoleMessageTest::MessageLevel::Error;
104 referenceMessage.message = "Error Console Message";
105 test->loadHtml("<html><body onload='console.error(\"Error Console Message\");'></body></html>", "http://foo.com/bar");
106 test->waitUntilConsoleMessageReceived();
107 g_assert_true(test->m_consoleMessage == referenceMessage);
108
109 referenceMessage.level = ConsoleMessageTest::MessageLevel::Debug;
110 referenceMessage.message = "Debug Console Message";
111 test->loadHtml("<html><body onload='console.debug(\"Debug Console Message\");'></body></html>", "http://foo.com/bar");
112 test->waitUntilConsoleMessageReceived();
113 g_assert_true(test->m_consoleMessage == referenceMessage);
114}
115
116static void testWebKitConsoleMessageJavaScriptException(ConsoleMessageTest* test, gconstpointer)
117{
118 ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::JavaScript, ConsoleMessageTest::MessageLevel::Error,
119 "ReferenceError: Can't find variable: foo", 1, "http://foo.com/bar" };
120 test->loadHtml("<html><body onload='foo()'></body></html>", "http://foo.com/bar");
121 test->waitUntilConsoleMessageReceived();
122 g_assert_true(test->m_consoleMessage == referenceMessage);
123}
124
125static void testWebKitConsoleMessageNetworkError(ConsoleMessageTest* test, gconstpointer)
126{
127 ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::Network, ConsoleMessageTest::MessageLevel::Error,
128 "Failed to load resource: The resource at “/org/webkit/glib/tests/not-found.css” does not exist", 0, "resource:///org/webkit/glib/tests/not-found.css" };
129 test->loadHtml("<html><head><link rel='stylesheet' href='not-found.css' type='text/css'></head><body></body></html>", "resource:///org/webkit/glib/tests/");
130 test->waitUntilConsoleMessageReceived();
131 g_assert_true(test->m_consoleMessage == referenceMessage);
132}
133
134static void testWebKitConsoleMessageSecurityError(ConsoleMessageTest* test, gconstpointer)
135{
136 ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::Security, ConsoleMessageTest::MessageLevel::Error,
137 "Not allowed to load local resource: file:///foo/bar/source.png", 1, "http://foo.com/bar" };
138 test->loadHtml("<html><body><img src=\"file:///foo/bar/source.png\"/></body></html>", "http://foo.com/bar");
139 test->waitUntilConsoleMessageReceived();
140 g_assert_true(test->m_consoleMessage == referenceMessage);
141}
142
143void beforeAll()
144{
145 ConsoleMessageTest::add("WebKitConsoleMessage", "console-api", testWebKitConsoleMessageConsoleAPI);
146 ConsoleMessageTest::add("WebKitConsoleMessage", "js-exception", testWebKitConsoleMessageJavaScriptException);
147 ConsoleMessageTest::add("WebKitConsoleMessage", "network-error", testWebKitConsoleMessageNetworkError);
148 ConsoleMessageTest::add("WebKitConsoleMessage", "security-error", testWebKitConsoleMessageSecurityError);
149}
150
151void afterAll()
152{
153}
154