diff options
Diffstat (limited to 'tests/auto/quick/qmltests')
52 files changed, 2584 insertions, 97 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..976de88a9 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** 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 + + 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 + var handleCertificateError = function(error) { + if (deferError) + error.defer() + else if (acceptCertificate) + error.acceptCertificate() + else + error.rejectCertificate() + } + view.certificateError.connect(handleCertificateError) + + 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()) + + view.certificateError.disconnect(handleCertificateError) + } + + function test_fatalError() { + var handleCertificateError = function(error) { + verify(!error.overrideable); + // QQuickWebEngineViewPrivate::allowCertificateError() will implicitly reject + // fatal errors and it should not crash if already rejected in handler. + error.rejectCertificate(); + } + view.certificateError.connect(handleCertificateError); + + view.url = Qt.resolvedUrl('https://revoked.badssl.com'); + if (!view.waitForLoadFailed(10000)) + skip("Couldn't load page from network, skipping test."); + compare(spyError.count, 1); + + view.certificateError.disconnect(handleCertificateError); + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml index 1b1750dd8..8607d846d 100644 --- a/tests/auto/quick/qmltests/data/tst_download.qml +++ b/tests/auto/quick/qmltests/data/tst_download.qml @@ -155,7 +155,7 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1) compare(downloadUrl, webEngineView.url) compare(suggestedFileName, "download.zip") - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested) + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested) verify(!downloadInterruptReason) } @@ -179,11 +179,11 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1) compare(downloadUrl, webEngineView.url) compare(suggestedFileName, "download.zip") - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested) - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress) + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested) + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadInProgress) downloadFinishedSpy.wait() compare(totalBytes, receivedBytes) - tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted) + tryCompare(downloadState, "2", WebEngineDownloadRequest.DownloadCompleted) verify(!downloadInterruptReason) } @@ -196,8 +196,8 @@ TestWebEngineView { compare(downloadUrl, webEngineView.url) compare(suggestedFileName, "download.zip") compare(downloadFinishedSpy.count, 1) - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadCancelled) - tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadItem.UserCanceled) + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadCancelled) + tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadRequest.UserCanceled) } function test_downloadLocation() { @@ -230,15 +230,15 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1); compare(downloadUrl, webEngineView.url); compare(suggestedFileName, "download.zip"); - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested); - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress); + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested); + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadInProgress); compare(downloadedPath, testDownloadProfile.downloadPath + downloadDirectory + downloadFileName); compare(downloadDirectoryChanged, 1); compare(downloadFileNameChanged, 1); compare(downloadPathChanged, 2); downloadFinishedSpy.wait(); compare(totalBytes, receivedBytes); - tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted); + tryCompare(downloadState, "2", WebEngineDownloadRequest.DownloadCompleted); verify(!downloadInterruptReason); } @@ -253,15 +253,15 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1); compare(downloadUrl, webEngineView.url); compare(suggestedFileName, "download.zip"); - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested); - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress); + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested); + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadInProgress); compare(downloadedPath, testDownloadProfile.downloadPath + downloadDirectory + "download.zip"); compare(downloadDirectoryChanged, 1); compare(downloadFileNameChanged, 0); compare(downloadPathChanged, 1); downloadFinishedSpy.wait(); compare(totalBytes, receivedBytes); - tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted); + tryCompare(downloadState, "2", WebEngineDownloadRequest.DownloadCompleted); verify(!downloadInterruptReason); // Download the same file to another directory with suggested file name. @@ -277,15 +277,15 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1); compare(downloadUrl, webEngineView.url); compare(suggestedFileName, "download.zip"); - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested); - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress); + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested); + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadInProgress); compare(downloadedPath, testDownloadProfile.downloadPath + downloadDirectory + "download.zip"); compare(downloadDirectoryChanged, 1); compare(downloadFileNameChanged, 0); compare(downloadPathChanged, 1); downloadFinishedSpy.wait(); compare(totalBytes, receivedBytes); - tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted); + tryCompare(downloadState, "2", WebEngineDownloadRequest.DownloadCompleted); verify(!downloadInterruptReason); // Download same file to same directory second time -> file name should be unified. @@ -301,15 +301,15 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1); compare(downloadUrl, webEngineView.url); compare(suggestedFileName, "download.zip"); - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested); - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress); + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested); + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadInProgress); compare(downloadedPath, testDownloadProfile.downloadPath + downloadDirectory + "download (1).zip"); compare(downloadDirectoryChanged, 1); compare(downloadFileNameChanged, 1); compare(downloadPathChanged, 1); downloadFinishedSpy.wait(); compare(totalBytes, receivedBytes); - tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted); + tryCompare(downloadState, "2", WebEngineDownloadRequest.DownloadCompleted); verify(!downloadInterruptReason); } @@ -323,15 +323,15 @@ TestWebEngineView { compare(downLoadRequestedSpy.count, 1); compare(downloadUrl, webEngineView.url); compare(suggestedFileName, "download.zip"); - compare(downloadState[0], WebEngineDownloadItem.DownloadRequested); - tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress); + compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested); + tryCompare(downloadState, "1", WebEngineDownloadRequest.DownloadInProgress); compare(downloadedPath, testDownloadProfile.downloadPath + downloadedSetPath); compare(downloadDirectoryChanged, 1); compare(downloadFileNameChanged, 1); compare(downloadPathChanged, 2); downloadFinishedSpy.wait(); compare(totalBytes, receivedBytes); - tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted); + tryCompare(downloadState, "2", WebEngineDownloadRequest.DownloadCompleted); verify(!downloadInterruptReason); } } 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..a521ea0d6 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** 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()); + + // Navigate away from page with onbeforeunload handler, + // otherwise it would trigger an extra dialog request when + // navigating in the subsequent test. + webEngineView.url = Qt.resolvedUrl("about:blank"); + verify(webEngineView.waitForLoadSucceeded()); + compare(JSDialogParams.dialogCount, 2) + } + + 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()); + + // Navigate away from page with onbeforeunload handler, + // otherwise it would trigger an extra dialog request when + // navigating in the subsequent test. + JSDialogParams.shouldAcceptDialog = true; + webEngineView.url = Qt.resolvedUrl("about:blank"); + verify(webEngineView.waitForLoadSucceeded()); + compare(JSDialogParams.dialogCount, 2) + } + + 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() == "" }); + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml index f4fcc30ab..4d0bd28bf 100644 --- a/tests/auto/quick/qmltests/data/tst_userScripts.qml +++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml @@ -31,32 +31,33 @@ import QtTest 1.0 import QtWebEngine 1.2 Item { - WebEngineScript { - id: changeDocumentTitleScript - sourceUrl: Qt.resolvedUrl("change-document-title.js") - injectionPoint: WebEngineScript.DocumentReady + + function changeDocumentTitleScript() { + return { name: "changeDocumentTitleScript", + sourceUrl: Qt.resolvedUrl("change-document-title.js"), + injectionPoint: WebEngineScript.DocumentReady } } - WebEngineScript { - id: appendDocumentTitleScript - sourceUrl: Qt.resolvedUrl("append-document-title.js") - injectionPoint: WebEngineScript.DocumentReady + function appendDocumentTitleScript() { + return { sourceUrl: Qt.resolvedUrl("append-document-title.js"), + injectionPoint: WebEngineScript.DocumentReady } } - WebEngineScript { - id: bigUserScript - sourceUrl: Qt.resolvedUrl("big-user-script.js") - injectionPoint: WebEngineScript.DocumentReady + function bigUserScript() { + return { sourceUrl: Qt.resolvedUrl("big-user-script.js"), + injectionPoint: WebEngineScript.DocumentReady } } - WebEngineScript { - id: scriptWithMetadata - sourceUrl: Qt.resolvedUrl("script-with-metadata.js") + function scriptWithMetadata() { + var script = WebEngine.script() + script.sourceUrl = Qt.resolvedUrl("script-with-metadata.js") + return script } - WebEngineScript { - id: scriptWithBadMatchMetadata - sourceUrl: Qt.resolvedUrl("script-with-bad-match-metadata.js") + function scriptWithBadMatchMetadata() { + var script = WebEngine.script() + script.sourceUrl = Qt.resolvedUrl("script-with-bad-match-metadata.js") + return script } TestWebEngineView { @@ -79,21 +80,22 @@ Item { onNavigationRequested: { var urlString = request.url.toString(); if (urlString.indexOf("test1.html") !== -1) - userScripts = [ changeDocumentTitleScript ]; + userScripts.collection = [ changeDocumentTitleScript() ]; else if (urlString.indexOf("test2.html") !== -1) - userScripts = [ appendDocumentTitleScript ]; + userScripts.collection = [ appendDocumentTitleScript() ]; else - userScripts = []; + userScripts.collection = []; } } TestCase { name: "WebEngineViewUserScripts" + function init() { webEngineView.url = ""; - webEngineView.userScripts = []; - webEngineView.profile.userScripts = []; + webEngineView.userScripts.collection = []; + webEngineView.profile.userScripts.collection = []; } function test_oneScript() { @@ -101,7 +103,8 @@ Item { webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page 1"); - webEngineView.userScripts = [ changeDocumentTitleScript ]; + webEngineView.userScripts.collection = [ changeDocumentTitleScript() ] + compare(webEngineView.title, "Test page 1"); webEngineView.reload(); @@ -112,7 +115,7 @@ Item { webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "New title"); - webEngineView.userScripts = []; + webEngineView.userScripts.collection = []; compare(webEngineView.title, "New title"); webEngineView.reload(); @@ -124,23 +127,25 @@ Item { webEngineView.url = Qt.resolvedUrl("test1.html"); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page 1"); - - webEngineView.userScripts = [ changeDocumentTitleScript, appendDocumentTitleScript ]; + var script1 = changeDocumentTitleScript(); + var script2 = appendDocumentTitleScript(); + script2.injectionPoint = WebEngineScript.Deferred; + webEngineView.userScripts.collection = [ script1, script2 ]; // Make sure the scripts are loaded in order. - appendDocumentTitleScript.injectionPoint = WebEngineScript.Deferred webEngineView.reload(); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "New title with appendix"); - appendDocumentTitleScript.injectionPoint = WebEngineScript.DocumentReady - changeDocumentTitleScript.injectionPoint = WebEngineScript.Deferred + script2.injectionPoint = WebEngineScript.DocumentReady + script1.injectionPoint = WebEngineScript.Deferred + webEngineView.userScripts.collection = [ script1, script2 ]; webEngineView.reload(); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "New title"); // Make sure we can remove scripts from the preload list. - webEngineView.userScripts = [ appendDocumentTitleScript ]; + webEngineView.userScripts.collection = [ script2 ]; webEngineView.reload(); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page 1 with appendix"); @@ -163,17 +168,18 @@ Item { } function test_bigScript() { - webEngineView.userScripts = [ bigUserScript ]; + webEngineView.userScripts.collection = [ bigUserScript() ]; webEngineView.url = Qt.resolvedUrl("test1.html"); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView , "title", "Big user script changed title"); } function test_parseMetadataHeader() { - compare(scriptWithMetadata.name, "Test script"); - compare(scriptWithMetadata.injectionPoint, WebEngineScript.DocumentReady); + var script = scriptWithMetadata() + compare(script.name, "Test script"); + compare(script.injectionPoint, WebEngineScript.DocumentReady); - webEngineView.userScripts = [ scriptWithMetadata ]; + webEngineView.userScripts.collection = [ script ]; // @include *data/test*.html webEngineView.url = Qt.resolvedUrl("test1.html"); @@ -197,10 +203,11 @@ Item { } function test_dontInjectBadUrlPatternsEverywhere() { - compare(scriptWithBadMatchMetadata.name, "Test bad match script"); - compare(scriptWithBadMatchMetadata.injectionPoint, WebEngineScript.DocumentReady); + var script = scriptWithBadMatchMetadata(); + compare(script.name, "Test bad match script"); + compare(script.injectionPoint, WebEngineScript.DocumentReady); - webEngineView.userScripts = [ scriptWithBadMatchMetadata ]; + webEngineView.userScripts.collection = [ script ]; // @match some:junk webEngineView.url = Qt.resolvedUrl("test2.html"); @@ -209,7 +216,7 @@ Item { } function test_profileWideScript() { - webEngineView.profile.userScripts = [ changeDocumentTitleScript ]; + webEngineView.profile.userScripts.collection = [ changeDocumentTitleScript() ]; webEngineView.url = Qt.resolvedUrl("test1.html"); webEngineView.waitForLoadSucceeded(); diff --git a/tests/auto/quick/qmltests/data/tst_viewSoure.qml b/tests/auto/quick/qmltests/data/tst_viewSoure.qml new file mode 100644 index 000000000..997582335 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_viewSoure.qml @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** 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.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 + + property var viewRequest: null + property var loadRequestArray: [] + + testSupport: WebEngineTestSupport { + errorPage.onLoadingChanged: { + loadRequestArray.push({ + "status": loadRequest.status, + }) + } + } + + onLoadingChanged: { + loadRequestArray.push({ + "status": loadRequest.status, + }); + } + + SignalSpy { + id: newViewRequestedSpy + target: webEngineView + signalName: "newViewRequested" + } + + SignalSpy { + id: titleChangedSpy + target: webEngineView + signalName: "titleChanged" + } + + onNewViewRequested: { + viewRequest = { + "destination": request.destination, + "userInitiated": request.userInitiated + }; + + request.openIn(webEngineView); + } + + TestCase { + id: test + name: "WebEngineViewSource" + + function init() { + webEngineView.loadStatus = null; + webEngineView.url = Qt.resolvedUrl("test1.html"); + tryCompare(webEngineView, "loadStatus", WebEngineView.LoadSucceededStatus); + webEngineView.loadStatus = null; + + newViewRequestedSpy.clear(); + titleChangedSpy.clear(); + viewRequest = null; + } + + function test_viewSourceURL_data() { + var testLocalUrl = "view-source:" + Qt.resolvedUrl("test1.html"); + var testLocalUrlWithoutScheme = "view-source:" + Qt.resolvedUrl("test1.html").toString().substring(7); + + return [ + { tag: "view-source:", userInputUrl: "view-source:", loadSucceed: true, url: "view-source:", title: "view-source:" }, + { 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: "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" }, + ]; + } + + function test_viewSourceURL(row) { + loadRequestArray = []; + WebEngine.settings.errorPageEnabled = true + webEngineView.url = row.userInputUrl; + + if (row.loadSucceed) { + tryVerify(function() { return loadRequestArray.length >= 2 }); + compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus); + } else { + tryVerify(function() { return loadRequestArray.length >= 2 }); + compare(loadRequestArray[1].status, WebEngineView.LoadFailedStatus); + tryVerify(function() { return loadRequestArray.length == 4 }); + compare(loadRequestArray[3].status, WebEngineView.LoadSucceededStatus); + } + tryVerify(function() { return titleChangedSpy.count == 1; }); + + compare(webEngineView.url, row.url); + tryCompare(webEngineView, "title", row.title); + if (row.loadSucceed) { + verify(!webEngineView.action(WebEngineView.ViewSource).enabled); + } else { + verify(webEngineView.action(WebEngineView.ViewSource).enabled); + } + } + } +} + diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/AlertDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/AlertDialog.qml new file mode 100644 index 000000000..4ba3be4b9 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/AlertDialog.qml @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// Both dialogs are basically expected to behave in the same way from an API point of view +ConfirmDialog +{ +} diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/ConfirmDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/ConfirmDialog.qml new file mode 100644 index 000000000..9933fc2f7 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/ConfirmDialog.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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 QtQml 2.0 +import QtTest 1.0 +import "../../TestParams" 1.0 + +QtObject { + property string text; + property string title; + signal accepted(); + signal rejected(); + + function open() { + JSDialogParams.dialogTitle = title; + JSDialogParams.dialogMessage = text; + JSDialogParams.dialogCount++; + if (JSDialogParams.shouldAcceptDialog) + accepted() + else + rejected() + } +} + diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/FilePicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/FilePicker.qml new file mode 100644 index 000000000..745f533f5 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/FilePicker.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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.2 +import "../../TestParams" 1.0 + +QtObject { + property bool selectMultiple: false; + property bool selectExisting: false; + property bool selectFolder: false; + property var nameFilters: []; + + signal filesSelected(var fileList); + signal rejected(); + + function open() { + FilePickerParams.filePickerOpened = true; + FilePickerParams.nameFilters = nameFilters; + if (FilePickerParams.selectFiles) + filesSelected(FilePickerParams.selectedFilesUrl) + else + rejected() + } +} 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/mock-delegates/QtWebEngine/Controls1Delegates/PromptDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/PromptDialog.qml new file mode 100644 index 000000000..7c5b16eab --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/PromptDialog.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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 QtQml 2.0 +import QtTest 1.0 +import "../../TestParams" 1.0 + +QtObject { + property string text; + property string title; + signal accepted(); + signal rejected(); + signal input(string text); + signal closing(); + + function open() { + JSDialogParams.dialogTitle = title; + JSDialogParams.dialogMessage = text; + JSDialogParams.dialogCount++; + if (JSDialogParams.shouldAcceptDialog) { + input(JSDialogParams.inputForPrompt) + accepted() + } else { + rejected() + } + } +} diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/qmldir b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/qmldir new file mode 100644 index 000000000..cf8ac0512 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/Controls1Delegates/qmldir @@ -0,0 +1,5 @@ +module QtWebEngine.UIDelegates +AlertDialog 1.0 AlertDialog.qml +ConfirmDialog 1.0 ConfirmDialog.qml +FilePicker 1.0 FilePicker.qml +PromptDialog 1.0 PromptDialog.qml diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml new file mode 100644 index 000000000..02b0da1d4 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +pragma Singleton +import QtQuick 2.0 + +QtObject { + property var selectedFilesUrl: []; + property bool selectFiles: false; + property bool filePickerOpened: false; + property var nameFilters: []; +} diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml new file mode 100644 index 000000000..70696803c --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +pragma Singleton +import QtQml 2.0 + +QtObject { + property string dialogMessage: ""; + property string dialogTitle: ""; + property bool shouldAcceptDialog: true; + property string inputForPrompt; + property int dialogCount: 0 +} diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir b/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir new file mode 100644 index 000000000..5807f1e6e --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir @@ -0,0 +1,4 @@ +# QML module so that the autotests can set testing parameters +module TestParams +singleton FilePickerParams 1.0 FilePickerParams.qml +singleton JSDialogParams 1.0 JSDialogParams.qml diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro index a50bfd7e6..5b2ea5d01 100644 --- a/tests/auto/quick/qmltests/qmltests.pro +++ b/tests/auto/quick/qmltests/qmltests.pro @@ -1,18 +1,110 @@ +include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) # workaround for QTBUG-68093 +QT_FOR_CONFIG += webengine-private + include(../tests.pri) -include(../../shared/http.pri) QT += qmltest - +DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$OUT_PWD$${QMAKE_DIR_SEP}webengine.qmltests)\\\" IMPORTPATH += $$PWD/data +QML_TESTS = \ + $$PWD/data/tst_action.qml \ + $$PWD/data/tst_activeFocusOnPress.qml \ + $$PWD/data/tst_audioMuted.qml \ + $$PWD/data/tst_desktopBehaviorLoadHtml.qml \ + $$PWD/data/tst_findText.qml \ + $$PWD/data/tst_focusOnNavigation.qml \ + $$PWD/data/tst_geopermission.qml \ + $$PWD/data/tst_getUserMedia.qml \ + $$PWD/data/tst_keyboardEvents.qml \ + $$PWD/data/tst_keyboardModifierMapping.qml \ + $$PWD/data/tst_loadHtml.qml \ + $$PWD/data/tst_loadProgress.qml \ + $$PWD/data/tst_loadRecursionCrash.qml \ + $$PWD/data/tst_loadUrl.qml \ + $$PWD/data/tst_mouseMove.qml \ + $$PWD/data/tst_navigationHistory.qml \ + $$PWD/data/tst_navigationRequested.qml \ + $$PWD/data/tst_newViewRequest.qml \ + $$PWD/data/tst_notification.qml \ + $$PWD/data/tst_profile.qml \ + $$PWD/data/tst_properties.qml \ + $$PWD/data/tst_runJavaScript.qml \ + $$PWD/data/tst_scrollPosition.qml \ + $$PWD/data/tst_settings.qml \ + $$PWD/data/tst_titleChanged.qml \ + $$PWD/data/tst_unhandledKeyEventPropagation.qml \ + $$PWD/data/tst_userScripts.qml \ + $$PWD/data/tst_viewSource.qml + +qtConfig(webengine-webchannel) { + QML_TESTS += $$PWD/data/tst_webchannel.qml +} + +qtConfig(ssl) { + include(../../shared/https.pri) + QML_TESTS += $$PWD/data/tst_certificateError.qml +} else { + include(../../shared/http.pri) +} + +qtConfig(webengine-testsupport) { + QML_TESTS += \ + $$PWD/data/tst_favicon.qml \ + $$PWD/data/tst_faviconDownload.qml \ + $$PWD/data/tst_inputMethod.qml \ + $$PWD/data/tst_linkHovered.qml \ + $$PWD/data/tst_loadFail.qml \ + $$PWD/data/tst_mouseClick.qml \ + $$PWD/data/tst_viewSoure.qml + qtHaveModule(quickcontrols): QML_TESTS += $$PWD/data/tst_javaScriptDialogs.qml +} else { + PLUGIN_EXTENSION = .so + PLUGIN_PREFIX = lib + macos: PLUGIN_PREFIX = .dylib + win32 { + PLUGIN_EXTENSION = .dll + PLUGIN_PREFIX = + } + + TESTSUPPORT_MODULE = $$shell_path($$[QT_INSTALL_QML]/QtWebEngine/testsupport/$${PLUGIN_PREFIX}qtwebenginetestsupportplugin$${PLUGIN_EXTENSION}) + BUILD_DIR = $$shell_path($$clean_path($$OUT_PWD/../../../..)) + SRC_DIR = $$shell_path($$clean_path($$PWD/../../../..)) + + 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 -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") +} + +qtHaveModule(quickcontrols) { + QML_TESTS += \ + $$PWD/data/tst_contextMenu.qml \ + $$PWD/data/tst_download.qml \ + $$PWD/data/tst_filePicker.qml +} + OTHER_FILES += \ $$PWD/data/TestWebEngineView.qml \ + $$PWD/data/accepttypes.html \ + $$PWD/data/alert.html \ + $$PWD/data/confirm.html \ + $$PWD/data/confirmclose.html \ $$PWD/data/append-document-title.js \ $$PWD/data/big-user-script.js \ $$PWD/data/change-document-title.js \ $$PWD/data/download.zip \ $$PWD/data/directoryupload.html \ $$PWD/data/favicon.html \ + $$PWD/data/favicon2.html \ + $$PWD/data/favicon-candidates-gray.html \ + $$PWD/data/favicon-misc.html \ + $$PWD/data/favicon-multi.html \ + $$PWD/data/favicon-multi-gray.html \ + $$PWD/data/favicon-single.html \ + $$PWD/data/favicon-shortcut.html \ + $$PWD/data/favicon-touch.html \ + $$PWD/data/favicon-unavailable.html \ $$PWD/data/forms.html \ $$PWD/data/geolocation.html \ $$PWD/data/javascript.html \ @@ -30,40 +122,35 @@ OTHER_FILES += \ $$PWD/data/keyboardModifierMapping.html \ $$PWD/data/keyboardEvents.html \ $$PWD/data/titleupdate.js \ - $$PWD/data/tst_action.qml \ - $$PWD/data/tst_activeFocusOnPress.qml \ - $$PWD/data/tst_audioMuted.qml \ - $$PWD/data/tst_contextMenu.qml \ - $$PWD/data/tst_desktopBehaviorLoadHtml.qml \ - $$PWD/data/tst_download.qml \ - $$PWD/data/tst_filePicker.qml \ - $$PWD/data/tst_findText.qml \ - $$PWD/data/tst_focusOnNavigation.qml \ - $$PWD/data/tst_geopermission.qml \ - $$PWD/data/tst_getUserMedia.qml \ - $$PWD/data/tst_loadHtml.qml \ - $$PWD/data/tst_loadProgress.qml \ - $$PWD/data/tst_loadRecursionCrash.qml \ - $$PWD/data/tst_loadUrl.qml \ - $$PWD/data/tst_mouseMove.qml \ - $$PWD/data/tst_navigationHistory.qml \ - $$PWD/data/tst_navigationRequested.qml \ - $$PWD/data/tst_newViewRequest.qml \ - $$PWD/data/tst_notification.qml \ - $$PWD/data/tst_profile.qml \ - $$PWD/data/tst_properties.qml \ - $$PWD/data/tst_runJavaScript.qml \ - $$PWD/data/tst_scrollPosition.qml \ - $$PWD/data/tst_titleChanged.qml \ - $$PWD/data/tst_unhandledKeyEventPropagation.qml \ - $$PWD/data/tst_userScripts.qml \ - $$PWD/data/tst_viewSource.qml \ - $$PWD/data/tst_webchannel.qml \ - $$PWD/data/tst_settings.qml \ - $$PWD/data/tst_keyboardModifierMapping.qml \ - $$PWD/data/tst_keyboardEvents.qml \ - $$PWD/data/webchannel-test.html \ $$PWD/data/icons/favicon.png \ + $$PWD/data/icons/gray128.png \ + $$PWD/data/icons/gray16.png \ + $$PWD/data/icons/gray255.png \ + $$PWD/data/icons/gray32.png \ + $$PWD/data/icons/gray64.png \ + $$PWD/data/icons/grayicons.ico \ + $$PWD/data/icons/qt144.png \ + $$PWD/data/icons/qt32.ico \ + $$PWD/data/icons/qtmulti.ico \ + $$PWD/data/icons/small-favicon.png \ + $$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 + +OTHER_FILES += $$QML_TESTS + +!build_pass:!isEmpty(QML_TESTS) { + for (file, QML_TESTS): QML_TESTS_CONTENT += "$${file}" + TEST_FILE = $$OUT_PWD/webengine.qmltests + write_file($$TEST_FILE, QML_TESTS_CONTENT) +} load(qt_build_paths) -DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$PWD$${QMAKE_DIR_SEP}data)\\\" + diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp index 5677f9047..8423df1bd 100644 --- a/tests/auto/quick/qmltests/tst_qmltests.cpp +++ b/tests/auto/quick/qmltests/tst_qmltests.cpp @@ -28,6 +28,10 @@ #include <httpserver.h> +#if QT_CONFIG(ssl) +#include <httpsserver.h> +#endif + #include <QtCore/QScopedPointer> #include <QTemporaryDir> #include <QtQuickTest/quicktest.h> @@ -130,7 +134,7 @@ int main(int argc, char **argv) QLocale::setDefault(QLocale("en")); static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")}; - QVector<const char *> w_argv(argc); \ + QList<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) \ @@ -151,6 +155,12 @@ int main(int argc, char **argv) return server; }); +#if QT_CONFIG(ssl) + qmlRegisterSingletonType<HttpsServer>( + "Test.Shared", 1, 0, "HttpsServer", + [&](QQmlEngine *, QJSEngine *) { return new HttpsServer; }); +#endif + int i = quick_test_main(argc, argv, "qmltests", QUICK_TEST_SOURCE_DIR); return i; } |