diff options
Diffstat (limited to 'tests')
13 files changed, 360 insertions, 2 deletions
diff --git a/tests/auto/quick/qmltests/data/script-with-bad-match-metadata.js b/tests/auto/quick/qmltests/data/script-with-bad-match-metadata.js new file mode 100644 index 000000000..c9a811e5c --- /dev/null +++ b/tests/auto/quick/qmltests/data/script-with-bad-match-metadata.js @@ -0,0 +1,9 @@ +// ==UserScript== +// @name Test bad match script +// @homepageURL http://www.qt.io/ +// @description Test script with metadata block with an invalid match directive +// @match some:junk +// @run-at document-end +// ==/UserScript== + +document.title = "New title for some:junk"; diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml index d7c7d5983..f4fcc30ab 100644 --- a/tests/auto/quick/qmltests/data/tst_userScripts.qml +++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml @@ -54,6 +54,11 @@ Item { sourceUrl: Qt.resolvedUrl("script-with-metadata.js") } + WebEngineScript { + id: scriptWithBadMatchMetadata + sourceUrl: Qt.resolvedUrl("script-with-bad-match-metadata.js") + } + TestWebEngineView { id: webEngineView width: 400 @@ -191,6 +196,18 @@ Item { tryCompare(webEngineView, "title", "Test page with huge link area and iframe"); } + function test_dontInjectBadUrlPatternsEverywhere() { + compare(scriptWithBadMatchMetadata.name, "Test bad match script"); + compare(scriptWithBadMatchMetadata.injectionPoint, WebEngineScript.DocumentReady); + + webEngineView.userScripts = [ scriptWithBadMatchMetadata ]; + + // @match some:junk + webEngineView.url = Qt.resolvedUrl("test2.html"); + webEngineView.waitForLoadSucceeded(); + tryCompare(webEngineView, "title", "Test page with huge link area"); + } + function test_profileWideScript() { webEngineView.profile.userScripts = [ changeDocumentTitleScript ]; diff --git a/tests/auto/widgets/origins/resources/dedicatedWorker.html b/tests/auto/widgets/origins/resources/dedicatedWorker.html new file mode 100644 index 000000000..cb4f14e73 --- /dev/null +++ b/tests/auto/widgets/origins/resources/dedicatedWorker.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <title>dedicatedWorker</title> + <script> + var done = false; + var result; + var error; + try { + let worker = new Worker("dedicatedWorker.js"); + worker.onmessage = (e) => { done = true; result = e.data; }; + worker.postMessage(41); + } catch (e) { + done = true; error = e.message; + } + </script> + </head> + <body></body> +</html> diff --git a/tests/auto/widgets/origins/resources/dedicatedWorker.js b/tests/auto/widgets/origins/resources/dedicatedWorker.js new file mode 100644 index 000000000..2631939d7 --- /dev/null +++ b/tests/auto/widgets/origins/resources/dedicatedWorker.js @@ -0,0 +1 @@ +onmessage = (e) => { postMessage(e.data + 1); }; diff --git a/tests/auto/widgets/origins/resources/serviceWorker.html b/tests/auto/widgets/origins/resources/serviceWorker.html new file mode 100644 index 000000000..b2bdc8c60 --- /dev/null +++ b/tests/auto/widgets/origins/resources/serviceWorker.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> + <head> + <title>serviceWorker</title> + <script> + var done = false; + var error; + navigator.serviceWorker.register("serviceWorker.js") + .then((r) => { done = true; }) + .catch((e) => { done = true; error = e.message; }); + </script> + </head> + <body></body> +</html> diff --git a/tests/auto/widgets/origins/resources/serviceWorker.js b/tests/auto/widgets/origins/resources/serviceWorker.js new file mode 100644 index 000000000..40a8c178f --- /dev/null +++ b/tests/auto/widgets/origins/resources/serviceWorker.js @@ -0,0 +1 @@ +/* empty */ diff --git a/tests/auto/widgets/origins/resources/sharedWorker.html b/tests/auto/widgets/origins/resources/sharedWorker.html new file mode 100644 index 000000000..8b5a0a794 --- /dev/null +++ b/tests/auto/widgets/origins/resources/sharedWorker.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <title>sharedWorker</title> + <script> + var done; + var result; + var error; + try { + let worker = new SharedWorker("sharedWorker.js"); + worker.port.onmessage = (e) => { done = true; result = e.data; }; + worker.port.postMessage(41); + } catch (e) { + done = true; error = e.message; + } + </script> + </head> + <body></body> +</html> diff --git a/tests/auto/widgets/origins/resources/sharedWorker.js b/tests/auto/widgets/origins/resources/sharedWorker.js new file mode 100644 index 000000000..60ef93a5f --- /dev/null +++ b/tests/auto/widgets/origins/resources/sharedWorker.js @@ -0,0 +1,6 @@ +onconnect = function(e) { + let port = e.ports[0]; + port.onmessage = function(e) { + port.postMessage(e.data + 1); + }; +}; diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp index 5c798ddc2..61d54e6de 100644 --- a/tests/auto/widgets/origins/tst_origins.cpp +++ b/tests/auto/widgets/origins/tst_origins.cpp @@ -73,6 +73,9 @@ private Q_SLOTS: void subdirWithoutAccess(); void mixedSchemes(); void webSocket(); + void dedicatedWorker(); + void sharedWorker(); + void serviceWorker(); private: bool load(const QUrl &url) @@ -259,9 +262,74 @@ void tst_Origins::webSocket() QVERIFY(load(QSL("qrc:/resources/websocket.html"))); QTRY_VERIFY(eval(QSL("err")) == QVariant(expected)); + QVERIFY(load(QSL("tst:/resources/websocket.html"))); + QTRY_VERIFY(eval(QSL("err")) == QVariant(expected)); +} + +// Create a (Dedicated)Worker. Since dedicated workers can only be accessed from +// one page, there is not much need for security restrictions. +void tst_Origins::dedicatedWorker() +{ + QVERIFY(load(QSL("file:" THIS_DIR "resources/dedicatedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QCOMPARE(eval(QSL("result")), QVariant(42)); + + QVERIFY(load(QSL("qrc:/resources/dedicatedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QCOMPARE(eval(QSL("result")), QVariant(42)); + // FIXME(juvaldma): QTBUG-62536 - // QVERIFY(load(QSL("tst:/resources/websocket.html"))); - // QTRY_VERIFY(eval(QSL("err")) == QVariant(expected)); + QVERIFY(load(QSL("tst:/resources/dedicatedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QVERIFY(eval(QSL("error")).toString() + .contains(QSL("Access to dedicated workers is denied to origin 'tst://'"))); +} + +// Create a SharedWorker. Shared workers can be accessed from multiple pages, +// and therefore the same-origin policy applies. +void tst_Origins::sharedWorker() +{ + { + ScopedAttribute sa(m_page.settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, false); + QVERIFY(load(QSL("file:" THIS_DIR "resources/sharedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QVERIFY(eval(QSL("error")).toString() + .contains(QSL("cannot be accessed from origin 'null'"))); + } + + { + ScopedAttribute sa(m_page.settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, true); + QVERIFY(load(QSL("file:" THIS_DIR "resources/sharedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QCOMPARE(eval(QSL("result")), QVariant(42)); + } + + QVERIFY(load(QSL("qrc:/resources/sharedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QCOMPARE(eval(QSL("result")), QVariant(42)); + + QVERIFY(load(QSL("tst:/resources/sharedWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QCOMPARE(eval(QSL("result")), QVariant(42)); +} + +// Service workers don't work. +void tst_Origins::serviceWorker() +{ + QVERIFY(load(QSL("file:" THIS_DIR "resources/serviceWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QVERIFY(eval(QSL("error")).toString() + .contains(QSL("The URL protocol of the current origin ('file://') is not supported."))); + + QVERIFY(load(QSL("qrc:/resources/serviceWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QVERIFY(eval(QSL("error")).toString() + .contains(QSL("The URL protocol of the current origin ('qrc://') is not supported."))); + + QVERIFY(load(QSL("tst:/resources/serviceWorker.html"))); + QTRY_VERIFY(eval(QSL("done")).toBool()); + QVERIFY(eval(QSL("error")).toString() + .contains(QSL("Only secure origins are allowed"))); } QTEST_MAIN(tst_Origins) diff --git a/tests/auto/widgets/origins/tst_origins.qrc b/tests/auto/widgets/origins/tst_origins.qrc index 47be3bd0d..fbbbef139 100644 --- a/tests/auto/widgets/origins/tst_origins.qrc +++ b/tests/auto/widgets/origins/tst_origins.qrc @@ -1,9 +1,15 @@ <!DOCTYPE RCC> <RCC version="1.0"> <qresource> + <file>resources/dedicatedWorker.html</file> + <file>resources/dedicatedWorker.js</file> <file>resources/mixed_frame.html</file> <file>resources/mixed_qrc.html</file> <file>resources/mixed_tst.html</file> + <file>resources/serviceWorker.html</file> + <file>resources/serviceWorker.js</file> + <file>resources/sharedWorker.html</file> + <file>resources/sharedWorker.js</file> <file>resources/subdir/frame2.html</file> <file>resources/subdir/index.html</file> <file>resources/subdir_frame1.html</file> diff --git a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp index 4848038df..f932d50c3 100644 --- a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp +++ b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp @@ -112,6 +112,7 @@ void tst_QWebEngineDownloads::initTestCase() m_page = new QWebEnginePage(m_profile); m_view = new QWebEngineView; m_view->setPage(m_page); + m_view->resize(640, 480); m_view->show(); } diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index ee7f9b2c2..025df76c7 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -2878,6 +2878,12 @@ void tst_QWebEnginePage::urlChange() QTRY_COMPARE(urlSpy.size(), 1); QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), dataUrl2); + + QUrl testUrl("http://test.qt.io/"); + m_view->setHtml(QStringLiteral("<h1>Test</h1"), testUrl); + + QTRY_COMPARE(urlSpy.size(), 1); + QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), testUrl); } class FakeReply : public QNetworkReply { @@ -3307,6 +3313,7 @@ protected: void tst_QWebEnginePage::evaluateWillCauseRepaint() { WebView view; + view.resize(640, 480); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -4047,6 +4054,7 @@ void tst_QWebEnginePage::mouseButtonTranslation() <div style=\"height:600px;\" onmousedown=\"saveLastEvent(event)\">\ </div>\ </body></html>")); + view.resize(640, 480); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QTRY_VERIFY(spy.count() == 1); @@ -4071,6 +4079,7 @@ void tst_QWebEnginePage::mouseMovementProperties() QWebEngineView view; ConsolePage page; view.setPage(&page); + view.resize(640, 480); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -4311,6 +4320,16 @@ void tst_QWebEnginePage::dataURLFragment() QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, 0, elementCenter(m_page, "link")); QVERIFY(urlChangedSpy.wait()); QCOMPARE(m_page->url().fragment(), QStringLiteral("anchor")); + + + m_page->setHtml("<html><body>" + "<a id='link' href='#anchor'>anchor</a>" + "</body></html>", QUrl("http://test.qt.io/mytest.html")); + QTRY_COMPARE(loadFinishedSpy.count(), 2); + + QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, 0, elementCenter(m_page, "link")); + QVERIFY(urlChangedSpy.wait()); + QCOMPARE(m_page->url(), QUrl("http://test.qt.io/mytest.html#anchor")); } void tst_QWebEnginePage::devTools() diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 207836bef..248d906ef 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -153,6 +153,7 @@ private Q_SLOTS: void focusOnNavigation_data(); void focusOnNavigation(); void focusInternalRenderWidgetHostViewQuickItem(); + void doNotBreakLayout(); void changeLocale(); void inputMethodsTextFormat_data(); @@ -173,6 +174,7 @@ private Q_SLOTS: void imeCompositionQueryEvent_data(); void imeCompositionQueryEvent(); void newlineInTextarea(); + void imeJSInputEvents(); void mouseLeave(); @@ -344,6 +346,7 @@ void tst_QWebEngineView::crashTests() void tst_QWebEngineView::microFocusCoordinates() { QWebEngineView webView; + webView.resize(640, 480); webView.show(); QVERIFY(QTest::qWaitForWindowExposed(&webView)); @@ -378,6 +381,7 @@ void tst_QWebEngineView::focusInputTypes() bool imeHasHiddenTextCapability = context && context->hasCapability(QPlatformInputContext::HiddenTextCapability); QWebEngineView webView; + webView.resize(640, 480); webView.show(); QVERIFY(QTest::qWaitForWindowExposed(&webView)); @@ -481,6 +485,7 @@ void tst_QWebEngineView::unhandledKeyEventPropagation() { KeyEventRecordingWidget parentWidget; QWebEngineView webView(&parentWidget); + webView.resize(640, 480); parentWidget.show(); QVERIFY(QTest::qWaitForWindowExposed(&webView)); @@ -824,6 +829,7 @@ void tst_QWebEngineView::doNotSendMouseKeyboardEventsWhenDisabled() QFETCH(int, resultEventCount); KeyboardAndMouseEventRecordingWidget parentWidget; + parentWidget.resize(640, 480); QWebEngineView webView(&parentWidget); webView.setEnabled(viewEnabled); parentWidget.setLayout(new QStackedLayout); @@ -1029,6 +1035,31 @@ void tst_QWebEngineView::focusInternalRenderWidgetHostViewQuickItem() QTRY_COMPARE(renderWidgetHostViewQuickItem->hasFocus(), true); } +void tst_QWebEngineView::doNotBreakLayout() +{ + QScopedPointer<QWidget> containerWidget(new QWidget); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(new QWidget); + layout->addWidget(new QWidget); + layout->addWidget(new QWidget); + layout->addWidget(new QWebEngineView); + + containerWidget->setLayout(layout); + containerWidget->setGeometry(50, 50, 800, 600); + containerWidget->show(); + QVERIFY(QTest::qWaitForWindowExposed(containerWidget.data())); + + QSize previousSize = static_cast<QWidgetItem *>(layout->itemAt(0))->widget()->size(); + for (int i = 1; i < layout->count(); i++) { + QSize actualSize = static_cast<QWidgetItem *>(layout->itemAt(i))->widget()->size(); + // There could be smaller differences on some platforms + QVERIFY(qAbs(previousSize.width() - actualSize.width()) <= 2); + QVERIFY(qAbs(previousSize.height() - actualSize.height()) <= 2); + previousSize = actualSize; + } +} + void tst_QWebEngineView::changeLocale() { QStringList errorLines; @@ -1592,6 +1623,7 @@ void tst_QWebEngineView::softwareInputPanel() { TestInputContext testContext; QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); @@ -1648,6 +1680,7 @@ void tst_QWebEngineView::softwareInputPanel() void tst_QWebEngineView::inputMethods() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); @@ -1744,6 +1777,7 @@ void tst_QWebEngineView::inputMethods() void tst_QWebEngineView::textSelectionInInputField() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); @@ -1825,6 +1859,7 @@ void tst_QWebEngineView::textSelectionInInputField() void tst_QWebEngineView::textSelectionOutOfInputField() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); @@ -1908,6 +1943,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField() void tst_QWebEngineView::hiddenText() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); @@ -1933,6 +1969,7 @@ void tst_QWebEngineView::hiddenText() void tst_QWebEngineView::emptyInputMethodEvent() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); @@ -1979,6 +2016,7 @@ void tst_QWebEngineView::emptyInputMethodEvent() void tst_QWebEngineView::imeComposition() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); @@ -2153,6 +2191,7 @@ void tst_QWebEngineView::imeComposition() void tst_QWebEngineView::newlineInTextarea() { QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); @@ -2249,6 +2288,142 @@ void tst_QWebEngineView::newlineInTextarea() QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line")); } +void tst_QWebEngineView::imeJSInputEvents() +{ + QWebEngineView view; + view.resize(640, 480); + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); + view.show(); + + auto logLines = [&view]() -> QStringList { + return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegExp(".+")); + }; + + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + view.page()->setHtml("<html>" + "<head><script>" + " var input, log;" + " function verboseEvent(ev) {" + " log.textContent += ev + ' ' + ev.type + ' ' + ev.data + '\\n';" + " }" + " function clear(ev) {" + " log.textContent = '';" + " input.textContent = '';" + " }" + " function init() {" + " input = document.getElementById('input');" + " log = document.getElementById('log');" + " events = [ 'textInput', 'beforeinput', 'input', 'compositionstart', 'compositionupdate', 'compositionend' ];" + " for (var e in events)" + " input.addEventListener(events[e], verboseEvent);" + " }" + "</script></head>" + "<body onload='init()'>" + " <div id='input' contenteditable='true' style='border-style: solid;'></div>" + " <pre id='log'></pre>" + "</body></html>"); + QVERIFY(loadFinishedSpy.wait()); + + evaluateJavaScriptSync(view.page(), "document.getElementById('input').focus()"); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input")); + + // 1. Commit text (this is how dead keys work on Linux). + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + event.setCommitString("commit"); + QApplication::sendEvent(view.focusProxy(), &event); + qApp->processEvents(); + } + + // Simply committing text should not trigger any JS composition event. + QTRY_COMPARE(logLines().count(), 3); + QCOMPARE(logLines()[0], "[object InputEvent] beforeinput commit"); + QCOMPARE(logLines()[1], "[object TextEvent] textInput commit"); + QCOMPARE(logLines()[2], "[object InputEvent] input commit"); + + evaluateJavaScriptSync(view.page(), "clear()"); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty()); + + // 2. Start composition then commit text (this is how dead keys work on macOS). + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("preedit", attributes); + QApplication::sendEvent(view.focusProxy(), &event); + qApp->processEvents(); + } + + QTRY_COMPARE(logLines().count(), 4); + QCOMPARE(logLines()[0], "[object CompositionEvent] compositionstart "); + QCOMPARE(logLines()[1], "[object InputEvent] beforeinput preedit"); + QCOMPARE(logLines()[2], "[object CompositionEvent] compositionupdate preedit"); + QCOMPARE(logLines()[3], "[object InputEvent] input preedit"); + + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + event.setCommitString("commit"); + QApplication::sendEvent(view.focusProxy(), &event); + qApp->processEvents(); + } + + QTRY_COMPARE(logLines().count(), 9); + QCOMPARE(logLines()[4], "[object InputEvent] beforeinput commit"); + QCOMPARE(logLines()[5], "[object CompositionEvent] compositionupdate commit"); + QCOMPARE(logLines()[6], "[object TextEvent] textInput commit"); + QCOMPARE(logLines()[7], "[object InputEvent] input commit"); + QCOMPARE(logLines()[8], "[object CompositionEvent] compositionend commit"); + + evaluateJavaScriptSync(view.page(), "clear()"); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty()); + + // 3. Start composition then cancel it with an empty IME event. + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("preedit", attributes); + QApplication::sendEvent(view.focusProxy(), &event); + qApp->processEvents(); + } + + QTRY_COMPARE(logLines().count(), 4); + QCOMPARE(logLines()[0], "[object CompositionEvent] compositionstart "); + QCOMPARE(logLines()[1], "[object InputEvent] beforeinput preedit"); + QCOMPARE(logLines()[2], "[object CompositionEvent] compositionupdate preedit"); + QCOMPARE(logLines()[3], "[object InputEvent] input preedit"); + + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + QApplication::sendEvent(view.focusProxy(), &event); + qApp->processEvents(); + } + + QTRY_COMPARE(logLines().count(), 9); + QCOMPARE(logLines()[4], "[object InputEvent] beforeinput "); + QCOMPARE(logLines()[5], "[object CompositionEvent] compositionupdate "); + QCOMPARE(logLines()[6], "[object TextEvent] textInput "); + QCOMPARE(logLines()[7], "[object InputEvent] input null"); + QCOMPARE(logLines()[8], "[object CompositionEvent] compositionend "); + + evaluateJavaScriptSync(view.page(), "clear()"); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty()); + + // 4. Send empty IME event. + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + QApplication::sendEvent(view.focusProxy(), &event); + qApp->processEvents(); + } + + // No JS event is expected. + QTest::qWait(100); + QVERIFY(logLines().isEmpty()); + + evaluateJavaScriptSync(view.page(), "clear()"); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty()); +} + void tst_QWebEngineView::imeCompositionQueryEvent_data() { QTest::addColumn<QString>("receiverObjectName"); @@ -2260,6 +2435,7 @@ void tst_QWebEngineView::imeCompositionQueryEvent_data() void tst_QWebEngineView::imeCompositionQueryEvent() { QWebEngineView view; + view.resize(640, 480); view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.show(); @@ -2341,6 +2517,7 @@ void tst_QWebEngineView::globalMouseSelection() QApplication::clipboard()->clear(QClipboard::Selection); QWebEngineView view; + view.resize(640, 480); view.show(); QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); @@ -2421,6 +2598,7 @@ void tst_QWebEngineView::contextMenu() } view.setContextMenuPolicy(contextMenuPolicy); + view.resize(640, 480); view.show(); QVERIFY(view.findChildren<QMenu *>().isEmpty()); |