diff options
author | Michal Klocek <michal.klocek@qt.io> | 2020-08-13 09:54:15 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2020-09-17 14:43:16 +0200 |
commit | adaf70ce2b61590180207af34ad47ddd6fabafc2 (patch) | |
tree | 5cfacf95729b1705a11f208054218083def0efe7 /tests/auto/quick/qmltests/data | |
parent | e2ca6dc90e8d598fc7e6af14bd2b0e0613fb2839 (diff) |
Fix qmltest duplication mess
We had split qmltest directory since we could not run qml tests
without test support, however this duplicated quite a lot files.
Moreover adding more fine-grained checks would mean creating
even more copies.
Generate test list on qmake call, so we can fine-grained which test
should be run.
Change-Id: I093bdd6deeca50a1936a72276d7d6af12a376c45
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'tests/auto/quick/qmltests/data')
37 files changed, 1849 insertions, 0 deletions
diff --git a/tests/auto/quick/qmltests/data/accepttypes.html b/tests/auto/quick/qmltests/data/accepttypes.html new file mode 100644 index 000000000..aff39f96e --- /dev/null +++ b/tests/auto/quick/qmltests/data/accepttypes.html @@ -0,0 +1,21 @@ +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>Default title</title> +</head> + +<body> +<input type="file" name="file" id="upfile" accept=""> + +<script> +window.onload = function() { + document.getElementById("upfile").focus(); +} + +function setAcceptType(acceptType) { + document.getElementById("upfile").accept = acceptType; + document.title = acceptType; +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/alert.html b/tests/auto/quick/qmltests/data/alert.html new file mode 100644 index 000000000..89715a727 --- /dev/null +++ b/tests/auto/quick/qmltests/data/alert.html @@ -0,0 +1,5 @@ +<html> +<head> + <script> alert("Hello Qt"); </script> +</head> +</html> diff --git a/tests/auto/quick/qmltests/data/confirm.html b/tests/auto/quick/qmltests/data/confirm.html new file mode 100644 index 000000000..a4fc5b532 --- /dev/null +++ b/tests/auto/quick/qmltests/data/confirm.html @@ -0,0 +1,10 @@ +<html> +<head> + <script> + if (confirm("Confirm test")) + document.title += " ACCEPTED"; + else + document.title += " REJECTED"; + </script> +</head> +</html> diff --git a/tests/auto/quick/qmltests/data/confirmclose.html b/tests/auto/quick/qmltests/data/confirmclose.html new file mode 100644 index 000000000..c2acbb67f --- /dev/null +++ b/tests/auto/quick/qmltests/data/confirmclose.html @@ -0,0 +1,6 @@ +<html> +<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/directoryupload.html b/tests/auto/quick/qmltests/data/directoryupload.html new file mode 100644 index 000000000..adc408ebb --- /dev/null +++ b/tests/auto/quick/qmltests/data/directoryupload.html @@ -0,0 +1,17 @@ +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title> Directory Upload </title> +<script src = "./titleupdate.js"> +</script> +</head> + +<body> +<input type="file" id="upfile" webkitdirectory="" directory="" onchange="updateTitle()"> +<script> +window.onload = function() { +document.getElementById("upfile").focus() +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-candidates-gray.html b/tests/auto/quick/qmltests/data/favicon-candidates-gray.html new file mode 100644 index 000000000..ebea35b02 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-candidates-gray.html @@ -0,0 +1,29 @@ +<html> + <head> + <title>Gray Candidate Favicons Test</title> + <link rel="shortcut icon" href="icons/gray16.png" /> + <link rel="shortcut icon" href="icons/gray32.png" /> + <link rel="shortcut icon" href="icons/gray64.png" /> + <link rel="shortcut icon" href="icons/gray128.png" /> + <link rel="shortcut icon" href="icons/gray255.png" /> + </head> + <body> + <h1>Gray Candidate Favicons Test</h1> + <table style="width:100%"> + <tr> + <td align="center"><img src="icons/gray16.png" height="16" width="16" border="1" /></td> + <td align="center"><img src="icons/gray32.png" height="32" width="32" border="1" /></td> + <td align="center"><img src="icons/gray64.png" height="64" width="64" border="1" /></td> + <td align="center"><img src="icons/gray128.png" height="128" width="128" border="1" /></td> + <td align="center"><img src="icons/gray255.png" height="255" width="255" border="1" /></td> + </tr> + <tr> + <td align="center">16x16</td> + <td align="center">32x32</td> + <td align="center">64x64</td> + <td align="center">128x128</td> + <td align="center">255x255</td> + </tr> + </table> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-misc.html b/tests/auto/quick/qmltests/data/favicon-misc.html new file mode 100644 index 000000000..9e788bdf4 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-misc.html @@ -0,0 +1,11 @@ +<html> + <head> + <title>Favicon Test</title> + <link rel="shortcut icon" href="icons/qt32.ico" /> + <link rel="apple-touch-icon" href="icons/qt144.png" /> + <link rel="shortcut icon" href="icons/unavailable.ico" /> + </head> + <body> + <h1>Favicon Test</h1> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-multi-gray.html b/tests/auto/quick/qmltests/data/favicon-multi-gray.html new file mode 100644 index 000000000..24b71640f --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-multi-gray.html @@ -0,0 +1,25 @@ +<html> + <head> + <title>Gray Multi-sized Favicon Test</title> + <link rel="shortcut icon" href="icons/grayicons.ico" /> + </head> + <body> + <h1>Gray Multi-sized Favicon Test</h1> + <table style="width:100%"> + <tr> + <td align="center"><img src="icons/gray16.png" height="16" width="16" border="1" /></td> + <td align="center"><img src="icons/gray32.png" height="32" width="32" border="1" /></td> + <td align="center"><img src="icons/gray64.png" height="64" width="64" border="1" /></td> + <td align="center"><img src="icons/gray128.png" height="128" width="128" border="1" /></td> + <td align="center"><img src="icons/gray255.png" height="255" width="255" border="1" /></td> + </tr> + <tr> + <td align="center">16x16</td> + <td align="center">32x32</td> + <td align="center">64x64</td> + <td align="center">128x128</td> + <td align="center">255x255</td> + </tr> + </table> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-multi.html b/tests/auto/quick/qmltests/data/favicon-multi.html new file mode 100644 index 000000000..cc5f3fd66 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-multi.html @@ -0,0 +1,9 @@ +<html> + <head> + <title>Multi-sized Favicon Test</title> + <link rel="shortcut icon" sizes="16x16 32x23 64x64" href="icons/qtmulti.ico" /> + </head> + <body> + <h1>Multi-sized Favicon Test</h1> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-shortcut.html b/tests/auto/quick/qmltests/data/favicon-shortcut.html new file mode 100644 index 000000000..786cdb816 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-shortcut.html @@ -0,0 +1,10 @@ +<html> + <head> + <title>Favicon Test</title> + <link rel="shortcut icon" href="icons/qt32.ico" /> + <link rel="shortcut icon" href="icons/qt144.png" /> + </head> + <body> + <h1>Favicon Test</h1> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-single.html b/tests/auto/quick/qmltests/data/favicon-single.html new file mode 100644 index 000000000..eb4675c75 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-single.html @@ -0,0 +1,9 @@ +<html> + <head> + <title>Favicon Test</title> + <link rel="shortcut icon" href="icons/qt32.ico" /> + </head> + <body> + <h1>Favicon Test</h1> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-touch.html b/tests/auto/quick/qmltests/data/favicon-touch.html new file mode 100644 index 000000000..271783434 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-touch.html @@ -0,0 +1,10 @@ +<html> + <head> + <title>Favicon Test</title> + <link rel="apple-touch-icon" href="icons/qt32.ico" /> + <link rel="apple-touch-icon" href="icons/qt144.png" /> + </head> + <body> + <h1>Favicon Test</h1> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon-unavailable.html b/tests/auto/quick/qmltests/data/favicon-unavailable.html new file mode 100644 index 000000000..c45664294 --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon-unavailable.html @@ -0,0 +1,9 @@ +<html> + <head> + <title>Favicon Test</title> + <link rel="shortcut icon" href="icons/unavailable.ico" /> + </head> + <body> + <h1>Favicon Test</h1> + </body> +</html> diff --git a/tests/auto/quick/qmltests/data/favicon2.html b/tests/auto/quick/qmltests/data/favicon2.html new file mode 100644 index 000000000..81c2690fe --- /dev/null +++ b/tests/auto/quick/qmltests/data/favicon2.html @@ -0,0 +1,10 @@ +<html> +<head> +</head> +<link type="image/png" href="icons/small-favicon.png" sizes="16x16" rel="icon" /> +<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/small-favicon.png"/> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/icons/gray128.png b/tests/auto/quick/qmltests/data/icons/gray128.png Binary files differnew file mode 100644 index 000000000..bf1cfaba0 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/gray128.png diff --git a/tests/auto/quick/qmltests/data/icons/gray16.png b/tests/auto/quick/qmltests/data/icons/gray16.png Binary files differnew file mode 100644 index 000000000..2a1a91a76 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/gray16.png diff --git a/tests/auto/quick/qmltests/data/icons/gray255.png b/tests/auto/quick/qmltests/data/icons/gray255.png Binary files differnew file mode 100644 index 000000000..549169551 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/gray255.png diff --git a/tests/auto/quick/qmltests/data/icons/gray32.png b/tests/auto/quick/qmltests/data/icons/gray32.png Binary files differnew file mode 100644 index 000000000..b269a528f --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/gray32.png diff --git a/tests/auto/quick/qmltests/data/icons/gray64.png b/tests/auto/quick/qmltests/data/icons/gray64.png Binary files differnew file mode 100644 index 000000000..e02559e5b --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/gray64.png diff --git a/tests/auto/quick/qmltests/data/icons/grayicons.ico b/tests/auto/quick/qmltests/data/icons/grayicons.ico Binary files differnew file mode 100644 index 000000000..8d8fee839 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/grayicons.ico diff --git a/tests/auto/quick/qmltests/data/icons/qt144.png b/tests/auto/quick/qmltests/data/icons/qt144.png Binary files differnew file mode 100644 index 000000000..050b1e066 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/qt144.png diff --git a/tests/auto/quick/qmltests/data/icons/qt32.ico b/tests/auto/quick/qmltests/data/icons/qt32.ico Binary files differnew file mode 100644 index 000000000..2f6fcb5bc --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/qt32.ico diff --git a/tests/auto/quick/qmltests/data/icons/qtmulti.ico b/tests/auto/quick/qmltests/data/icons/qtmulti.ico Binary files differnew file mode 100644 index 000000000..81e5a22e8 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/qtmulti.ico diff --git a/tests/auto/quick/qmltests/data/icons/small-favicon.png b/tests/auto/quick/qmltests/data/icons/small-favicon.png Binary files differnew file mode 100644 index 000000000..8cf9a50a4 --- /dev/null +++ b/tests/auto/quick/qmltests/data/icons/small-favicon.png diff --git a/tests/auto/quick/qmltests/data/multifileupload.html b/tests/auto/quick/qmltests/data/multifileupload.html new file mode 100644 index 000000000..d41ea15c0 --- /dev/null +++ b/tests/auto/quick/qmltests/data/multifileupload.html @@ -0,0 +1,18 @@ +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title> Failed to Upload </title> +<script src = "./titleupdate.js"> +</script> +</head> + +<body> +<input type="file" name="file" id="upfile" onchange="updateTitle()" multiple/> + +<script> +window.onload = function() { +document.getElementById("upfile").focus() +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/prompt.html b/tests/auto/quick/qmltests/data/prompt.html new file mode 100644 index 000000000..3293c0dcf --- /dev/null +++ b/tests/auto/quick/qmltests/data/prompt.html @@ -0,0 +1,7 @@ +<html> +<head> + <script> + document.title = prompt("Please, reverse the default value", "Hello Qt"); + </script> +</head> +</html> diff --git a/tests/auto/quick/qmltests/data/singlefileupload.html b/tests/auto/quick/qmltests/data/singlefileupload.html new file mode 100644 index 000000000..ac91c2c0d --- /dev/null +++ b/tests/auto/quick/qmltests/data/singlefileupload.html @@ -0,0 +1,18 @@ +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title> Failed to Upload </title> +<script src = "./titleupdate.js"> +</script> +</head> + +<body> +<input type="file" name="file" id="upfile" onchange="updateTitle()"/> + +<script> +window.onload = function() { +document.getElementById("upfile").focus() +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/titleupdate.js b/tests/auto/quick/qmltests/data/titleupdate.js new file mode 100644 index 000000000..c86139c13 --- /dev/null +++ b/tests/auto/quick/qmltests/data/titleupdate.js @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** 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: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$ +** +****************************************************************************/ + +function updateTitle() +{ + var inp = document.getElementById("upfile"); + var allfiles = new String(""); + var name = new String(""); + for (var i = 0; i < inp.files.length; ++i) { + name = inp.files.item(i).name; + if (allfiles.length == 0) + allfiles = name; + else + allfiles = allfiles + "," + name; + } + document.title = allfiles; +} diff --git a/tests/auto/quick/qmltests/data/tst_certificateError.qml b/tests/auto/quick/qmltests/data/tst_certificateError.qml new file mode 100644 index 000000000..a4bd9597a --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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.9 + +import Test.Shared 1.0 as Shared + +TestWebEngineView { + id: view; width: 320; height: 320 + + property bool deferError: false + property bool acceptCertificate: false + + onCertificateError: function(error) { + if (deferError) + error.defer() + else if (acceptCertificate) + error.acceptCertificate() + else + error.rejectCertificate() + } + + SignalSpy { + id: spyError + target: view + signalName: 'certificateError' + } + + TestCase { + name: 'CertificateError' + when: windowShown + + function initTestCase() { + Shared.HttpsServer.setExpectError(true) + Shared.HttpsServer.newRequest.connect(function (request) { + request.setResponseBody('<html><body>Test</body></html>') + request.sendResponse() + }) + view.settings.errorPageEnabled = false + } + + function init() { + verify(Shared.HttpsServer.start()) + } + + function cleanup() { + Shared.HttpsServer.stop() + view.deferError = false + view.acceptCertificate = false + spyError.clear() + } + + function test_error_data() { + return [ + { tag: 'reject', deferError: false, acceptCertificate: false, expectedContent: '' }, + { tag: 'defer_reject', deferError: true, acceptCertificate: false, expectedContent: '' }, + { tag: 'defer_accept', deferError: true, acceptCertificate: true, expectedContent: 'Test' }, + ] + } + + function test_error(data) { + view.deferError = data.deferError + view.acceptCertificate = data.acceptCertificate + view.url = Shared.HttpsServer.url() + + if (data.deferError) { + spyError.wait() + compare(spyError.count, 1) + compare('', view.getBodyText()) + + let error = spyError.signalArguments[0][0] + if (data.acceptCertificate) + error.acceptCertificate() + else + error.rejectCertificate() + } + + if (data.acceptCertificate) + verify(view.waitForLoadSucceeded()) + else + verify(view.waitForLoadFailed()) + + compare(spyError.count, 1) + compare(data.expectedContent, view.getBodyText()) + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml new file mode 100644 index 000000000..3f522d91a --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_favicon.qml @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** 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: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.3 +import QtWebEngine.testsupport 1.0 +import QtQuick.Window 2.0 +import "../../qmltests/data" 1.0 + +TestWebEngineView { + id: webEngineView + width: 200 + height: 400 + + testSupport: WebEngineTestSupport { + property var errorPageLoadStatus: null + + function waitForErrorPageLoadSucceeded() { + var success = _waitFor(function() { return testSupport.errorPageLoadStatus == WebEngineView.LoadSucceededStatus }) + testSupport.errorPageLoadStatus = null + return success + } + + errorPage.onLoadingChanged: { + errorPageLoadStatus = loadRequest.status + } + } + + function removeFaviconProviderPrefix(url) { + return url.toString().substring(16) + } + + function getFaviconPixel(faviconImage) { + var grabImage = Qt.createQmlObject(" + import QtQuick 2.5\n + Image { }", test) + var faviconCanvas = Qt.createQmlObject(" + import QtQuick 2.5\n + Canvas { }", test) + + test.tryVerify(function() { return faviconImage.status == Image.Ready }); + faviconImage.grabToImage(function(result) { + grabImage.source = result.url + }); + test.tryVerify(function() { return grabImage.status == Image.Ready }); + + faviconCanvas.width = faviconImage.width; + faviconCanvas.height = faviconImage.height; + var ctx = faviconCanvas.getContext("2d"); + ctx.drawImage(grabImage, 0, 0, grabImage.width, grabImage.height); + var imageData = ctx.getImageData(Math.round(faviconCanvas.width/2), + Math.round(faviconCanvas.height/2), + faviconCanvas.width, + faviconCanvas.height); + + grabImage.destroy(); + faviconCanvas.destroy(); + + return imageData.data; + } + + SignalSpy { + id: iconChangedSpy + target: webEngineView + signalName: "iconChanged" + } + + Image { + id: favicon + source: webEngineView.icon + } + + TestCase { + id: test + name: "WebEngineFavicon" + when: windowShown + + + function init() { + // It is worth to restore the initial state with loading a blank page before all test functions. + webEngineView.url = 'about:blank' + verify(webEngineView.waitForLoadSucceeded()) + iconChangedSpy.clear() + } + + function test_faviconLoad() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("favicon.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + compare(iconChangedSpy.count, 1) + + compare(favicon.width, 48) + compare(favicon.height, 48) + } + + function test_faviconLoadEncodedUrl() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("favicon2.html?favicon=load should work with#whitespace!") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + compare(iconChangedSpy.count, 1) + + compare(favicon.width, 16) + compare(favicon.height, 16) + } + + function test_noFavicon() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("test1.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + } + + function test_aboutBlank() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("about:blank") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + } + + function test_unavailableFavicon() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("favicon-unavailable.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + } + + function test_errorPageEnabled() { + WebEngine.settings.errorPageEnabled = true + + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("http://url.invalid") + webEngineView.url = url + verify(webEngineView.waitForLoadFailed(20000)) + verify(webEngineView.testSupport.waitForErrorPageLoadSucceeded()) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + } + + function test_errorPageDisabled() { + WebEngine.settings.errorPageEnabled = false + + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("http://url.invalid") + webEngineView.url = url + verify(webEngineView.waitForLoadFailed(20000)) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + } + + function test_bestFavicon() { + compare(iconChangedSpy.count, 0) + var url, iconUrl + + url = Qt.resolvedUrl("favicon-misc.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + compare(iconChangedSpy.count, 1) + + iconUrl = removeFaviconProviderPrefix(webEngineView.icon) + // Touch icon is ignored + compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico")) + compare(favicon.width, 32) + compare(favicon.height, 32) + + iconChangedSpy.clear() + + url = Qt.resolvedUrl("favicon-shortcut.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + verify(iconChangedSpy.count >= 1) + iconUrl = removeFaviconProviderPrefix(webEngineView.icon) + + // If the icon URL is empty we have to wait for + // the second iconChanged signal that propagates the expected URL + if (iconUrl == Qt.resolvedUrl("")) { + tryCompare(iconChangedSpy, "count", 2) + iconUrl = removeFaviconProviderPrefix(webEngineView.icon) + } + + compare(iconUrl, Qt.resolvedUrl("icons/qt144.png")) + compare(favicon.width, 144) + compare(favicon.height, 144) + } + + function test_touchIcon() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("favicon-touch.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + compare(favicon.width, 0) + compare(favicon.height, 0) + + WebEngine.settings.touchIconsEnabled = true + + url = Qt.resolvedUrl("favicon-touch.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + iconUrl = removeFaviconProviderPrefix(webEngineView.icon) + compare(iconUrl, Qt.resolvedUrl("icons/qt144.png")) + compare(iconChangedSpy.count, 1) + compare(favicon.width, 144) + compare(favicon.height, 144) + } + + function test_multiIcon() { + compare(iconChangedSpy.count, 0) + + var url = Qt.resolvedUrl("favicon-multi.html") + webEngineView.url = url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + compare(iconChangedSpy.count, 1) + compare(favicon.width, 64) + compare(favicon.height, 64) + } + + function test_faviconProvider_data() { + return [ + { tag: "multi 8x8", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 8, value: 16 }, + { tag: "multi 16x16", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 16, value: 16 }, + { tag: "multi 17x17", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 17, value: 32 }, + { tag: "multi 31x31", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 31, value: 32 }, + { tag: "multi 32x32", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 32, value: 32 }, + { tag: "multi 33x33", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 33, value: 64 }, + { tag: "multi 64x64", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 64, value: 64 }, + { tag: "multi 128x128", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 128, value: 128 }, + { tag: "multi 255x255", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 255, value: 255 }, + { tag: "multi 256x256", url: Qt.resolvedUrl("favicon-multi-gray.html"), size: 256, value: 255 }, + { tag: "candidate 8x8", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 8, value: 16 }, + { tag: "candidate 16x16", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 16, value: 16 }, + { tag: "candidate 17x17", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 17, value: 32 }, + { tag: "candidate 31x31", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 31, value: 32 }, + { tag: "candidate 32x32", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 32, value: 32 }, + { tag: "candidate 33x33", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 33, value: 64 }, + { tag: "candidate 64x64", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 64, value: 64 }, + { tag: "candidate 128x128", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 128, value: 128 }, + { tag: "candidate 255x255", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 255, value: 255 }, + { tag: "candidate 256x256", url: Qt.resolvedUrl("favicon-candidates-gray.html"), size: 256, value: 255 }, + ]; + } + + function test_faviconProvider(row) { + var faviconImage = Qt.createQmlObject(" + import QtQuick 2.5\n + Image { sourceSize: Qt.size(width, height) }", test) + + compare(iconChangedSpy.count, 0) + + webEngineView.url = row.url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + compare(iconChangedSpy.count, 1) + + faviconImage.width = row.size / Screen.devicePixelRatio + faviconImage.height = row.size / Screen.devicePixelRatio + faviconImage.source = webEngineView.icon + + var pixel = getFaviconPixel(faviconImage); + compare(pixel[0], row.value) + + faviconImage.destroy() + } + + function test_dynamicFavicon() { + var faviconImage = Qt.createQmlObject(" + import QtQuick 2.5\n + Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", test) + faviconImage.source = Qt.binding(function() { return webEngineView.icon; }); + + var colors = [ + {"url": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==", "r": 255, "g": 0, "b": 0}, + {"url": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg==", "r": 0, "g": 255, "b": 0}, + {"url": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg==", "r": 0, "g": 0, "b": 255}, + ]; + var pixel; + + compare(iconChangedSpy.count, 0); + webEngineView.loadHtml( + "<html>" + + "<link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='/>" + + "</html>" + ); + verify(webEngineView.waitForLoadSucceeded()); + tryCompare(iconChangedSpy, "count", 1); + + pixel = getFaviconPixel(faviconImage); + compare(pixel[0], 0); + compare(pixel[1], 0); + compare(pixel[2], 0); + + for (var i = 0; i < colors.length; ++i) { + iconChangedSpy.clear(); + runJavaScript("document.getElementsByTagName('link')[0].href = 'data:image/png;base64," + colors[i]["url"] + "';"); + tryCompare(faviconImage, "source", "image://favicon/data:image/png;base64," + colors[i]["url"]); + compare(iconChangedSpy.count, 1); + + pixel = getFaviconPixel(faviconImage); + compare(pixel[0], colors[i]["r"]); + compare(pixel[1], colors[i]["g"]); + compare(pixel[2], colors[i]["b"]); + } + + faviconImage.destroy() + } + + function test_touchIconWithSameURL() + { + WebEngine.settings.touchIconsEnabled = false; + + var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="; + + webEngineView.loadHtml( + "<html>" + + "<link rel='icon' type='image/png' href='" + icon + "'/>" + + "<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>" + + "</html>" + ); + verify(webEngineView.waitForLoadSucceeded()); + + // The default favicon has to be loaded even if its URL is also set as a touch icon while touch icons are disabled. + tryCompare(iconChangedSpy, "count", 1); + compare(webEngineView.icon.toString().replace(/^image:\/\/favicon\//, ''), icon); + + iconChangedSpy.clear(); + + webEngineView.loadHtml( + "<html>" + + "<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>" + + "</html>" + ); + verify(webEngineView.waitForLoadSucceeded()); + + // This page only has a touch icon. With disabled touch icons we don't expect any icon to be shown even if the same icon + // was loaded previously. + tryCompare(iconChangedSpy, "count", 1); + verify(!webEngineView.icon.toString().replace(/^image:\/\/favicon\//, '')); + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml new file mode 100644 index 000000000..9aa32279c --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** 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: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.3 +import "../../qmltests/data" 1.0 + +TestWebEngineView { + id: webEngineView + width: 200 + height: 400 + + function removeFaviconProviderPrefix(url) { + return url.toString().substring(16) + } + + SignalSpy { + id: iconChangedSpy + target: webEngineView + signalName: "iconChanged" + } + + TestCase { + id: test + name: "WebEngineFaviconDownload" + + function init() { + WebEngine.settings.autoLoadIconsForPage = true + WebEngine.settings.touchIconsEnabled = false + + if (webEngineView.icon != '') { + // If this is not the first test, then load a blank page without favicon, restoring the initial state. + webEngineView.url = 'about:blank' + verify(webEngineView.waitForLoadSucceeded()) + iconChangedSpy.wait() + } + + iconChangedSpy.clear() + } + + function cleanupTestCase() { + WebEngine.settings.autoLoadIconsForPage = true + WebEngine.settings.touchIconsEnabled = false + } + + function test_downloadIconsDisabled_data() { + return [ + { tag: "misc", url: Qt.resolvedUrl("favicon-misc.html") }, + { tag: "shortcut", url: Qt.resolvedUrl("favicon-shortcut.html") }, + { tag: "single", url: Qt.resolvedUrl("favicon-single.html") }, + { tag: "touch", url: Qt.resolvedUrl("favicon-touch.html") }, + { tag: "unavailable", url: Qt.resolvedUrl("favicon-unavailable.html") }, + ]; + } + + function test_downloadIconsDisabled(row) { + WebEngine.settings.autoLoadIconsForPage = false + + compare(iconChangedSpy.count, 0) + + webEngineView.url = row.url + verify(webEngineView.waitForLoadSucceeded()) + + compare(iconChangedSpy.count, 0) + + var iconUrl = webEngineView.icon + compare(iconUrl, Qt.resolvedUrl("")) + } + + function test_downloadTouchIconsEnabled_data() { + return [ + { tag: "misc", url: Qt.resolvedUrl("favicon-misc.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") }, + { tag: "shortcut", url: Qt.resolvedUrl("favicon-shortcut.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") }, + { tag: "single", url: Qt.resolvedUrl("favicon-single.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt32.ico") }, + { tag: "touch", url: Qt.resolvedUrl("favicon-touch.html"), expectedIconUrl: Qt.resolvedUrl("icons/qt144.png") }, + ]; + } + + function test_downloadTouchIconsEnabled(row) { + WebEngine.settings.touchIconsEnabled = true + + compare(iconChangedSpy.count, 0) + + webEngineView.url = row.url + verify(webEngineView.waitForLoadSucceeded()) + + iconChangedSpy.wait() + compare(iconChangedSpy.count, 1) + + var iconUrl = removeFaviconProviderPrefix(webEngineView.icon) + compare(iconUrl, row.expectedIconUrl) + } + } +} + diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml new file mode 100644 index 000000000..ab30d9e82 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml @@ -0,0 +1,310 @@ +/**************************************************************************** +** +** 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: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.2 +import "../../qmltests/data" 1.0 +import "../mock-delegates/TestParams" 1.0 + +TestWebEngineView { + id: webEngineView + width: 400 + height: 300 + property var titleChanges: [] + + function driveLetter() { + if (Qt.platform.os !== "windows") + return ""; + return "C:/"; + } + + SignalSpy { + id: titleSpy + target: webEngineView + signalName: "titleChanged" + } + SignalSpy { + id: terminationSpy + target: webEngineView + signalName: "renderProcessTerminated" + } + + onTitleChanged: { titleChanges.push(webEngineView.title) } + + TestCase { + name: "WebEngineViewSingleFileUpload" + when: windowShown + + function init() { + FilePickerParams.filePickerOpened = false + FilePickerParams.selectFiles = false + FilePickerParams.selectedFilesUrl = [] + FilePickerParams.nameFilters = [] + titleSpy.clear() + terminationSpy.clear() + titleChanges = [] + } + + function cleanup() { + // Test that the render process doesn't crash, and make sure if it does it does so now. + wait(100) + verify(terminationSpy.count == 0, "Render process didn't self terminate") + + // FIXME: Almost every second url loading progress does get stuck at about 90 percent, so the loadFinished signal won't arrive. + // This cleanup function is a workaround for this problem. + webEngineView.url = Qt.resolvedUrl("about:blank") + webEngineView.waitForLoadSucceeded() + } + + function test_acceptSingleFileSelection_data() { + return [ + { tag: "test.txt", input: "test.txt", expected: "Failed to Upload" }, + { tag: driveLetter() + "/test.txt", input: driveLetter() + "/test.txt", expected: "test.txt" }, + { tag: driveLetter() + "/tést.txt", input: driveLetter() + "/tést.txt", expected: "tést.txt" }, + { tag: driveLetter() + "/t%65st.txt", input: driveLetter() + "/t%65st.txt", expected: "t%65st.txt" }, + { tag: "file:///" + driveLetter() + "test.txt", input: "file:///" + driveLetter() + "test.txt", expected: "test.txt" }, + { tag: "file:///" + driveLetter() + "tést.txt", input: "file:///" + driveLetter() + "tést.txt", expected: "tést.txt" }, + { tag: "file:///" + driveLetter() + "t%65st.txt", input: "file:///" + driveLetter() + "t%65st.txt", expected: "t%65st.txt" }, + { tag: "file://" + driveLetter() + "test.txt", input: "file://" + driveLetter() + "test.txt", expected: "Failed to Upload" }, + { tag: "file:/" + driveLetter() + "test.txt", input: "file:/" + driveLetter() + "test.txt", expected: "test.txt"}, + { tag: "file:test//test.txt", input: "file:test//test.txt", expected: "Failed to Upload" }, + { tag: "http://test.txt", input: "http://test.txt", expected: "Failed to Upload" }, + { tag: "qrc:/test.txt", input: "qrc:/test.txt", expected: "Failed to Upload" }, + ]; + } + + function test_acceptSingleFileSelection(row) { + var expectedFileName; + + // Default dialog + webEngineView.url = Qt.resolvedUrl("singlefileupload.html"); + verify(webEngineView.waitForLoadSucceeded()); + + FilePickerParams.selectFiles = true; + FilePickerParams.selectedFilesUrl.push(row.input); + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryCompare(FilePickerParams, "filePickerOpened", true); + webEngineView.url = Qt.resolvedUrl("about:blank"); + verify(webEngineView.waitForLoadSucceeded()); + tryCompare(webEngineView, "title", "about:blank"); + compare(titleChanges[titleChanges.length-2], row.expected); + + + // Custom dialog + var finished = false; + + function acceptedFileHandler(request) { + request.accepted = true; + request.dialogAccept(row.input); + finished = true; + } + + webEngineView.fileDialogRequested.connect(acceptedFileHandler); + webEngineView.url = Qt.resolvedUrl("singlefileupload.html"); + verify(webEngineView.waitForLoadSucceeded()); + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryVerify(function() { return finished; }); + webEngineView.url = Qt.resolvedUrl("about:blank"); + verify(webEngineView.waitForLoadSucceeded()); + tryCompare(webEngineView, "title", "about:blank"); + compare(titleChanges[titleChanges.length-2], row.expected); + webEngineView.fileDialogRequested.disconnect(acceptedFileHandler); + } + + function test_acceptMultipleFilesSelection() { + webEngineView.url = Qt.resolvedUrl("multifileupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + FilePickerParams.selectFiles = true + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test1.html")) + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test2.html")) + + keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + tryCompare(FilePickerParams, "filePickerOpened", true) + tryCompare(webEngineView, "title", "test1.html,test2.html") + } + + function test_acceptDirectory() { + webEngineView.url = Qt.resolvedUrl("directoryupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + FilePickerParams.selectFiles = true + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data")) + + keyClick(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + tryCompare(FilePickerParams, "filePickerOpened", true) + // Check that the title is a file list (eg. "test1.html,test2.html") + tryVerify(function() { return webEngineView.title.match("^([^,]+,)+[^,]+$"); }) + } + + function test_reject() { + webEngineView.url = Qt.resolvedUrl("singlefileupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + titleSpy.clear() + keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + wait(100) + compare(titleSpy.count, 0) + } + + function test_acceptMultipleFilesWithCustomDialog_data() { + return [ + { tag: "path", input: [driveLetter() + "/test1.txt", driveLetter() + "/test2.txt"], expectedValue: "test1.txt,test2.txt" }, + { tag: "file", input: ["file:///" + driveLetter() + "test1.txt", "file:/" + driveLetter() + "test2.txt"], expectedValue: "test1.txt,test2.txt" }, + { tag: "mixed", input: ["file:///" + driveLetter() + "test1.txt", driveLetter() + "/test2.txt"], expectedValue: "test1.txt,test2.txt" }, + ]; + } + + function test_acceptMultipleFilesWithCustomDialog(row) { + // Default dialog + webEngineView.url = Qt.resolvedUrl("multifileupload.html"); + verify(webEngineView.waitForLoadSucceeded()); + + FilePickerParams.selectFiles = true; + FilePickerParams.selectedFilesUrl = row.input; + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryCompare(FilePickerParams, "filePickerOpened", true); + tryCompare(webEngineView, "title", row.expectedValue); + + + // Custom dialog + var finished = false; + + function acceptedFileHandler(request) { + request.accepted = true; + request.dialogAccept(row.input); + finished = true; + } + + webEngineView.fileDialogRequested.connect(acceptedFileHandler); + webEngineView.url = Qt.resolvedUrl("multifileupload.html"); + verify(webEngineView.waitForLoadSucceeded()); + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryVerify(function() { return finished; }); + tryCompare(webEngineView, "title", row.expectedValue); + webEngineView.fileDialogRequested.disconnect(acceptedFileHandler); + } + + function test_acceptFileOnWindows_data() { + return [ + { tag: "C:test.txt", input: "C:test.txt", expected: "Failed to Upload"}, + { tag: "C:test:txt", input: "C:test:txt", expected: "Failed to Upload"}, + { tag: "C:/test.txt", input: "C:/test.txt", expected: "test.txt"}, + { tag: "C:\\test.txt", input: "C:\\test.txt", expected: "test.txt"}, + { tag: "C:\\Documents and Settings\\test\\test.txt", input: "C:\\Documents and Settings\\test\\test.txt", expected: "test.txt"}, + { tag: "\\\\applib\\products\\a%2Db\\ abc%5F9\\t.est\\test.txt", input: "\\\\applib\\products\\a%2Db\\ abc%5F9\\t.est\\test.txt", expected: "test.txt"}, + { tag: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", input: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", expected: "test.txt"}, + { tag: "file://applib/products/a-b/abc_1/t.est/test.txt", input: "file://applib/products/a-b/abc_1/t.est/test.txt", expected: "test.txt"}, + { tag: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", input: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", expected: "test.txt"}, + { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "test.tx"}, + { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "test.tx"}, + { tag: "file://C:/test.txt", input: "file://C:/test.txt", expected: "Failed to Upload"}, + { tag: "file:///C:test.txt", input: "file:///C:test.txt", expected: "Failed to Upload"}, + { tag: "file:///C:/test.txt", input: "file:///C:/test.txt", expected: "test.txt"}, + { tag: "file:///C:\\test.txt", input: "file:///C:\\test.txt", expected: "test.txt"}, + { tag: "file:\\//C:/test.txt", input: "file:\\//C:/test.txt", expected: "test.txt"}, + { tag: "file:\\\\/C:\\test.txt", input: "file:\\\\/C:\\test.txt", expected: "test.txt"}, + { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "test.tx"}, + ]; + } + + function test_acceptFileOnWindows(row) { + if (Qt.platform.os !== "windows") + skip("Windows-only test"); + + // Default dialog + webEngineView.url = Qt.resolvedUrl("singlefileupload.html"); + verify(webEngineView.waitForLoadSucceeded()); + + FilePickerParams.selectFiles = true; + FilePickerParams.selectedFilesUrl.push(row.input); + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryCompare(FilePickerParams, "filePickerOpened", true); + webEngineView.url = Qt.resolvedUrl("about:blank"); + verify(webEngineView.waitForLoadSucceeded()); + tryCompare(webEngineView, "title", "about:blank"); + compare(titleChanges[titleChanges.length-2], row.expected); + + + // Custom dialog + var finished = false; + + function acceptedFileHandler(request) { + request.accepted = true; + request.dialogAccept(row.input); + finished = true; + } + + webEngineView.fileDialogRequested.connect(acceptedFileHandler); + webEngineView.url = Qt.resolvedUrl("singlefileupload.html"); + verify(webEngineView.waitForLoadSucceeded()); + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryVerify(function() { return finished; }); + webEngineView.url = Qt.resolvedUrl("about:blank"); + verify(webEngineView.waitForLoadSucceeded()); + tryCompare(webEngineView, "title", "about:blank"); + compare(titleChanges[titleChanges.length-2], row.expected); + webEngineView.fileDialogRequested.disconnect(acceptedFileHandler); + } + + function test_acceptFileTypes_data() { + return [ + { tag: "CustomSuffix", input: ".pug", expected: ".pug", exactMatch: false}, + { tag: "CustomMime", input: "dog/pug", expected: "Accepted types ()", exactMatch: true}, + { tag: "CustomGlob", input: "dog/*", expected: "Accepted types ()", exactMatch: true}, + { tag: "Invalid", input: "---", expected: undefined, exactMatch: true}, + { tag: "Jpeg", input: "image/jpeg", expected: ".jpeg", exactMatch: false} + ]; + } + + function test_acceptFileTypes(row) { + var expectedFileName; + + webEngineView.url = Qt.resolvedUrl("accepttypes.html"); + verify(webEngineView.waitForLoadSucceeded()); + + webEngineView.runJavaScript("setAcceptType('" + row.input + "');"); + tryCompare(webEngineView, "title", row.input); + + keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. + tryCompare(FilePickerParams, "filePickerOpened", true); + + if (row.exactMatch) + compare(FilePickerParams.nameFilters[0], row.expected); + else + verify(FilePickerParams.nameFilters[0].includes(row.expected)); + } + } +} 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..0bf9f7eb0 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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 +import "../../qmltests/data" 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 new file mode 100644 index 000000000..658071005 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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.2 +import QtWebEngine.testsupport 1.0 +import "../../qmltests/data" 1.0 +import "../mock-delegates/TestParams" 1.0 + +TestWebEngineView { + id: webEngineView + anchors.fill: parent + + testSupport: WebEngineTestSupport { + property bool windowCloseRejectedSignalEmitted: false + + function waitForWindowCloseRejected() { + return _waitFor(function () { + return testSupport.windowCloseRejectedSignalEmitted; + }); + } + + onWindowCloseRejected: { + windowCloseRejectedSignalEmitted = true; + } + } + + TestCase { + id: test + name: "WebEngineViewJavaScriptDialogs" + when: windowShown + + function init() { + JSDialogParams.dialogMessage = ""; + JSDialogParams.dialogTitle = ""; + JSDialogParams.dialogCount = 0; + JSDialogParams.shouldAcceptDialog = true; + } + + function test_alert() { + webEngineView.url = Qt.resolvedUrl("alert.html") + verify(webEngineView.waitForLoadSucceeded()) + compare(JSDialogParams.dialogCount, 1) + compare(JSDialogParams.dialogMessage, "Hello Qt") + verify(JSDialogParams.dialogTitle.indexOf("Javascript Alert -") === 0) + } + + function test_confirm() { + webEngineView.url = Qt.resolvedUrl("confirm.html") + verify(webEngineView.waitForLoadSucceeded()) + compare(JSDialogParams.dialogMessage, "Confirm test") + compare(JSDialogParams.dialogCount, 1) + compare(webEngineView.title, "ACCEPTED") + JSDialogParams.shouldAcceptDialog = false + webEngineView.reload() + verify(webEngineView.waitForLoadSucceeded()) + compare(JSDialogParams.dialogCount, 2) + 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()); + } + + function test_rejectClose() { + webEngineView.url = Qt.resolvedUrl("confirmclose.html"); + verify(webEngineView.waitForLoadSucceeded()); + webEngineView.testSupport.windowCloseRejectedSignalEmitted = false; + JSDialogParams.shouldAcceptDialog = false; + + simulateUserGesture() + webEngineView.triggerWebAction(WebEngineView.RequestClose); + verify(webEngineView.testSupport.waitForWindowCloseRejected()); + } + + function test_prompt() { + JSDialogParams.inputForPrompt = "tQ olleH" + webEngineView.url = Qt.resolvedUrl("prompt.html") + verify(webEngineView.waitForLoadSucceeded()) + compare(JSDialogParams.dialogCount, 1) + compare(webEngineView.title, "tQ olleH") + JSDialogParams.shouldAcceptDialog = false + webEngineView.reload() + verify(webEngineView.waitForLoadSucceeded()) + compare(JSDialogParams.dialogCount, 2) + compare(webEngineView.title, "null") + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_linkHovered.qml b/tests/auto/quick/qmltests/data/tst_linkHovered.qml new file mode 100644 index 000000000..faf943c55 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_linkHovered.qml @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** 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: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.2 +import QtWebEngine.testsupport 1.0 +import "../../qmltests/data" 1.0 + +TestWebEngineView { + id: webEngineView + width: 200 + height: 400 + focus: true + + property string lastUrl + + testSupport: WebEngineTestSupport { } + + SignalSpy { + id: loadVisuallyCommittedSpy + target: webEngineView.testSupport + signalName: "loadVisuallyCommitted" + } + + SignalSpy { + id: linkHoveredSpy + target: webEngineView + signalName: "linkHovered" + } + + onLinkHovered: { + webEngineView.lastUrl = hoveredUrl + } + + TestCase { + name: "DesktopWebEngineViewLinkHovered" + + // Delayed windowShown to workaround problems with Qt5 in debug mode. + when: false + Timer { + running: parent.windowShown + repeat: false + interval: 1 + onTriggered: parent.when = true + } + + function init() { + webEngineView.lastUrl = ""; + loadVisuallyCommittedSpy.clear(); + linkHoveredSpy.clear(); + } + + function test_linkHovered() { + compare(linkHoveredSpy.count, 0); + mouseMove(webEngineView, 100, 300) + webEngineView.url = Qt.resolvedUrl("test2.html") + verify(webEngineView.waitForLoadSucceeded()) + + // We get a linkHovered signal with empty hoveredUrl after page load + linkHoveredSpy.wait(); + compare(linkHoveredSpy.count, 1); + compare(webEngineView.lastUrl, "") + + // Wait for the page to be rendered before trying to test based on input events + loadVisuallyCommittedSpy.wait(); + + mouseMove(webEngineView, 100, 100) + linkHoveredSpy.wait(12000); + compare(linkHoveredSpy.count, 2); + compare(webEngineView.lastUrl, Qt.resolvedUrl("test1.html")) + mouseMove(webEngineView, 100, 300) + linkHoveredSpy.wait(12000); + compare(linkHoveredSpy.count, 3); + compare(webEngineView.lastUrl, "") + } + + function test_linkHoveredDoesntEmitRepeated() { + compare(linkHoveredSpy.count, 0); + webEngineView.url = Qt.resolvedUrl("test2.html") + verify(webEngineView.waitForLoadSucceeded()) + + // We get a linkHovered signal with empty hoveredUrl after page load + linkHoveredSpy.wait(); + compare(linkHoveredSpy.count, 1); + compare(webEngineView.lastUrl, "") + + // Wait for the page to be rendered before trying to test based on input events + loadVisuallyCommittedSpy.wait(); + + for (var i = 0; i < 100; i += 10) + mouseMove(webEngineView, 100, 100 + i) + + linkHoveredSpy.wait(12000); + compare(linkHoveredSpy.count, 2); + compare(webEngineView.lastUrl, Qt.resolvedUrl("test1.html")) + + for (var i = 0; i < 100; i += 10) + mouseMove(webEngineView, 100, 300 + i) + + linkHoveredSpy.wait(12000); + compare(linkHoveredSpy.count, 3); + compare(webEngineView.lastUrl, "") + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml new file mode 100644 index 000000000..db412f252 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** 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: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.2 +import QtWebEngine.testsupport 1.0 +import "../../qmltests/data" 1.0 + +TestWebEngineView { + id: webEngineView + width: 400 + height: 300 + + property var unavailableUrl: Qt.resolvedUrl("file_that_does_not_exist.html") + property var loadRequestArray: [] + + testSupport: WebEngineTestSupport { + property var errorPageLoadStatus: null + + function waitForErrorPageLoadSucceeded() { + var success = _waitFor(function() { return testSupport.errorPageLoadStatus == WebEngineView.LoadSucceededStatus }) + testSupport.errorPageLoadStatus = null + return success + } + + errorPage.onLoadingChanged: { + errorPageLoadStatus = loadRequest.status + + loadRequestArray.push({ + "status": loadRequest.status, + "url": loadRequest.url.toString(), + "errorDomain": loadRequest.errorDomain, + "isErrorPage": true + }) + } + } + + onLoadingChanged: { + if (loadRequest.status == WebEngineView.LoadFailedStatus) { + test.compare(loadRequest.url, unavailableUrl) + test.compare(loadRequest.errorDomain, WebEngineView.InternalErrorDomain) + } + + loadRequestArray.push({ + "status": loadRequest.status, + "url": loadRequest.url.toString(), + "errorDomain": loadRequest.errorDomain, + "isErrorPage": false + }) + } + + TestCase { + id: test + name: "WebEngineViewLoadFail" + + function test_fail() { + WebEngine.settings.errorPageEnabled = false + webEngineView.url = unavailableUrl + verify(webEngineView.waitForLoadFailed()) + } + + function test_fail_url() { + WebEngine.settings.errorPageEnabled = false + var url = Qt.resolvedUrl("test1.html") + webEngineView.url = url + compare(webEngineView.url, url) + verify(webEngineView.waitForLoadSucceeded()) + compare(webEngineView.url, url) + + webEngineView.url = unavailableUrl + compare(webEngineView.url, unavailableUrl) + verify(webEngineView.waitForLoadFailed()) + // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored. + // We expect the url of the previously loaded page here. + compare(webEngineView.url, url) + } + + function test_error_page() { + WebEngine.settings.errorPageEnabled = true + webEngineView.url = unavailableUrl + + // Loading of the error page must be successful + verify(webEngineView.testSupport.waitForErrorPageLoadSucceeded()) + + var loadRequest = null + compare(loadRequestArray.length, 4) + + // Start to load unavailableUrl + loadRequest = loadRequestArray[0] + compare(loadRequest.status, WebEngineView.LoadStartedStatus) + compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain) + compare(loadRequest.url, unavailableUrl) + verify(!loadRequest.isErrorPage) + + // Loading of the unavailableUrl must fail + loadRequest = loadRequestArray[1] + compare(loadRequest.status, WebEngineView.LoadFailedStatus) + compare(loadRequest.errorDomain, WebEngineView.InternalErrorDomain) + compare(loadRequest.url, unavailableUrl) + verify(!loadRequest.isErrorPage) + + // Start to load error page + loadRequest = loadRequestArray[2] + compare(loadRequest.status, WebEngineView.LoadStartedStatus) + compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain) + compare(loadRequest.url, "chrome-error://chromewebdata/") + verify(loadRequest.isErrorPage) + + // Loading of the error page must be successful + loadRequest = loadRequestArray[3] + compare(loadRequest.status, WebEngineView.LoadSucceededStatus) + compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain) + compare(loadRequest.url, "chrome-error://chromewebdata/") + verify(loadRequest.isErrorPage) + + compare(webEngineView.url, unavailableUrl) + compare(webEngineView.title, unavailableUrl) + } + } +} 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..eaa012f86 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** 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 +import "../../qmltests/data" 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); + } + + function mouseQuadraClick(item, x, y) { + mouseMultiClick(item, x, y, 4); + } + } + + + 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() == "" }); + } + + function test_quadraClick() { + 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.mouseQuadraClick(webEngineView, center.x, center.y); + verifyElementHasFocus("input"); + tryVerify(function() { return getTextSelection() == "" }); + } + } +} |