/*
 * Copyright (C) 2017 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"

#include "TestMain.h"
#include "WebViewTest.h"
#include <wtf/glib/GUniquePtr.h>

#if PLATFORM(GTK)
#include <WebKit/GtkVersioning.h>
#if USE(GTK4)
#include <webkit/WebKitWebViewBaseInternal.h>
using PlatformEventKey = GdkEvent;
#else
using PlatformEventKey = GdkEventKey;
#endif
#elif PLATFORM(WPE)
using PlatformEventKey = void;
#endif

typedef struct _WebKitInputMethodContextMock {
    WebKitInputMethodContext parent;

    bool enabled;
    GString* preedit;
    bool commitNextCharacter;
    char* surroundingText;
    unsigned surroundingCursorIndex;
    unsigned surroundingSelectionIndex;
#if ENABLE(WPE_PLATFORM)
    bool usingWPEPlatformAPI;
#endif
} WebKitInputMethodContextMock;

typedef struct _WebKitInputMethodContextMockClass {
    WebKitInputMethodContextClass parent;
} WebKitInputMethodContextMockClass;

G_DEFINE_TYPE(WebKitInputMethodContextMock, webkit_input_method_context_mock, WEBKIT_TYPE_INPUT_METHOD_CONTEXT)

static const char* testHTML = "<html><body><textarea id='editable' rows='3', cols='50' onkeydown='logKeyDown()' onkeyup='logKeyUp()' onkeypress='logKeyPress()'></textarea><script>"
    "var input = document.getElementById('editable');"
    "input.addEventListener('compositionstart', logCompositionEvent);"
    "input.addEventListener('compositionupdate', logCompositionEvent);"
    "input.addEventListener('compositionend', logCompositionEvent);"
    "function logCompositionEvent(event) { window.webkit.messageHandlers.imEvent.postMessage({ 'type' : event.type, 'data' : event.data }) }"
    "function logKeyDown() { window.webkit.messageHandlers.imEvent.postMessage({ 'type' : 'keyDown', 'keyCode' : event.keyCode, 'key' : event.key, 'isComposing' : event.isComposing }) }"
    "function logKeyUp() { window.webkit.messageHandlers.imEvent.postMessage({ 'type' : 'keyUp', 'keyCode' : event.keyCode, 'key' : event.key, 'isComposing' : event.isComposing }) }"
    "function logKeyPress() { window.webkit.messageHandlers.imEvent.postMessage({ 'type' : 'keyPress', 'keyCode' : event.keyCode }) }"
    "</script></body></html>";

static void webkitInputMethodContextMockFinalize(GObject* object)
{
    auto* mock = reinterpret_cast<WebKitInputMethodContextMock*>(object);
    if (mock->preedit) {
        g_string_free(mock->preedit, TRUE);
        mock->preedit = nullptr;
    }
    g_clear_pointer(&mock->surroundingText, g_free);
    G_OBJECT_CLASS(webkit_input_method_context_mock_parent_class)->finalize(object);
}

static void webkitInputMethodContextMockGetPreedit(WebKitInputMethodContext* context, char** text, GList** underlines, guint* cursorOffset)
{
    auto* mock = reinterpret_cast<WebKitInputMethodContextMock*>(context);
    if (text)
        *text = mock->preedit ? g_strdup(mock->preedit->str) : g_strdup("");
    if (underlines)
        *underlines = mock->preedit ? g_list_prepend(*underlines, webkit_input_method_underline_new(0, mock->preedit->len)) : nullptr;
    if (cursorOffset)
        *cursorOffset = mock->preedit ? mock->preedit->len : 0;
}

static gboolean webkitInputMethodContextMockFilterKeyEvent(WebKitInputMethodContext* context, PlatformEventKey* keyEvent)
{
    auto* mock = reinterpret_cast<WebKitInputMethodContextMock*>(context);
    if (!mock->enabled)
        return FALSE;

#if PLATFORM(GTK)
#if USE(GTK4)
    auto* event = reinterpret_cast<KeyEvent*>(keyEvent);
    unsigned keyval = event->keyval;
    auto state = static_cast<GdkModifierType>(event->modifiers);
    bool isKeyPress = event->type == GDK_KEY_PRESS;
#else
    GdkModifierType state;
    guint keyval;
    if (!gdk_event_get_state(reinterpret_cast<GdkEvent*>(keyEvent), &state) || !gdk_event_get_keyval(reinterpret_cast<GdkEvent*>(keyEvent), &keyval))
        return FALSE;
    bool isKeyPress = gdk_event_get_event_type(reinterpret_cast<GdkEvent*>(keyEvent)) == GDK_KEY_PRESS;
#endif
    gunichar character = gdk_keyval_to_unicode(keyval);
    bool isControl = state & GDK_CONTROL_MASK;
    bool isShift = state & GDK_SHIFT_MASK;
#elif PLATFORM(WPE)
    uint32_t keyval = 0;
    bool isKeyPress = false;
    gunichar character = 0;
    bool isControl = false;
    bool isShift = false;
#if ENABLE(WPE_PLATFORM)
    if (mock->usingWPEPlatformAPI) {
        auto* wpeKeyEvent = static_cast<WPEEvent*>(keyEvent);
        keyval = wpe_event_keyboard_get_keyval(wpeKeyEvent);
        isKeyPress = wpe_event_get_event_type(wpeKeyEvent) == WPE_EVENT_KEYBOARD_KEY_DOWN;
        character = wpe_keyval_to_unicode(keyval);
        auto state = wpe_event_get_modifiers(wpeKeyEvent);
        isControl = state & WPE_MODIFIER_KEYBOARD_CONTROL;
        isShift = state & WPE_MODIFIER_KEYBOARD_SHIFT;
    } else
#endif
    {
#if USE(LIBWPE)
        struct wpe_input_keyboard_event* wpeKeyEvent = static_cast<struct wpe_input_keyboard_event*>(keyEvent);
        keyval = wpeKeyEvent->key_code;
        isKeyPress = wpeKeyEvent->pressed;
        character = wpe_key_code_to_unicode(keyval);
        isControl = wpeKeyEvent->modifiers & wpe_input_keyboard_modifier_control;
        isShift = wpeKeyEvent->modifiers & wpe_input_keyboard_modifier_shift;
#endif
    }
#endif
    bool isComposeEnd = (keyval == KEY(space) || keyval == KEY(Return) || keyval == KEY(ISO_Enter));

    if (isKeyPress && mock->commitNextCharacter) {
        char buffer[6];
        auto length = g_unichar_to_utf8(character, buffer);
        buffer[length] = '\0';
        g_signal_emit_by_name(context, "committed", buffer, nullptr);
        mock->commitNextCharacter = false;

        return TRUE;
    }

    if (!mock->preedit) {
        if (isKeyPress && isControl && isShift && keyval == KEY(w)) {
            mock->preedit = g_string_new("w");
            g_signal_emit_by_name(context, "preedit-started", nullptr);
            g_signal_emit_by_name(context, "preedit-changed", nullptr);

            return TRUE;
        }

        return FALSE;
    }

    if (keyval == KEY(Escape)) {
        g_string_free(mock->preedit, TRUE);
        mock->preedit = nullptr;
        g_signal_emit_by_name(context, "preedit-changed", nullptr);
        g_signal_emit_by_name(context, "preedit-finished", nullptr);

        return TRUE;
    }

    if (isComposeEnd) {
        if (!g_strcmp0(mock->preedit->str, "wgtk"))
            g_signal_emit_by_name(context, "committed", "WebKitGTK", nullptr);
        else if (!g_strcmp0(mock->preedit->str, "wwpe"))
            g_signal_emit_by_name(context, "committed", "WPEWebKit", nullptr);
        else
            g_signal_emit_by_name(context, "committed", mock->preedit->str + 1, nullptr);

        g_string_free(mock->preedit, TRUE);
        mock->preedit = nullptr;
        g_signal_emit_by_name(context, "preedit-changed", nullptr);
        g_signal_emit_by_name(context, "preedit-finished", nullptr);

        return TRUE;
    }

    if (isKeyPress) {
        g_string_append_unichar(mock->preedit, character);
        g_signal_emit_by_name(context, "preedit-changed", nullptr);

        return TRUE;
    }

    return FALSE;
}

static void webkitInputMethodContextMockNotifyFocusIn(WebKitInputMethodContext* context)
{
    reinterpret_cast<WebKitInputMethodContextMock*>(context)->enabled = true;
}

static void webkitInputMethodContextMockNotifyFocusOut(WebKitInputMethodContext* context)
{
    reinterpret_cast<WebKitInputMethodContextMock*>(context)->enabled = false;
}

static void webkitInputMethodContextMockNotifySurrounding(WebKitInputMethodContext* context, const gchar *text, unsigned length, unsigned cursorIndex, unsigned selectionIndex)
{
    auto* mock = reinterpret_cast<WebKitInputMethodContextMock*>(context);
    g_clear_pointer(&mock->surroundingText, g_free);

    if (!mock->preedit && cursorIndex >= 3 && text[cursorIndex - 3] == ':' && text[cursorIndex - 2] == '-' && text[cursorIndex - 1] == ')') {
        g_signal_emit_by_name(context, "delete-surrounding", -3, 3, nullptr);
        g_signal_emit_by_name(context, "committed", "😀️", nullptr);
    }
    mock->surroundingText = g_strndup(text, length);
    mock->surroundingCursorIndex = cursorIndex;
    mock->surroundingSelectionIndex = selectionIndex;
}

static void webkitInputMethodContextMockReset(WebKitInputMethodContext* context)
{
    auto* mock = reinterpret_cast<WebKitInputMethodContextMock*>(context);
    if (!mock->preedit)
        return;

    g_string_free(mock->preedit, TRUE);
    mock->preedit = nullptr;
    g_clear_pointer(&mock->surroundingText, g_free);
    mock->surroundingCursorIndex = 0;
    mock->surroundingSelectionIndex = 0;

    g_signal_emit_by_name(context, "preedit-changed", nullptr);
    g_signal_emit_by_name(context, "preedit-finished", nullptr);
}

#if ENABLE(WPE_PLATFORM)
static void webkitInputMethodContextMockSetInUsingWPEPlatformAPI(WebKitInputMethodContextMock* mock)
{
    mock->usingWPEPlatformAPI = true;
}
#endif

static void webkit_input_method_context_mock_class_init(WebKitInputMethodContextMockClass* klass)
{
    GObjectClass* objectClass = G_OBJECT_CLASS(klass);
    objectClass->finalize = webkitInputMethodContextMockFinalize;

    auto* imClass = WEBKIT_INPUT_METHOD_CONTEXT_CLASS(klass);
    imClass->get_preedit = webkitInputMethodContextMockGetPreedit;
    imClass->filter_key_event = webkitInputMethodContextMockFilterKeyEvent;
    imClass->notify_focus_in = webkitInputMethodContextMockNotifyFocusIn;
    imClass->notify_focus_out = webkitInputMethodContextMockNotifyFocusOut;
    imClass->notify_surrounding = webkitInputMethodContextMockNotifySurrounding;
    imClass->reset = webkitInputMethodContextMockReset;
}

static void webkit_input_method_context_mock_init(WebKitInputMethodContextMock*)
{
}

class InputMethodTest: public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(InputMethodTest);

    struct Event {
        enum class Type { KeyDown, KeyPress, KeyUp, CompositionStart, CompositionUpdate, CompositionEnd };

        explicit Event(Type type)
            : type(type)
        {
        }

        Type type;
        CString data;
        unsigned keyCode;
        CString key;
        bool isComposing;
    };

#if ENABLE(2022_GLIB_API)
    static void imEventCallback(WebKitUserContentManager*, JSCValue* result, InputMethodTest* test)
    {
        test->imEvent(result);
    }
#else
    static void imEventCallback(WebKitUserContentManager*, WebKitJavascriptResult* result, InputMethodTest* test)
    {
        test->imEvent(webkit_javascript_result_get_js_value(result));
    }
#endif

    InputMethodTest()
        : m_context(adoptGRef(static_cast<WebKitInputMethodContextMock*>(g_object_new(webkit_input_method_context_mock_get_type(), nullptr))))
    {
#if ENABLE(WPE_PLATFORM)
        if (m_display)
            webkitInputMethodContextMockSetInUsingWPEPlatformAPI(m_context.get());
#endif
        WebViewTest::showInWindow();
#if PLATFORM(GTK)
        auto* defaultContext = webkit_web_view_get_input_method_context(m_webView.get());
        g_assert_true(WEBKIT_IS_INPUT_METHOD_CONTEXT(defaultContext));
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(defaultContext));
#elif PLATFORM(WPE)
#if ENABLE(WPE_PLATFORM)
        if (m_display) {
            auto* defaultContext = webkit_web_view_get_input_method_context(m_webView.get());
            g_assert_true(WEBKIT_IS_INPUT_METHOD_CONTEXT(defaultContext));
            assertObjectIsDeletedWhenTestFinishes(G_OBJECT(defaultContext));
        } else
            g_assert_null(webkit_web_view_get_input_method_context(m_webView.get()));
#else
        g_assert_null(webkit_web_view_get_input_method_context(m_webView.get()));
#endif
#endif
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_context.get()));
        webkit_web_view_set_input_method_context(m_webView.get(), WEBKIT_INPUT_METHOD_CONTEXT(m_context.get()));
        g_assert_true(webkit_web_view_get_input_method_context(m_webView.get()) == WEBKIT_INPUT_METHOD_CONTEXT(m_context.get()));

#if !ENABLE(2022_GLIB_API)
        webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), "imEvent");
#else
        webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), "imEvent", nullptr);
#endif
        g_signal_connect(m_userContentManager.get(), "script-message-received::imEvent", G_CALLBACK(imEventCallback), this);
    }

    ~InputMethodTest()
    {
#if !ENABLE(2022_GLIB_API)
        webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), "imEvent");
#else
        webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), "imEvent", nullptr);
#endif
        g_signal_handlers_disconnect_by_data(m_userContentManager.get(), this);
    }

    void imEvent(JSCValue* jsEvent)
    {
        g_assert_true(jsc_value_is_object(jsEvent));

        GRefPtr<JSCValue> value = adoptGRef(jsc_value_object_get_property(jsEvent, "type"));
        g_assert_true(jsc_value_is_string(value.get()));
        GUniquePtr<char> strValue(jsc_value_to_string(value.get()));
        if (!g_strcmp0(strValue.get(), "keyDown")) {
            InputMethodTest::Event event(InputMethodTest::Event::Type::KeyDown);
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "keyCode"));
            g_assert_true(jsc_value_is_number(value.get()));
            event.keyCode = jsc_value_to_int32(value.get());
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "key"));
            g_assert_true(jsc_value_is_string(value.get()));
            strValue.reset(jsc_value_to_string(value.get()));
            event.key = strValue.get();
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "isComposing"));
            g_assert_true(jsc_value_is_boolean(value.get()));
            event.isComposing = jsc_value_to_boolean(value.get());
            m_events.append(WTF::move(event));
        } else if (!g_strcmp0(strValue.get(), "keyPress")) {
            InputMethodTest::Event event(InputMethodTest::Event::Type::KeyPress);
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "keyCode"));
            g_assert_true(jsc_value_is_number(value.get()));
            event.keyCode = jsc_value_to_int32(value.get());
            m_events.append(WTF::move(event));
        } else if (!g_strcmp0(strValue.get(), "keyUp")) {
            InputMethodTest::Event event(InputMethodTest::Event::Type::KeyUp);
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "keyCode"));
            g_assert_true(jsc_value_is_number(value.get()));
            event.keyCode = jsc_value_to_int32(value.get());
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "key"));
            g_assert_true(jsc_value_is_string(value.get()));
            strValue.reset(jsc_value_to_string(value.get()));
            event.key = strValue.get();
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "isComposing"));
            g_assert_true(jsc_value_is_boolean(value.get()));
            event.isComposing = jsc_value_to_boolean(value.get());
            m_events.append(WTF::move(event));
        } else if (!g_strcmp0(strValue.get(), "compositionstart")) {
            InputMethodTest::Event event(InputMethodTest::Event::Type::CompositionStart);
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "data"));
            g_assert_true(jsc_value_is_string(value.get()));
            strValue.reset(jsc_value_to_string(value.get()));
            event.data = strValue.get();
            m_events.append(WTF::move(event));
        } else if (!g_strcmp0(strValue.get(), "compositionupdate")) {
            InputMethodTest::Event event(InputMethodTest::Event::Type::CompositionUpdate);
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "data"));
            g_assert_true(jsc_value_is_string(value.get()));
            strValue.reset(jsc_value_to_string(value.get()));
            event.data = strValue.get();
            m_events.append(WTF::move(event));
        } else if (!g_strcmp0(strValue.get(), "compositionend")) {
            InputMethodTest::Event event(InputMethodTest::Event::Type::CompositionEnd);
            value = adoptGRef(jsc_value_object_get_property(jsEvent, "data"));
            g_assert_true(jsc_value_is_string(value.get()));
            strValue.reset(jsc_value_to_string(value.get()));
            event.data = strValue.get();
            m_events.append(WTF::move(event));
        }

        if (m_events.size() == m_eventsExpected)
            g_main_loop_quit(m_mainLoop);
    }

    void focusEditableAndWaitUntilInputMethodEnabled()
    {
        g_assert_false(m_context->enabled);
        runJavaScriptAndWaitUntilFinished("document.getElementById('editable').focus()", nullptr);
        if (m_context->enabled)
            return;

        g_idle_add([](gpointer userData) -> gboolean {
            auto* test = static_cast<InputMethodTest*>(userData);
            if (test->m_context->enabled) {
                test->quitMainLoop();
                return FALSE;
            }

            return TRUE;
        }, this);
        g_main_loop_run(m_mainLoop);
        g_assert_true(m_context->enabled);
    }

    void unfocusEditableAndWaitUntilInputMethodDisabled()
    {
        g_assert_true(m_context->enabled);
        runJavaScriptAndWaitUntilFinished("document.getElementById('editable').blur()", nullptr);
        if (!m_context->enabled)
            return;

        g_idle_add([](gpointer userData) -> gboolean {
            auto* test = static_cast<InputMethodTest*>(userData);
            if (!test->m_context->enabled) {
                test->quitMainLoop();
                return FALSE;
            }

            return TRUE;
        }, this);
        g_main_loop_run(m_mainLoop);
        g_assert_false(m_context->enabled);
    }

    void resetEditable()
    {
        runJavaScriptAndWaitUntilFinished("document.getElementById('editable').value = ''", nullptr);
        m_events.clear();
    }

    GUniquePtr<char> editableValue()
    {
        auto* jsResult = runJavaScriptAndWaitUntilFinished("document.getElementById('editable').value", nullptr);
        return GUniquePtr<char>(WebViewTest::javascriptResultToCString(jsResult));
    }

    void keyStrokeAndWaitForEvents(unsigned keyval, unsigned eventsCount, OptionSet<Modifiers> modifiers = OptionSet<Modifiers>())
    {
        m_eventsExpected = eventsCount;
        keyStroke(keyval, modifiers);
        g_main_loop_run(m_mainLoop);
        m_eventsExpected = 0;
    }

    void keyStrokeHandledByInputMethodAndWaitForEvents(unsigned keyval, unsigned eventsCount)
    {
        m_context->commitNextCharacter = true;
        keyStrokeAndWaitForEvents(keyval, eventsCount);
        m_context->commitNextCharacter = false;
    }

    void clickAndWaitForEvents(unsigned eventsCount)
    {
        m_eventsExpected = eventsCount;
        clickMouseButton(0, 0);
        g_main_loop_run(m_mainLoop);
        m_eventsExpected = 0;
    }

    WebKitInputPurpose purpose() const
    {
        return webkit_input_method_context_get_input_purpose(WEBKIT_INPUT_METHOD_CONTEXT(m_context.get()));
    }

    WebKitInputHints hints() const
    {
        return webkit_input_method_context_get_input_hints(WEBKIT_INPUT_METHOD_CONTEXT(m_context.get()));
    }

    const char* surroundingText() const
    {
        return m_context->surroundingText;
    }

    unsigned surroundingCursorIndex() const
    {
        return m_context->surroundingCursorIndex;
    }

    unsigned surroundingSelectionIndex() const
    {
        return m_context->surroundingSelectionIndex;
    }

    void waitForSurroundingText(const char* text)
    {
        m_expectedSurroundingText = text;
        g_idle_add([](gpointer userData) -> gboolean {
            auto* test = static_cast<InputMethodTest*>(userData);
            if (!g_strcmp0(test->m_context->surroundingText, test->m_expectedSurroundingText.data())) {
                test->quitMainLoop();
                return FALSE;
            }

            return TRUE;
        }, this);
        g_main_loop_run(m_mainLoop);
        m_expectedSurroundingText = { };
    }

    GRefPtr<WebKitInputMethodContextMock> m_context;
    Vector<Event> m_events;
    unsigned m_eventsExpected { 0 };
    CString m_expectedSurroundingText;
};

static void testWebKitInputMethodContextSimple(InputMethodTest* test, gconstpointer)
{
    test->loadHtml(testHTML, nullptr);
    test->waitUntilLoadFinished();

    test->focusEditableAndWaitUntilInputMethodEnabled();

    // Send a normal character not handled by IM.
    test->keyStrokeAndWaitForEvents(KEY(a), 3);
    g_assert_cmpuint(test->m_events.size(), ==, 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 65);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "a");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::KeyPress);
    g_assert_cmpuint(test->m_events[1].keyCode, ==, 97);
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 65);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "a");
    g_assert_false(test->m_events[2].isComposing);
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "a");
    }
    test->resetEditable();

    // Send a normal character handled by IM.
    test->keyStrokeHandledByInputMethodAndWaitForEvents(KEY(a), 3);
    g_assert_cmpuint(test->m_events.size(), ==, 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 65);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "a");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::KeyPress);
    g_assert_cmpuint(test->m_events[1].keyCode, ==, 97);
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 65);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "a");
    g_assert_false(test->m_events[2].isComposing);
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "a");
    }
    test->resetEditable();
}

static void testWebKitInputMethodContextSequence(InputMethodTest* test, gconstpointer)
{
    test->loadHtml(testHTML, nullptr);
    test->waitUntilLoadFinished();

    test->focusEditableAndWaitUntilInputMethodEnabled();

    // Compose w + gtk + Enter.
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionStart);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[2].data.data(), ==, "w");
    g_assert_true(test->m_events[3].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[3].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[3].key.data(), ==, "w");
    g_assert_true(test->m_events[3].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(g), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "wg");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 71);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "g");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(t), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "wgt");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 84);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "t");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(k), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "wgtk");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 75);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "k");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(ISO_Enter), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionEnd);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "WebKitGTK");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 13);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "Enter");
    g_assert_false(test->m_events[2].isComposing);
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "WebKitGTK");
    }
    test->resetEditable();

    // Compose w + wpe + Space.
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionStart);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[2].data.data(), ==, "w");
    g_assert_true(test->m_events[3].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[3].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[3].key.data(), ==, "w");
    g_assert_true(test->m_events[3].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(w), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "ww");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "w");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(p), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "wwp");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 80);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "p");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(e), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "wwpe");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 69);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "e");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(space), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionEnd);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "WPEWebKit");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 32);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, " ");
    g_assert_false(test->m_events[2].isComposing);
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "WPEWebKit");
    }
    test->resetEditable();
}

static void testWebKitInputMethodContextInvalidSequence(InputMethodTest* test, gconstpointer)
{
    test->loadHtml(testHTML, nullptr);
    test->waitUntilLoadFinished();

    test->focusEditableAndWaitUntilInputMethodEnabled();

    // Compose w + w + Space -> invalid sequence.
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionStart);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[2].data.data(), ==, "w");
    g_assert_true(test->m_events[3].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[3].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[3].key.data(), ==, "w");
    g_assert_true(test->m_events[3].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(w), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "ww");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "w");
    g_assert_true(test->m_events[2].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(space), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionEnd);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "w");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 32);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, " ");
    g_assert_false(test->m_events[2].isComposing);
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "w");
    }
    test->resetEditable();
}

static void testWebKitInputMethodContextCancelSequence(InputMethodTest* test, gconstpointer)
{
    test->loadHtml(testHTML, nullptr);
    test->waitUntilLoadFinished();

    test->focusEditableAndWaitUntilInputMethodEnabled();

    // Compose w + w + Escape -> cancel sequence.
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionStart);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[2].data.data(), ==, "w");
    g_assert_true(test->m_events[3].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[3].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[3].key.data(), ==, "w");
    g_assert_true(test->m_events[3].isComposing);
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(Escape), 3);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_true(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionEnd);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[2].keyCode, ==, 27);
    g_assert_cmpstr(test->m_events[2].key.data(), ==, "Escape");
    g_assert_false(test->m_events[2].isComposing);
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "");
    }
    test->resetEditable();
}

static void testWebKitInputMethodContextSurrounding(InputMethodTest* test, gconstpointer)
{
    test->loadHtml(testHTML, nullptr);
    test->waitUntilLoadFinished();

    test->focusEditableAndWaitUntilInputMethodEnabled();

    g_assert_null(test->surroundingText());
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());

    test->keyStrokeAndWaitForEvents(KEY(a), 3);
    test->keyStrokeAndWaitForEvents(KEY(b), 6);
    test->keyStrokeAndWaitForEvents(KEY(c), 9);
    g_assert_cmpstr(test->surroundingText(), ==, "abc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 3);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();

    // Check preedit string is not included in surrounding.
    // 1. Preedit string at the beginning of context.
    test->keyStrokeAndWaitForEvents(KEY(Left), 2);
    test->keyStrokeAndWaitForEvents(KEY(Left), 4);
    test->keyStrokeAndWaitForEvents(KEY(Left), 6);
    g_assert_cmpstr(test->surroundingText(), ==, "abc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_cmpstr(test->surroundingText(), ==, "abc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->keyStrokeAndWaitForEvents(KEY(g), 7);
    test->keyStrokeAndWaitForEvents(KEY(t), 10);
    test->keyStrokeAndWaitForEvents(KEY(k), 13);
    g_assert_cmpstr(test->surroundingText(), ==, "abc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->keyStrokeAndWaitForEvents(KEY(ISO_Enter), 16);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 9);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();
    // 2. Preedit string in the middle of context.
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 9);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->keyStrokeAndWaitForEvents(KEY(w), 7);
    test->keyStrokeAndWaitForEvents(KEY(p), 10);
    test->keyStrokeAndWaitForEvents(KEY(e), 13);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 9);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->keyStrokeAndWaitForEvents(KEY(space), 16);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 18);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();
    // 3. Preedit string at the end of context.
    test->keyStrokeAndWaitForEvents(KEY(Right), 2);
    test->keyStrokeAndWaitForEvents(KEY(Right), 4);
    test->keyStrokeAndWaitForEvents(KEY(Right), 6);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 21);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 21);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->keyStrokeAndWaitForEvents(KEY(g), 7);
    test->keyStrokeAndWaitForEvents(KEY(t), 10);
    test->keyStrokeAndWaitForEvents(KEY(k), 13);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabc");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 21);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->keyStrokeAndWaitForEvents(KEY(ISO_Enter), 16);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabcWebKitGTK");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 30);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();

    // Check selection cursor.
    test->keyStrokeAndWaitForEvents(KEY(Left), 2, { WebViewTest::Modifiers::Shift });
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabcWebKitGTK");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 29);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, 30);
    test->keyStrokeAndWaitForEvents(KEY(Home), 4, { WebViewTest::Modifiers::Shift });
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, 30);
    test->keyStrokeAndWaitForEvents(KEY(Left), 6);
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();
    test->keyStrokeAndWaitForEvents(KEY(Right), 2, { WebViewTest::Modifiers::Shift });
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabcWebKitGTK");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, 1);
    test->keyStrokeAndWaitForEvents(KEY(End), 4, { WebViewTest::Modifiers::Shift });
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 0);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, 30);
    test->keyStrokeAndWaitForEvents(KEY(Right), 6);
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabcWebKitGTK");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 30);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();

    // Check text replacements (get surrounding + delete surrounding).
    test->keyStrokeAndWaitForEvents(KEY(colon), 3);
    test->keyStrokeAndWaitForEvents(KEY(minus), 6);
    test->keyStrokeAndWaitForEvents(KEY(parenright), 9);
    test->waitForSurroundingText("WebKitGTKWPEWebKitabcWebKitGTK😀️");
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabcWebKitGTK😀️");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 37);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();

    // Check multiline context.
    test->keyStrokeAndWaitForEvents(KEY(Return), 3);
    test->keyStrokeAndWaitForEvents(KEY(a), 6);
    test->waitForSurroundingText("WebKitGTKWPEWebKitabcWebKitGTK😀️\na");
    g_assert_cmpstr(test->surroundingText(), ==, "WebKitGTKWPEWebKitabcWebKitGTK😀️\na");
    g_assert_cmpuint(test->surroundingCursorIndex(), ==, 39);
    g_assert_cmpuint(test->surroundingSelectionIndex(), ==, test->surroundingCursorIndex());
    test->m_events.clear();
}

static void testWebKitInputMethodContextReset(InputMethodTest* test, gconstpointer)
{
    test->loadHtml(testHTML, nullptr);
    test->waitUntilLoadFinished();

    test->focusEditableAndWaitUntilInputMethodEnabled();

    // Compose w + w + click -> reset sequence.
    test->keyStrokeAndWaitForEvents(KEY(w), 4, { WebViewTest::Modifiers::Control, WebViewTest::Modifiers::Shift });
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::KeyDown);
    g_assert_cmpuint(test->m_events[0].keyCode, ==, 229);
    g_assert_cmpstr(test->m_events[0].key.data(), ==, "Unidentified");
    g_assert_false(test->m_events[0].isComposing);
    g_assert_true(test->m_events[1].type == InputMethodTest::Event::Type::CompositionStart);
    g_assert_cmpstr(test->m_events[1].data.data(), ==, "");
    g_assert_true(test->m_events[2].type == InputMethodTest::Event::Type::CompositionUpdate);
    g_assert_cmpstr(test->m_events[2].data.data(), ==, "w");
    g_assert_true(test->m_events[3].type == InputMethodTest::Event::Type::KeyUp);
    g_assert_cmpuint(test->m_events[3].keyCode, ==, 87);
    g_assert_cmpstr(test->m_events[3].key.data(), ==, "w");
    g_assert_true(test->m_events[3].isComposing);
    test->m_events.clear();
    test->clickAndWaitForEvents(1);
    g_assert_true(test->m_events[0].type == InputMethodTest::Event::Type::CompositionEnd);
    g_assert_cmpstr(test->m_events[0].data.data(), ==, "w");
    {
        auto editableValue = test->editableValue();
        g_assert_cmpstr(editableValue.get(), ==, "w");
    }
    test->resetEditable();
}

static void testWebKitInputMethodContextContentType(InputMethodTest* test, gconstpointer)
{
    test->loadHtml("<input id='editable' spellcheck='false'></input>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='number' spellcheck='false'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_NUMBER);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='number' spellcheck='false' pattern='[0-9]*'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_DIGITS);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='text' spellcheck='false' pattern='\\d*'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_DIGITS);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='tel' spellcheck='false'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_PHONE);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='url' spellcheck='false'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_URL);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='email' spellcheck='false'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_EMAIL);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<input id='editable' type='password' spellcheck='false'>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_PASSWORD);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='text' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='decimal' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_NUMBER);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='numeric' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_DIGITS);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='tel' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_PHONE);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='email' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_EMAIL);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='url' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_URL);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='search' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_NONE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<div contenteditable id='editable' inputmode='none' spellcheck='false'></div>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_INHIBIT_OSK);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<textarea id='editable'></textarea>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_SPELLCHECK);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<textarea id='editable' autocapitalize='none'></textarea>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_SPELLCHECK | WEBKIT_INPUT_HINT_LOWERCASE);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<textarea id='editable' autocapitalize='sentences'></textarea>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_SPELLCHECK | WEBKIT_INPUT_HINT_UPPERCASE_SENTENCES);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<textarea id='editable' autocapitalize='words'></textarea>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_SPELLCHECK | WEBKIT_INPUT_HINT_UPPERCASE_WORDS);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();

    test->loadHtml("<textarea id='editable' autocapitalize='characters'></textarea>", nullptr);
    test->waitUntilLoadFinished();
    test->focusEditableAndWaitUntilInputMethodEnabled();
    g_assert_cmpuint(test->purpose(), ==, WEBKIT_INPUT_PURPOSE_FREE_FORM);
    g_assert_cmpuint(test->hints(), ==, WEBKIT_INPUT_HINT_SPELLCHECK | WEBKIT_INPUT_HINT_UPPERCASE_CHARS);
    test->unfocusEditableAndWaitUntilInputMethodDisabled();
}

void beforeAll()
{
    InputMethodTest::add("WebKitInputMethodContext", "simple", testWebKitInputMethodContextSimple);
    InputMethodTest::add("WebKitInputMethodContext", "sequence", testWebKitInputMethodContextSequence);
    InputMethodTest::add("WebKitInputMethodContext", "invalid-sequence", testWebKitInputMethodContextInvalidSequence);
    InputMethodTest::add("WebKitInputMethodContext", "cancel-sequence", testWebKitInputMethodContextCancelSequence);
    InputMethodTest::add("WebKitInputMethodContext", "surrounding", testWebKitInputMethodContextSurrounding);
    InputMethodTest::add("WebKitInputMethodContext", "reset", testWebKitInputMethodContextReset);
    InputMethodTest::add("WebKitInputMethodContext", "content-type", testWebKitInputMethodContextContentType);
}

void afterAll()
{

}
