summaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml21
-rw-r--r--tests/auto/quick/qmltests/data/confirmclose.html3
-rw-r--r--tests/auto/quick/qmltests/data/favicon.html2
-rw-r--r--tests/auto/quick/qmltests/data/tst_contextMenu.qml224
-rw-r--r--tests/auto/quick/qmltests/data/tst_favicon.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml12
-rw-r--r--tests/auto/quick/qmltests/data/tst_getUserMedia.qml201
-rw-r--r--tests/auto/quick/qmltests/data/tst_inputMethod.qml76
-rw-r--r--tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml24
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadProgress.qml3
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_mouseClick.qml113
-rw-r--r--tests/auto/quick/qmltests/data/tst_mouseMove.qml4
-rw-r--r--tests/auto/quick/qmltests/data/tst_viewSource.qml9
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/Menu.qml57
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/MenuItem.qml44
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro20
-rw-r--r--tests/auto/quick/qmltests/tst_qmltests.cpp13
-rw-r--r--tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp2
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST6
-rw-r--r--tests/auto/quick/qquickwebengineview/qquickwebengineview.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp59
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro2
-rw-r--r--tests/auto/quick/quick.pro4
-rw-r--r--tests/auto/quick/shared/util.h24
-rw-r--r--tests/auto/quick/tests.pri5
26 files changed, 885 insertions, 48 deletions
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index a7d890072..2ce8f3026 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -28,11 +28,12 @@
import QtQuick 2.0
import QtTest 1.1
-import QtWebEngine 1.3
+import QtWebEngine 1.6
WebEngineView {
property var loadStatus: null
property bool windowCloseRequestedSignalEmitted: false
+ settings.focusOnNavigationEnabled: true
function waitForLoadSucceeded() {
var success = _waitFor(function() { return loadStatus == WebEngineView.LoadSucceededStatus })
@@ -81,6 +82,24 @@ WebEngineView {
verifyElementHasFocus(element);
}
+ function getElementCenter(element) {
+ var center;
+ runJavaScript("(function() {" +
+ " var elem = document.getElementById('" + element + "');" +
+ " var rect = elem.getBoundingClientRect();" +
+ " return { 'x': (rect.left + rect.right) / 2, 'y': (rect.top + rect.bottom) / 2 };" +
+ "})();", function(result) { center = result } );
+ testCase.tryVerify(function() { return center !== undefined; });
+ return center;
+ }
+
+ function getTextSelection() {
+ var textSelection;
+ runJavaScript("window.getSelection().toString()", function(result) { textSelection = result });
+ testCase.tryVerify(function() { return textSelection !== undefined; });
+ return textSelection;
+ }
+
TestResult { id: testResult }
TestCase { id: testCase }
diff --git a/tests/auto/quick/qmltests/data/confirmclose.html b/tests/auto/quick/qmltests/data/confirmclose.html
index ba11da7a4..c2acbb67f 100644
--- a/tests/auto/quick/qmltests/data/confirmclose.html
+++ b/tests/auto/quick/qmltests/data/confirmclose.html
@@ -1,5 +1,6 @@
<html>
-<body onbeforeunload="return 'You are about to miss out on some awesome content.';">
+<body onbeforeunload="return 'You are about to miss out on some awesome content.';"
+ onmousedown="window.mousePressReceived = true;">
Be greeted, precious viewer!
</body>
</html>
diff --git a/tests/auto/quick/qmltests/data/favicon.html b/tests/auto/quick/qmltests/data/favicon.html
index 9823fa323..7a81194e4 100644
--- a/tests/auto/quick/qmltests/data/favicon.html
+++ b/tests/auto/quick/qmltests/data/favicon.html
@@ -5,6 +5,6 @@
<body>
<p>It's expected that you see a favicon displayed for this page when you open it as a local file.</p>
<p>The favicon looks like this:</p>
-<img src="icons/favicon.png"/>
+<img id='image' src="icons/favicon.png"/>
</body>
</html>
diff --git a/tests/auto/quick/qmltests/data/tst_contextMenu.qml b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
new file mode 100644
index 000000000..58947beaf
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Controls 1.4
+import QtTest 1.0
+import QtWebEngine 1.6
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 400
+
+ property string linkText: ""
+ property var mediaType: null
+ property string selectedText: ""
+
+ onContextMenuRequested: {
+ linkText = request.linkText;
+ mediaType = request.mediaType;
+ selectedText = request.selectedText;
+ }
+
+ SignalSpy {
+ id: contextMenuRequestedSpy
+ target: webEngineView
+ signalName: "contextMenuRequested"
+ }
+
+ function getContextMenus() {
+ var data = webEngineView.data;
+ var contextMenus = [];
+
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].type == MenuItemType.Menu) {
+ contextMenus.push(data[i]);
+ }
+ }
+ return contextMenus;
+ }
+
+ function destroyContextMenu() {
+ contextMenuTest.keyPress(Qt.Key_Escape);
+ return getContextMenus().length == 0;
+ }
+
+ TestCase {
+ id: contextMenuTest
+ name: "WebEngineViewContextMenu"
+ when: windowShown
+
+ function init() {
+ var contextMenus = getContextMenus();
+ compare(contextMenus.length, 0);
+ }
+
+ function cleanup() {
+ contextMenuRequestedSpy.clear();
+ }
+
+ function test_contextMenu_data() {
+ return [
+ { tag: "defaultContextMenu", userHandled: false, accepted: false },
+ { tag: "defaultContextMenuWithConnect", userHandled: true, accepted: false },
+ { tag: "dontShowDefaultContextMenu", userHandled: true, accepted: true },
+ ];
+ }
+
+ function test_contextMenu(row) {
+ if (Qt.platform.os == "osx") {
+ skip("When the menu pops up on macOS, it does not return and the test fails after time out.");
+ }
+
+ function contextMenuHandler(request) {
+ request.accepted = row.accepted;
+ }
+
+ if (row.userHandled) {
+ webEngineView.contextMenuRequested.connect(contextMenuHandler);
+ }
+
+ mouseClick(webEngineView, 20, 20, Qt.RightButton);
+ contextMenuRequestedSpy.wait();
+ compare(contextMenuRequestedSpy.count, 1);
+
+ // There should be maximum one ContextMenu present at a time
+ var contextMenus = getContextMenus();
+ verify(contextMenus.length <= 1);
+ compare(contextMenus[0] != null, !row.accepted);
+
+ // FIXME: Sometimes the keyPress(Qt.Key_Escape) event isn't caught so we keep trying
+ tryVerify(destroyContextMenu);
+ webEngineView.contextMenuRequested.disconnect(contextMenuHandler);
+ }
+
+ function test_contextMenuLinkAndSelectedText() {
+ if (Qt.platform.os == "osx") {
+ skip("When the menu pops up on macOS, it does not return and the test fails after time out.");
+ }
+
+ webEngineView.loadHtml("<html><body>" +
+ "<span id='text'>Text </span>" +
+ "<a id='link' href='test1.html'>Link</a>" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // 1. Nothing is selected, right click on the link
+ var linkCenter = getElementCenter("link");
+ mouseClick(webEngineView, linkCenter.x, linkCenter.y, Qt.RightButton);
+ contextMenuRequestedSpy.wait();
+ compare(contextMenuRequestedSpy.count, 1);
+
+ var contextMenus = getContextMenus();
+ compare(contextMenus.length, 1);
+ verify(contextMenus[0]);
+ compare(linkText, "Link");
+ compare(mediaType, ContextMenuRequest.MediaTypeNone);
+ compare(selectedText, "");
+
+ contextMenuRequestedSpy.clear();
+ // FIXME: Sometimes the keyPress(Qt.Key_Escape) event isn't caught so we keep trying
+ tryVerify(destroyContextMenu);
+
+ // 2. Everything is selected, right click on the link
+ webEngineView.triggerWebAction(WebEngineView.SelectAll);
+ tryVerify(function() { return getTextSelection() == "Text Link" });
+
+ mouseClick(webEngineView, linkCenter.x, linkCenter.y, Qt.RightButton);
+ contextMenuRequestedSpy.wait();
+ compare(contextMenuRequestedSpy.count, 1);
+
+ contextMenus = getContextMenus();
+ compare(contextMenus.length, 1);
+ verify(contextMenus[0]);
+ compare(linkText, "Link");
+ compare(mediaType, ContextMenuRequest.MediaTypeNone);
+ compare(selectedText, "Text Link");
+
+ contextMenuRequestedSpy.clear();
+ // FIXME: Sometimes the keyPress(Qt.Key_Escape) event isn't caught so we keep trying
+ tryVerify(destroyContextMenu);
+
+ // 3. Everything is selected, right click on the text
+ var textCenter = getElementCenter("text");
+ mouseClick(webEngineView, textCenter.x, textCenter.y, Qt.RightButton);
+ contextMenuRequestedSpy.wait();
+ compare(contextMenuRequestedSpy.count, 1);
+
+ contextMenus = getContextMenus();
+ compare(contextMenus.length, 1);
+ verify(contextMenus[0]);
+ compare(linkText, "");
+ compare(mediaType, ContextMenuRequest.MediaTypeNone);
+ compare(selectedText, "Text Link");
+
+ // FIXME: Sometimes the keyPress(Qt.Key_Escape) event isn't caught so we keep trying
+ tryVerify(destroyContextMenu);
+ }
+
+ function test_contextMenuMediaType() {
+ if (Qt.platform.os == "osx") {
+ skip("When the menu pops up on macOS, it does not return and the test fails after time out.");
+ }
+
+ webEngineView.url = Qt.resolvedUrl("favicon.html");
+ verify(webEngineView.waitForLoadSucceeded());
+ // 1. Right click on the image
+ var center = getElementCenter("image");
+ mouseClick(webEngineView, center.x, center.y, Qt.RightButton);
+ contextMenuRequestedSpy.wait();
+ compare(contextMenuRequestedSpy.count, 1);
+
+ var contextMenus = getContextMenus();
+ compare(contextMenus.length, 1);
+ verify(contextMenus[0]);
+ compare(linkText, "");
+ compare(mediaType, ContextMenuRequest.MediaTypeImage);
+ compare(selectedText, "");
+ contextMenuRequestedSpy.clear();
+ // FIXME: Sometimes the keyPress(Qt.Key_Escape) event isn't caught so we keep trying
+ tryVerify(destroyContextMenu);
+
+ // 2. Right click out of the image
+ mouseClick(webEngineView, center.x + 30, center.y, Qt.RightButton);
+ contextMenuRequestedSpy.wait();
+ compare(contextMenuRequestedSpy.count, 1);
+
+ contextMenus = getContextMenus();
+ compare(contextMenus.length, 1);
+ verify(contextMenus[0]);
+ compare(linkText, "");
+ compare(mediaType, ContextMenuRequest.MediaTypeNone);
+ compare(selectedText, "");
+
+ // FIXME: Sometimes the keyPress(Qt.Key_Escape) event isn't caught so we keep trying
+ tryVerify(destroyContextMenu);
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index cc000c7fc..1159f3194 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -181,6 +181,7 @@ TestWebEngineView {
var url = Qt.resolvedUrl("invalid://url")
webEngineView.url = url
+ verify(webEngineView.waitForLoadFailed())
verify(webEngineView.testSupport.waitForErrorPageLoadSucceeded())
compare(iconChangedSpy.count, 0)
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index f8730ca7b..dfcfd586f 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -57,7 +57,7 @@ TestWebEngineView {
runJavaScript("document.body.innerHTML", function(result) {
bodyInnerHTML = result;
});
- tryVerify(function() { return bodyInnerHTML != undefined; });
+ tryVerify(function() { return bodyInnerHTML != undefined; }, 20000);
return bodyInnerHTML;
}
@@ -66,7 +66,7 @@ TestWebEngineView {
runJavaScript("document.getElementById('list').getElementsByTagName('li')[" + index + "].innerText;", function(result) {
listItemText = result;
});
- tryVerify(function() { return listItemText != undefined; });
+ tryVerify(function() { return listItemText != undefined; }, 20000);
return listItemText;
}
@@ -82,9 +82,9 @@ TestWebEngineView {
var itemIndex;
runJavaScript(script, function(result) { itemIndex = result; });
- tryVerify(function() { return itemIndex != undefined; });
+ tryVerify(function() { return itemIndex != undefined; }, 20000);
// Make sure the DOM is up-to-date.
- tryVerify(function() { return getListItemText(itemIndex).length == text.length; });
+ tryVerify(function() { return getListItemText(itemIndex).length == text.length; }, 20000);
}
function test_findText() {
@@ -176,7 +176,7 @@ TestWebEngineView {
verify(findFailed)
runJavaScript("document.body.innerHTML = 'blahellobla'");
- tryVerify(function() { return getBodyInnerHTML() == "blahellobla"; });
+ tryVerify(function() { return getBodyInnerHTML() == "blahellobla"; }, 20000);
webEngineView.clear()
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
@@ -213,7 +213,7 @@ TestWebEngineView {
// The callback is not supposed to be called, see QTBUG-61506.
// Check whether the callback was called (-1 = no, other values = yes).
- tryVerify(function() { return webEngineView.matchCount == -1; });
+ tryVerify(function() { return webEngineView.matchCount == -1; }, 20000);
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
new file mode 100644
index 000000000..b497542e3
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtTest 1.0
+import QtWebEngine 1.6
+
+TestWebEngineView {
+ id: webEngineView
+
+ settings.screenCaptureEnabled: true
+
+ TestCase {
+ name: "GetUserMedia"
+
+ function init_data() {
+ return [
+ {
+ tag: "device audio",
+ constraints: { audio: true },
+ feature: WebEngineView.MediaAudioCapture,
+ },
+ {
+ tag: "device video",
+ constraints: { video: true },
+ feature: WebEngineView.MediaVideoCapture,
+ },
+ {
+ tag: "device audio+video",
+ constraints: { audio: true, video: true },
+ feature: WebEngineView.MediaAudioVideoCapture,
+ },
+ {
+ tag: "desktop video",
+ constraints: {
+ video: {
+ mandatory: {
+ chromeMediaSource: "desktop"
+ }
+ }
+ },
+ feature: WebEngineView.DesktopVideoCapture,
+ },
+ {
+ tag: "desktop audio+video",
+ constraints: {
+ audio: {
+ mandatory: {
+ chromeMediaSource: "desktop"
+ }
+ },
+ video: {
+ mandatory: {
+ chromeMediaSource: "desktop"
+ }
+ }
+ },
+ feature: WebEngineView.DesktopAudioVideoCapture,
+ }
+ ]
+ }
+
+ function test_getUserMedia(row) {
+ loadSync(Qt.resolvedUrl("test1.html"))
+
+ // 1. Rejecting request on QML side should reject promise on JS side.
+ jsGetUserMedia(row.constraints)
+ tryVerify(function(){ return gotFeatureRequest(row.feature) })
+ rejectPendingRequest()
+ tryVerify(function(){ return !jsPromiseFulfilled() && jsPromiseRejected() })
+
+ // 2. Accepting request on QML side should either fulfill or reject the
+ // Promise on JS side. Due to the potential lack of physical media devices
+ // deeper in the content layer we cannot guarantee that the promise will
+ // always be fulfilled, however in this case an error should be returned to
+ // JS instead of leaving the Promise in limbo.
+ jsGetUserMedia(row.constraints)
+ tryVerify(function(){ return gotFeatureRequest(row.feature) })
+ acceptPendingRequest()
+ tryVerify(function(){ return jsPromiseFulfilled() || jsPromiseRejected() });
+
+ // 3. Media feature permissions are not remembered.
+ jsGetUserMedia(row.constraints);
+ tryVerify(function(){ return gotFeatureRequest(row.feature) })
+ acceptPendingRequest()
+ tryVerify(function(){ return jsPromiseFulfilled() || jsPromiseRejected() });
+ }
+ }
+
+ ////
+ // synchronous loading
+
+ signal loadFinished
+
+ SignalSpy {
+ id: spyOnLoadFinished
+ target: webEngineView
+ signalName: "loadFinished"
+ }
+
+ onLoadingChanged: {
+ if (loadRequest.status == WebEngineLoadRequest.LoadSucceededStatus) {
+ loadFinished()
+ }
+ }
+
+ function loadSync(url) {
+ webEngineView.url = url
+ spyOnLoadFinished.wait()
+ }
+
+ ////
+ // synchronous permission requests
+
+ property variant requestedFeature
+ property variant requestedSecurityOrigin
+
+ onFeaturePermissionRequested: {
+ requestedFeature = feature
+ requestedSecurityOrigin = securityOrigin
+ }
+
+ function gotFeatureRequest(expectedFeature) {
+ return requestedFeature == expectedFeature
+ }
+
+ function acceptPendingRequest() {
+ webEngineView.grantFeaturePermission(requestedSecurityOrigin, requestedFeature, true)
+ requestedFeature = undefined
+ requestedSecurityOrigin = undefined
+ }
+
+ function rejectPendingRequest() {
+ webEngineView.grantFeaturePermission(requestedSecurityOrigin, requestedFeature, false)
+ requestedFeature = undefined
+ requestedSecurityOrigin = undefined
+ }
+
+ ////
+ // synchronous JavaScript evaluation
+
+ signal runJavaScriptFinished(variant result)
+
+ SignalSpy {
+ id: spyOnRunJavaScriptFinished
+ target: webEngineView
+ signalName: "runJavaScriptFinished"
+ }
+
+ function runJavaScriptSync(code) {
+ spyOnRunJavaScriptFinished.clear()
+ runJavaScript(code, runJavaScriptFinished)
+ spyOnRunJavaScriptFinished.wait()
+ return spyOnRunJavaScriptFinished.signalArguments[0][0]
+ }
+
+ ////
+ // JavaScript snippets
+
+ function jsGetUserMedia(constraints) {
+ runJavaScript(
+ "var promiseFulfilled = false;" +
+ "var promiseRejected = false;" +
+ "navigator.mediaDevices.getUserMedia(" + JSON.stringify(constraints) + ")" +
+ ".then(stream => { promiseFulfilled = true})" +
+ ".catch(err => { promiseRejected = true})")
+ }
+
+ function jsPromiseFulfilled() {
+ return runJavaScriptSync("promiseFulfilled")
+ }
+
+ function jsPromiseRejected() {
+ return runJavaScriptSync("promiseRejected")
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_inputMethod.qml b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
new file mode 100644
index 000000000..c09a8bdd9
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.4
+import QtWebEngine.testsupport 1.0
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 400
+
+ testSupport: WebEngineTestSupport { }
+
+ TestCase {
+ name: "WebEngineViewInputMethod"
+ when: windowShown
+
+ function init() {
+ testSupport.testInputContext.create();
+ }
+
+ function cleanup() {
+ testSupport.testInputContext.release();
+ }
+
+ function test_softwareInputPanel() {
+ verify(!Qt.inputMethod.visible);
+ webEngineView.loadHtml(
+ "<html><body>" +
+ " <form><input id='textInput' type='text' /></form>" +
+ "</body></html");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ verify(!getActiveElementId());
+ verify(!Qt.inputMethod.visible);
+
+ // Show input panel
+ webEngineView.runJavaScript("document.getElementById('textInput').focus()");
+ webEngineView.verifyElementHasFocus("textInput");
+ tryVerify(function() { return Qt.inputMethod.visible; });
+
+ // Hide input panel
+ webEngineView.runJavaScript("document.getElementById('textInput').blur()");
+ verify(!getActiveElementId());
+ tryVerify(function() { return !Qt.inputMethod.visible; });
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
index 73673f511..07236c3be 100644
--- a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
+++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
@@ -34,6 +34,7 @@ import "../mock-delegates/TestParams" 1.0
TestWebEngineView {
id: webEngineView
+ anchors.fill: parent
testSupport: WebEngineTestSupport {
property bool windowCloseRejectedSignalEmitted: false
@@ -52,6 +53,7 @@ TestWebEngineView {
TestCase {
id: test
name: "WebEngineViewJavaScriptDialogs"
+ when: windowShown
function init() {
JSDialogParams.dialogMessage = "";
@@ -81,12 +83,32 @@ TestWebEngineView {
compare(webEngineView.title, "REJECTED")
}
+ function readMousePressRecieved() {
+ var mousePressReceived;
+ runJavaScript("window.mousePressReceived", function(result) {
+ mousePressReceived = result;
+ });
+
+ _waitFor(function() { return mousePressReceived != undefined; });
+ return mousePressReceived;
+ }
+
+ function simulateUserGesture() {
+ // A user gesture after page load is required since Chromium 60 to allow showing
+ // an onbeforeunload dialog.
+ // See https://www.chromestatus.com/feature/5082396709879808
+ mouseClick(webEngineView, 10, 10, Qt.LeftButton)
+
+ tryVerify(readMousePressRecieved)
+ }
function test_confirmClose() {
webEngineView.url = Qt.resolvedUrl("confirmclose.html");
verify(webEngineView.waitForLoadSucceeded());
webEngineView.windowCloseRequestedSignalEmitted = false;
JSDialogParams.shouldAcceptDialog = true;
+
+ simulateUserGesture()
webEngineView.triggerWebAction(WebEngineView.RequestClose);
verify(webEngineView.waitForWindowCloseRequested());
}
@@ -96,6 +118,8 @@ TestWebEngineView {
verify(webEngineView.waitForLoadSucceeded());
webEngineView.testSupport.windowCloseRejectedSignalEmitted = false;
JSDialogParams.shouldAcceptDialog = false;
+
+ simulateUserGesture()
webEngineView.triggerWebAction(WebEngineView.RequestClose);
verify(webEngineView.testSupport.waitForWindowCloseRejected());
}
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgress.qml b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
index bb85ed8e3..15058cb8f 100644
--- a/tests/auto/quick/qmltests/data/tst_loadProgress.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
@@ -71,7 +71,8 @@ TestWebEngineView {
var loadProgressMin = 0
for (var i in loadProgressArray) {
var loadProgress = loadProgressArray[i]
- verify(loadProgressMin <= loadProgress)
+ if (loadProgressMin > loadProgress)
+ fail("Invalid sequence of progress-values: " + loadProgressArray)
loadProgressMin = loadProgress
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 2cb9f6b81..80d7a18b3 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -231,9 +231,11 @@ TestWebEngineView {
loadRequest = loadRequestArray[2];
compare(loadRequest.status, WebEngineView.LoadStartedStatus);
compare(loadRequest.activeUrl, aboutBlank);
+ compare(loadRequest.url, bogusSite)
loadRequest = loadRequestArray[3];
compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
compare(loadRequest.activeUrl, bogusSite);
+ compare(loadRequest.url, bogusSite)
webEngineView.clear();
}
diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
new file mode 100644
index 000000000..bd6625a90
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.4
+
+import QtWebEngine.testsupport 1.0
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 200
+
+ testSupport: WebEngineTestSupport {
+ function mouseMultiClick(item, x, y, clickCount) {
+ if (!item)
+ qtest_fail("No item given to mouseMultiClick", 1);
+
+ if (x === undefined)
+ x = item.width / 2;
+ if (y === undefined)
+ y = item.height / 2;
+ if (!testEvent.mouseMultiClick(item, x, y, clickCount))
+ qtest_fail("window not shown", 2);
+ }
+
+ function mouseDoubleClick(item, x, y) {
+ mouseMultiClick(item, x, y, 2);
+ }
+
+ function mouseTripleClick(item, x, y) {
+ mouseMultiClick(item, x, y, 3);
+ }
+ }
+
+
+ TestCase {
+ name: "WebEngineViewMouseClick"
+ when: windowShown
+
+ function test_singleClick() {
+ webEngineView.settings.focusOnNavigationEnabled = false;
+ webEngineView.loadHtml("<html><body>" +
+ "<form><input id='input' width='150' type='text' value='The Qt Company' /></form>" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ verify(!getActiveElementId());
+
+ var center = getElementCenter("input");
+ mouseClick(webEngineView, center.x, center.y);
+ verifyElementHasFocus("input");
+ compare(getTextSelection(), "");
+ }
+
+ function test_doubleClick() {
+ webEngineView.settings.focusOnNavigationEnabled = true;
+ webEngineView.loadHtml("<html><body onload='document.getElementById(\"input\").focus()'>" +
+ "<form><input id='input' width='150' type='text' value='The Qt Company' /></form>" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ var center = getElementCenter("input");
+ webEngineView.testSupport.mouseDoubleClick(webEngineView, center.x, center.y);
+ verifyElementHasFocus("input");
+ tryVerify(function() { return getTextSelection() == "Company" });
+
+ mouseClick(webEngineView, center.x, center.y);
+ tryVerify(function() { return getTextSelection() == "" });
+ }
+
+ function test_tripleClick() {
+ webEngineView.settings.focusOnNavigationEnabled = true;
+ webEngineView.loadHtml("<html><body onload='document.getElementById(\"input\").focus()'>" +
+ "<form><input id='input' width='150' type='text' value='The Qt Company' /></form>" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ var center = getElementCenter("input");
+ webEngineView.testSupport.mouseTripleClick(webEngineView, center.x, center.y);
+ verifyElementHasFocus("input");
+ tryVerify(function() { return getTextSelection() == "The Qt Company" });
+
+ mouseClick(webEngineView, center.x, center.y);
+ tryVerify(function() { return getTextSelection() == "" });
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_mouseMove.qml b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
index adb937139..adfa3941c 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseMove.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
@@ -81,7 +81,9 @@ Rectangle {
"</body>" +
"</html>");
verify(webEngineView.waitForLoadSucceeded());
- verify(!webEngineView.getInnerText("testDiv"));
+ // Make sure the testDiv text is empty.
+ webEngineView.runJavaScript("document.getElementById('testDiv').innerText = ''");
+ tryVerify(function() { return !webEngineView.getInnerText("testDiv") });
for (var i = 90; i < 110; ++i)
mouseMove(root, 50, i);
diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml
index 22c3947d3..576035ef2 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSource.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml
@@ -63,7 +63,7 @@ TestWebEngineView {
name: "WebEngineViewSource"
function init() {
- webEngineView.url = Qt.resolvedUrl("about:blank");
+ webEngineView.url = Qt.resolvedUrl("test1.html");
verify(webEngineView.waitForLoadSucceeded());
newViewRequestedSpy.clear();
@@ -103,8 +103,8 @@ TestWebEngineView {
{ tag: "view-source:about:blank", userInputUrl: "view-source:about:blank", loadSucceed: true, url: "view-source:about:blank", title: "view-source:about:blank" },
{ tag: testLocalUrl, userInputUrl: testLocalUrl, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
{ tag: testLocalUrlWithoutScheme, userInputUrl: testLocalUrlWithoutScheme, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
- { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "non.existent" },
- { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "non.existent" },
+ { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
+ { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
];
}
@@ -114,11 +114,10 @@ TestWebEngineView {
if (row.loadSucceed) {
verify(webEngineView.waitForLoadSucceeded());
- tryVerify(function() { return titleChangedSpy.count >= 1; });
} else {
verify(webEngineView.waitForLoadFailed());
- tryVerify(function() { return titleChangedSpy.count >= 2; });
}
+ tryVerify(function() { return titleChangedSpy.count == 1; });
compare(webEngineView.url, row.url);
tryCompare(webEngineView, "title", row.title);
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/Menu.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/Menu.qml
new file mode 100644
index 000000000..36efa7680
--- /dev/null
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/Menu.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4 as Controls
+
+Controls.Menu {
+ id: menu
+ signal done()
+
+ // Use private API for now
+ onAboutToHide: doneTimer.start()
+
+ // WORKAROUND On Mac the Menu may be destroyed before the MenuItem
+ // is actually triggered (see qtbase commit 08cc9b9991ae9ab51)
+ Timer {
+ id: doneTimer
+ interval: 100
+ onTriggered: menu.done()
+ }
+}
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/MenuItem.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/MenuItem.qml
new file mode 100644
index 000000000..e61f4c230
--- /dev/null
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/MenuItem.qml
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4 as Controls
+
+Controls.MenuItem { }
+
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index f09e5f009..16ecbc1bc 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -43,6 +43,7 @@ OTHER_FILES += \
$$PWD/data/keyboardEvents.html \
$$PWD/data/titleupdate.js \
$$PWD/data/tst_activeFocusOnPress.qml \
+ $$PWD/data/tst_contextMenu.qml \
$$PWD/data/tst_desktopBehaviorLoadHtml.qml \
$$PWD/data/tst_download.qml \
$$PWD/data/tst_favicon.qml \
@@ -52,6 +53,8 @@ OTHER_FILES += \
$$PWD/data/tst_focusOnNavigation.qml \
$$PWD/data/tst_formValidation.qml \
$$PWD/data/tst_geopermission.qml \
+ $$PWD/data/tst_getUserMedia.qml \
+ $$PWD/data/tst_inputMethod.qml \
$$PWD/data/tst_javaScriptDialogs.qml \
$$PWD/data/tst_linkHovered.qml \
$$PWD/data/tst_loadFail.qml \
@@ -59,6 +62,7 @@ OTHER_FILES += \
$$PWD/data/tst_loadProgress.qml \
$$PWD/data/tst_loadRecursionCrash.qml \
$$PWD/data/tst_loadUrl.qml \
+ $$PWD/data/tst_mouseClick.qml \
$$PWD/data/tst_mouseMove.qml \
$$PWD/data/tst_navigationHistory.qml \
$$PWD/data/tst_navigationRequested.qml \
@@ -86,11 +90,13 @@ OTHER_FILES += \
$$PWD/data/icons/qt144.png \
$$PWD/data/icons/qt32.ico \
$$PWD/data/icons/qtmulti.ico \
- $$PWD/mock-delegates/QtWebEngine/UIDelegates/AlertDialog.qml \
- $$PWD/mock-delegates/QtWebEngine/UIDelegates/ConfirmDialog.qml \
- $$PWD/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml \
- $$PWD/mock-delegates/QtWebEngine/UIDelegates/PromptDialog.qml \
- $$PWD/mock-delegates/QtWebEngine/UIDelegates/qmldir \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/AlertDialog.qml \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/ConfirmDialog.qml \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/FilePicker.qml \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/Menu.qml \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/MenuItem.qml \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/PromptDialog.qml \
+ $$PWD/mock-delegates/QtWebEngine/Controls1Delegates/qmldir \
$$PWD/mock-delegates/TestParams/FilePickerParams.qml \
$$PWD/mock-delegates/TestParams/JSDialogParams.qml \
$$PWD/mock-delegates/TestParams/qmldir \
@@ -98,7 +104,7 @@ OTHER_FILES += \
load(qt_build_paths)
DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$PWD$${QMAKE_DIR_SEP}data)\\\"
-!isQMLTestSupportApiEnabled() {
+!qtConfig(webengine-testsupport) {
PLUGIN_EXTENSION = .so
PLUGIN_PREFIX = lib
osx: PLUGIN_PREFIX = .dylib
@@ -113,6 +119,6 @@ DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$PWD$${QMAKE_DIR_SEP}data)\\\"
warning("QML Test Support API is disabled. This means some QML tests that use Test Support API will fail.")
warning("Use the following command to build Test Support module and rebuild WebEngineView API:")
- warning("cd $$BUILD_DIR && qmake WEBENGINE_CONFIG+=testsupport -r $$shell_path($$SRC_DIR/qtwebengine.pro) && make -C $$shell_path($$BUILD_DIR/src/webengine) clean && make")
+ warning("cd $$BUILD_DIR && qmake -r $$shell_path($$SRC_DIR/qtwebengine.pro -- --feature-testsupport=yes) && make -C $$shell_path($$BUILD_DIR/src/webengine) clean && make")
warning("After performing the command above make sure QML module \"QtWebEngine.testsupport\" is deployed at $$TESTSUPPORT_MODULE")
}
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index 5dc909709..2aa24b76c 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -114,8 +114,17 @@ int main(int argc, char **argv)
// Force to use English language for testing due to error message checks
QLocale::setDefault(QLocale("en"));
- if (!QCoreApplication::instance())
- app.reset(new Application(argc, argv));
+ static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
+ QVector<const char *> w_argv(argc); \
+ for (int i = 0; i < argc; ++i) \
+ w_argv[i] = argv[i]; \
+ for (int i = 0; i < params.size(); ++i) \
+ w_argv.append(params[i].data()); \
+ int w_argc = w_argv.size(); \
+
+ if (!QCoreApplication::instance()) {
+ app.reset(new Application(w_argc, const_cast<char **>(w_argv.data())));
+ }
QtWebEngine::initialize();
QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
index abdbbc495..734c4ff7a 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
@@ -102,7 +102,7 @@ QUrl tst_QQuickWebEngineDefaultSurfaceFormat::urlFromTestPath(const char *localF
void tst_QQuickWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat()
{
-#if !defined(Q_OS_MACOSX)
+#if !defined(Q_OS_MACOS)
QSKIP("OpenGL Core Profile is currently only supported on macOS.");
#endif
// Setting a new default QSurfaceFormat with a core OpenGL profile, before
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index 2cde59454..831039266 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -3,3 +3,9 @@ windows
[inputEventForwardingDisabledWhenActiveFocusOnPressDisabled]
*
+
+[transparentWebEngineViews]
+*
+
+[basicRenderingSanity]
+*
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
index df9b3e1b7..25bf44597 100644
--- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
+++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
@@ -5,7 +5,7 @@ QT_PRIVATE += webengine-private gui-private
HEADERS += ../shared/util.h
-use?(pdf) {
+qtConfig(webengine-printing-and-pdf) {
DEFINES += ENABLE_PDF
}
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index c5718dc1f..a64197b1c 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -37,6 +37,7 @@
#include <QtWebEngine/QQuickWebEngineProfile>
#include <private/qinputmethod_p.h>
#include <private/qquickwebengineview_p.h>
+#include <private/qquickwebenginesettings_p.h>
#include <qpa/qplatforminputcontext.h>
#include <functional>
@@ -387,7 +388,8 @@ void tst_QQuickWebEngineView::titleUpdate()
titleSpy.clear();
- // No titleChanged signal for failed load
+ // No titleChanged signal for failed load (with no error-page)
+ webEngineView()->settings()->setErrorPageEnabled(false);
webEngineView()->setUrl(urlFromTestPath("html/file_that_does_not_exist.html"));
QVERIFY(waitForLoadFailed(webEngineView()));
QCOMPARE(titleSpy.size(), 0);
@@ -439,19 +441,30 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
void tst_QQuickWebEngineView::inputMethod()
{
-#if !defined(QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD)
- QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
-#else
+ m_window->show();
+ QTRY_VERIFY(qApp->focusObject());
+ QQuickItem *input;
+
QQuickWebEngineView *view = webEngineView();
+ view->settings()->setFocusOnNavigationEnabled(true);
view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QVERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+
runJavaScript("document.getElementById('inputField').focus();");
+ QTRY_COMPARE(activeElementId(view), QStringLiteral("inputField"));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_VERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+
runJavaScript("document.getElementById('inputField').blur();");
+ QTRY_VERIFY(activeElementId(view).isEmpty());
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_VERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
-#endif
}
class TestInputContext : public QPlatformInputContext
@@ -500,6 +513,7 @@ void tst_QQuickWebEngineView::interruptImeTextComposition()
QQuickItem *input;
QQuickWebEngineView *view = webEngineView();
+ view->settings()->setFocusOnNavigationEnabled(true);
view->loadHtml("<html><body>"
" <input type='text' id='input1' /><br>"
" <input type='text' id='input2' />"
@@ -533,7 +547,7 @@ void tst_QQuickWebEngineView::interruptImeTextComposition()
#ifndef Q_OS_WIN
QTRY_COMPARE(testContext.commitCallCount, 1);
#else
- QTRY_COMPARE(testContext.resetCallCount, 2);
+ QTRY_COMPARE(testContext.resetCallCount, 1);
#endif
// Check the composition text has been committed
@@ -545,33 +559,43 @@ void tst_QQuickWebEngineView::interruptImeTextComposition()
void tst_QQuickWebEngineView::inputMethodHints()
{
-#if !defined(QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD)
- QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
-#else
- QQuickWebEngineView *view = webEngineView();
+ m_window->show();
+ QTRY_VERIFY(qApp->focusObject());
+ QQuickItem *input;
+ QQuickWebEngineView *view = webEngineView();
+ view->settings()->setFocusOnNavigationEnabled(true);
view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
+ // Initialize input fields with values to check input method query is being updated.
+ runJavaScript("document.getElementById('emailInputField').value = 'a@b.com';");
+ runJavaScript("document.getElementById('editableDiv').innerText = 'bla';");
+
// Setting focus on an input element results in an element in its shadow tree becoming the focus node.
// Input hints should not be set from this shadow tree node but from the input element itself.
runJavaScript("document.getElementById('emailInputField').focus();");
+ QTRY_COMPARE(activeElementId(view), QStringLiteral("emailInputField"));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_COMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("a@b.com"));
+ QVERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QInputMethodQueryEvent query(Qt::ImHints);
- QGuiApplication::sendEvent(view, &query);
- Qt::InputMethodHints hints(query.value(Qt::ImHints).toUInt() & Qt::ImhExclusiveInputMask);
- QCOMPARE(hints, Qt::ImhEmailCharactersOnly);
+ QGuiApplication::sendEvent(input, &query);
+ QTRY_COMPARE(Qt::InputMethodHints(query.value(Qt::ImHints).toUInt() & Qt::ImhExclusiveInputMask), Qt::ImhEmailCharactersOnly);
// The focus of an editable DIV is given directly to it, so no shadow root element
// is necessary. This tests the WebPage::editorState() method ability to get the
// right element without breaking.
runJavaScript("document.getElementById('editableDiv').focus();");
+ QTRY_COMPARE(activeElementId(view), QStringLiteral("editableDiv"));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_COMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("bla"));
+ QVERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
query = QInputMethodQueryEvent(Qt::ImHints);
- QGuiApplication::sendEvent(view, &query);
- hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt());
- QCOMPARE(hints, Qt::ImhNone);
-#endif
+ QGuiApplication::sendEvent(input, &query);
+ QTRY_COMPARE(Qt::InputMethodHints(query.value(Qt::ImHints).toUInt()), Qt::ImhPreferLowercase | Qt::ImhMultiLine);
}
void tst_QQuickWebEngineView::setZoomFactor()
@@ -632,6 +656,7 @@ void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled()
QQuickWebEngineView *view = webEngineView();
m_window->show();
+ view->settings()->setFocusOnNavigationEnabled(true);
view->setSize(QSizeF(640, 480));
view->setEnabled(viewEnabled);
view->loadHtml("<html><head><title>Title</title></head><body>Hello"
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro b/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
index 9471def00..2a2155e44 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
+++ b/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
@@ -1,4 +1,4 @@
include(../tests.pri)
CONFIG -= testcase # remove, once this passes in the CI
exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
-QT_PRIVATE += webengine-private
+QT_PRIVATE += webengine-private gui-private
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 8733ccac1..e67cf0ed0 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -1,3 +1,5 @@
+QT_FOR_CONFIG += webengine-private
+
TEMPLATE = subdirs
SUBDIRS += \
@@ -6,7 +8,7 @@ SUBDIRS += \
qquickwebenginedefaultsurfaceformat \
qquickwebengineview
-isQMLTestSupportApiEnabled() {
+qtConfig(webengine-testsupport) {
SUBDIRS += \
qmltests \
qquickwebengineviewgraphics
diff --git a/tests/auto/quick/shared/util.h b/tests/auto/quick/shared/util.h
index 619a02d67..bfe3ff9c6 100644
--- a/tests/auto/quick/shared/util.h
+++ b/tests/auto/quick/shared/util.h
@@ -116,7 +116,7 @@ inline bool waitForViewportReady(QQuickWebEngineView *webEngineView, int timeout
Q_UNUSED(timeout)
qFatal("Test Support API is disabled. The result is not reliable.\
Use the following command to build Test Support module and rebuild WebEngineView API:\
- qmake -r WEBENGINE_CONFIG+=testsupport && make");
+ qmake -r -- --feature-testsupport=yes && make");
return false;
#endif
}
@@ -160,4 +160,26 @@ inline QPoint elementCenter(QQuickWebEngineView *view, const QString &id)
return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
}
+inline QString activeElementId(QQuickWebEngineView *webEngineView)
+{
+ qRegisterMetaType<QQuickWebEngineView::JavaScriptConsoleMessageLevel>("JavaScriptConsoleMessageLevel");
+ QSignalSpy consoleMessageSpy(webEngineView, &QQuickWebEngineView::javaScriptConsoleMessage);
+
+ webEngineView->runJavaScript(
+ "if (document.activeElement == null)"
+ " console.log('');"
+ "else"
+ " console.log(document.activeElement.id);"
+ );
+
+ if (!consoleMessageSpy.wait())
+ return QString();
+
+ QList<QVariant> arguments = consoleMessageSpy.takeFirst();
+ if (static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(arguments.at(0).toInt()) != QQuickWebEngineView::InfoMessageLevel)
+ return QString();
+
+ return arguments.at(1).toString();
+}
+
#endif /* UTIL_H */
diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri
index e00537b9e..7983a248f 100644
--- a/tests/auto/quick/tests.pri
+++ b/tests/auto/quick/tests.pri
@@ -1,3 +1,6 @@
+include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri)
+QT_FOR_CONFIG += webengine-private
+
TEMPLATE = app
CONFIG += testcase
@@ -16,7 +19,7 @@ QT += testlib network quick webengine
# This define is used by some tests to look up resources in the source tree
DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD/\\\"
-isQMLTestSupportApiEnabled() {
+qtConfig(webengine-testsupport) {
DEFINES += ENABLE_QML_TESTSUPPORT_API
}