summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST18
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml22
-rw-r--r--tests/auto/quick/qmltests/data/favicon-candidates-gray.html10
-rw-r--r--tests/auto/quick/qmltests/data/favicon-multi-gray.html10
-rw-r--r--tests/auto/quick/qmltests/data/keyboardEvents.html98
-rw-r--r--tests/auto/quick/qmltests/data/redirect.html3
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml19
-rw-r--r--tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml13
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardEvents.qml156
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml42
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml329
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationRequested.qml3
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml137
-rw-r--r--tests/auto/quick/qmltests/data/tst_settings.qml16
-rw-r--r--tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml8
-rw-r--r--tests/auto/quick/qmltests/data/tst_viewSource.qml12
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro4
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp20
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp28
-rw-r--r--tests/auto/widgets/qwebenginespellcheck/dict/de-DE.aff5
-rw-r--r--tests/auto/widgets/qwebenginespellcheck/dict/de-DE.dic14
-rw-r--r--tests/auto/widgets/qwebenginespellcheck/qwebenginespellcheck.pro6
-rw-r--r--tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp35
-rw-r--r--tests/auto/widgets/qwebengineview/resources/keyboardEvents.html98
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp90
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc1
-rw-r--r--tests/auto/widgets/widgets.pro9
-rw-r--r--tests/manual/manual.pro3
-rw-r--r--tests/manual/quick/faviconbrowser/AddressBar.qml124
-rw-r--r--tests/manual/quick/faviconbrowser/FaviconPanel.qml256
-rw-r--r--tests/manual/quick/faviconbrowser/faviconbrowser.pro23
-rw-r--r--tests/manual/quick/faviconbrowser/faviconbrowser.qrc17
-rw-r--r--tests/manual/quick/faviconbrowser/main.cpp76
-rw-r--r--tests/manual/quick/faviconbrowser/main.qml192
-rw-r--r--tests/manual/quick/faviconbrowser/utils.h70
-rw-r--r--tests/manual/quick/quick.pro4
36 files changed, 1732 insertions, 239 deletions
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index 16abe5ff6..d281020df 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -1,23 +1,11 @@
[DesktopWebEngineViewLinkHovered::test_linkHovered]
*
+[DesktopWebEngineViewLinkHovered::test_linkHoveredDoesntEmitRepeated]
+*
+
[WebViewGeopermission::test_deniedGeolocationByUser]
osx
[WebViewGeopermission::test_geoPermissionRequest]
osx
-
-[WebEngineViewFocusOnNavigation::test_focusOnNavigation]
-*
-
-[WebEngineViewLoadUrl::test_urlProperty]
-windows
-
-[WebEngineViewSettings::test_javascriptDisabled]
-windows
-
-[WebEngineViewUnhandledKeyEventPropagation::test_keyboardModifierMapping]
-windows
-
-[WebEngineViewSource::test_viewSourceURL]
-windows
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index 0d2a34645..aa1f77942 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -27,7 +27,7 @@
****************************************************************************/
import QtQuick 2.0
-import QtTest 1.0
+import QtTest 1.1
import QtWebEngine 1.3
WebEngineView {
@@ -62,7 +62,27 @@ WebEngineView {
return predicate()
}
+ function getActiveElementId() {
+ var activeElementId;
+ runJavaScript("document.activeElement.id", function(result) {
+ activeElementId = result;
+ });
+ testCase.tryVerify(function() { return activeElementId != undefined });
+ return activeElementId;
+ }
+
+ function verifyElementHasFocus(element) {
+ testCase.tryVerify(function() { return getActiveElementId() == element; }, 5000,
+ "Element \"" + element + "\" has focus");
+ }
+
+ function setFocusToElement(element) {
+ runJavaScript("document.getElementById('" + element + "').focus()");
+ verifyElementHasFocus(element);
+ }
+
TestResult { id: testResult }
+ TestCase { id: testCase }
onLoadingChanged: {
loadStatus = loadRequest.status
diff --git a/tests/auto/quick/qmltests/data/favicon-candidates-gray.html b/tests/auto/quick/qmltests/data/favicon-candidates-gray.html
index 3cbc4a4c3..ebea35b02 100644
--- a/tests/auto/quick/qmltests/data/favicon-candidates-gray.html
+++ b/tests/auto/quick/qmltests/data/favicon-candidates-gray.html
@@ -11,11 +11,11 @@
<h1>Gray Candidate Favicons Test</h1>
<table style="width:100%">
<tr>
- <td align="center"><img src="icons/gray16.png" height="16" width="16" /></td>
- <td align="center"><img src="icons/gray32.png" height="32" width="32" /></td>
- <td align="center"><img src="icons/gray64.png" height="64" width="64" /></td>
- <td align="center"><img src="icons/gray128.png" height="128" width="128" /></td>
- <td align="center"><img src="icons/gray255.png" height="255" width="255" /></td>
+ <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>
diff --git a/tests/auto/quick/qmltests/data/favicon-multi-gray.html b/tests/auto/quick/qmltests/data/favicon-multi-gray.html
index 9b9b7432d..24b71640f 100644
--- a/tests/auto/quick/qmltests/data/favicon-multi-gray.html
+++ b/tests/auto/quick/qmltests/data/favicon-multi-gray.html
@@ -7,11 +7,11 @@
<h1>Gray Multi-sized Favicon Test</h1>
<table style="width:100%">
<tr>
- <td align="center"><img src="icons/gray16.png" height="16" width="16" /></td>
- <td align="center"><img src="icons/gray32.png" height="32" width="32" /></td>
- <td align="center"><img src="icons/gray64.png" height="64" width="64" /></td>
- <td align="center"><img src="icons/gray128.png" height="128" width="128" /></td>
- <td align="center"><img src="icons/gray255.png" height="255" width="255" /></td>
+ <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>
diff --git a/tests/auto/quick/qmltests/data/keyboardEvents.html b/tests/auto/quick/qmltests/data/keyboardEvents.html
new file mode 100644
index 000000000..d536d849f
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/keyboardEvents.html
@@ -0,0 +1,98 @@
+<html>
+<head>
+ <style>
+ div {
+ width: 300px;
+ margin-bottom: 10px;
+ }
+
+ #div_container {
+ display: inline-block;
+ }
+
+ #div_container div {
+ width: 100px;
+ height: 100px;
+ border: 2px solid black;
+ padding: 10px;
+ margin: 0 10px 0 10px;
+ float: left;
+ }
+
+ #div_container div:focus {
+ border: 2px solid red;
+ }
+
+ #form_container span {
+ display: block;
+ padding-bottom: 10px;
+ }
+
+ #form_container label {
+ float: left;
+ text-align: right;
+ width: 50px;
+ margin-right: 20px;
+ }
+ </style>
+</head>
+
+<body onload="document.getElementById('first_div').focus()">
+ <div id="div_container">
+ <div id="first_div" tabindex="0">First</div>
+ <div id="second_div" tabindex="0">Second</div>
+ </div>
+
+ <div id="form_container">
+ <form><fieldset>
+ <legend>Form</legend>
+
+ <span>
+ <label for="text_input">text</label>
+ <input id="text_input" type="text" />
+ </span>
+
+ <span>
+ <input id="radio1" type="radio" name="radio">radio1</input>
+ <input id="radio2" type="radio" name="radio">radio2</input>
+ </span>
+
+ <span>
+ <input id="checkbox1" type="checkbox" name="checkbox1" checked="true">checkbox1</input>
+ <input id="checkbox2" type="checkbox" name="checkbox2" checked="true">checkbox2</input>
+ </span>
+
+ <span>
+ <label for="number_input">number</label>
+ <input id="number_input" type="number" min="0" max="10" value="5" />
+ </span>
+
+ <span>
+ <label for="range_input">range</label>
+ <input id="range_input" type="range" min="0" max="10" value="5" />
+ </span>
+
+ <span>
+ <label for="search_input">search</label>
+ <input id="search_input" type="search" value="test" />
+ </span>
+
+ <input id="submit_button" type="submit" value="Submit" />
+ </fieldset></form>
+ </div>
+
+ <div>
+ <select id="combobox">
+ <option value="a">a</option>
+ <option value="b">b</option>
+ <option value="c">c</option>
+ </select>
+ </div>
+
+ <div>
+ <a id="first_hyperlink" href="">First</a>
+ <br />
+ <a id="second_hyperlink" href="">Second</a>
+ </div>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/redirect.html b/tests/auto/quick/qmltests/data/redirect.html
index 914e5e35a..44eb6cd28 100644
--- a/tests/auto/quick/qmltests/data/redirect.html
+++ b/tests/auto/quick/qmltests/data/redirect.html
@@ -1,8 +1,9 @@
<!doctype html>
<html>
<head>
-<meta http-equiv="refresh" content="2; url=test1.html"
+ <meta http-equiv="refresh" content="2; url=test1.html">
</head>
<body>
+ Redirecting to test1.html
</body>
</html>
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index 904a8feb2..4761513c1 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -107,5 +107,24 @@ TestWebEngineView {
tryCompare(webEngineView, "matchCount", 0)
verify(findFailed)
}
+
+ function test_findTextAfterNotFound() {
+ var findFlags = 0
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.clear()
+ webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
+ tryCompare(webEngineView, "matchCount", 0)
+ verify(findFailed)
+
+ webEngineView.url = Qt.resolvedUrl("test1.html")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.clear()
+ webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
+ tryCompare(webEngineView, "matchCount", 1)
+ verify(!findFailed)
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
index ce0fa2e31..93410a727 100644
--- a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
+++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
@@ -67,8 +67,6 @@ Item {
TestCase {
name: "WebEngineViewFocusOnNavigation"
when: windowShown
- function init() {
- }
function test_focusOnNavigation_data() {
return [
@@ -79,18 +77,9 @@ Item {
]
}
- function triggerJavascriptFocus() {
- var callbackCalled = false;
- webView.runJavaScript("document.getElementById(\"input\").focus()", function(result) {
- callbackCalled = true;
- });
- wait(100);
- verify(callbackCalled);
- }
-
function loadAndTriggerFocusAndCompare(data) {
verify(webView.waitForLoadSucceeded());
- triggerJavascriptFocus();
+ webView.setFocusToElement("input");
compare(webView.activeFocus, data.viewReceivedFocus);
}
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
new file mode 100644
index 000000000..677727632
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** 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.4
+
+TestWebEngineView {
+ id: webEngineView
+ width: 350
+ height: 480
+
+ TestCase {
+ name: "WebEngineViewKeyboardEvents"
+ when: windowShown
+
+ function isElementChecked(element) {
+ var elementChecked;
+ runJavaScript("document.getElementById('" + element + "').checked", function(result) {
+ elementChecked = result;
+ });
+ tryVerify(function() { return elementChecked != undefined; });
+ return elementChecked;
+ }
+
+ function verifyElementChecked(element, expected) {
+ tryVerify(function() { return expected == isElementChecked(element); }, 5000,
+ "Element \"" + element + "\" is " + (expected ? "" : "not") + " checked");
+ }
+
+ function getElementValue(element) {
+ var elementValue;
+ runJavaScript("document.getElementById('" + element + "').value", function(result) {
+ elementValue = result;
+ });
+ tryVerify(function() { return elementValue != undefined; });
+ return elementValue;
+ }
+
+ function compareElementValue(element, expected) {
+ tryVerify(function() { return expected == getElementValue(element); }, 5000,
+ "Value of element \"" + element + "\" is \"" + expected + "\"");
+ }
+
+ function test_keyboardEvents() {
+ webEngineView.url = Qt.resolvedUrl("keyboardEvents.html");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ var elements = [
+ "first_div", "second_div",
+ "text_input", "radio1", "checkbox1", "checkbox2",
+ "number_input", "range_input", "search_input",
+ "submit_button", "combobox", "first_hyperlink", "second_hyperlink"
+ ];
+
+ // Iterate over the elements of the test page with the Tab key. This tests whether any
+ // element blocks the in-page navigation by Tab.
+ for (var i = 0; i < elements.length; ++i) {
+ verifyElementHasFocus(elements[i])
+ keyPress(Qt.Key_Tab);
+ }
+
+ // Move back to the radio buttons with the Shift+Tab key combination
+ for (var i = 0; i < 10; ++i)
+ keyPress(Qt.Key_Tab, Qt.ShiftModifier);
+ verifyElementHasFocus("radio2");
+
+ // Test the Space key by checking a radio button
+ verifyElementChecked("radio2", false);
+ keyClick(Qt.Key_Space);
+ verifyElementChecked("radio2", true);
+
+ // Test the Left key by switching the radio button
+ verifyElementChecked("radio1", false);
+ keyPress(Qt.Key_Left);
+ verifyElementHasFocus("radio1");
+ verifyElementChecked("radio1", true);
+
+ // Test the Space key by unchecking a checkbox
+ setFocusToElement("checkbox1");
+ verifyElementChecked("checkbox1", true);
+ keyClick(Qt.Key_Space);
+ verifyElementChecked("checkbox1", false);
+
+ // Test the Up and Down keys by changing the value of a spinbox
+ setFocusToElement("number_input");
+ compareElementValue("number_input", 5);
+ keyPress(Qt.Key_Up);
+ compareElementValue("number_input", 6);
+ keyPress(Qt.Key_Down);
+ compareElementValue("number_input", 5);
+
+ // Test the Left, Right, Home, PageUp, End and PageDown keys by changing the value of a slider
+ setFocusToElement("range_input");
+ compareElementValue("range_input", 5);
+ keyPress(Qt.Key_Left);
+ compareElementValue("range_input", 4);
+ keyPress(Qt.Key_Right);
+ compareElementValue("range_input", 5);
+ keyPress(Qt.Key_Home);
+ compareElementValue("range_input", 0);
+ keyPress(Qt.Key_PageUp);
+ compareElementValue("range_input", 1);
+ keyPress(Qt.Key_End);
+ compareElementValue("range_input", 10);
+ keyPress(Qt.Key_PageDown);
+ compareElementValue("range_input", 9);
+
+ // Test the Escape key by removing the content of a search field
+ setFocusToElement("search_input");
+ compareElementValue("search_input", "test");
+ keyPress(Qt.Key_Escape);
+ compareElementValue("search_input", "");
+
+ // Test the alpha keys by changing the values in a combobox
+ setFocusToElement("combobox");
+ compareElementValue("combobox", "a");
+ keyPress(Qt.Key_B);
+ compareElementValue("combobox", "b");
+ // Must wait with the second key press to simulate selection of another element
+ wait(1000);
+ keyPress(Qt.Key_C);
+ compareElementValue("combobox", "c");
+
+ // Test the Enter key by loading a page with a hyperlink
+ setFocusToElement("first_hyperlink");
+ keyPress(Qt.Key_Enter);
+ verify(webEngineView.waitForLoadSucceeded());
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
index ae60e5f5e..e0a8c0a41 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
@@ -52,24 +52,26 @@ TestWebEngineView {
onTriggered: parent.when = true
}
+ function getPressedModifiers() {
+ var pressedModifiers;
+ runJavaScript("getPressedModifiers()", function(result) {
+ pressedModifiers = result;
+ });
+ tryVerify(function() { return pressedModifiers != undefined });
+ return pressedModifiers;
+ }
+
function test_keyboardModifierMapping() {
webEngineView.url = Qt.resolvedUrl("keyboardModifierMapping.html")
waitForLoadSucceeded();
titleSpy.wait()
- var callbackCalled = false;
// Alt
keyPress(Qt.Key_Alt);
titleSpy.wait()
- runJavaScript("getPressedModifiers()", function(result) {
- compare(result, "alt:pressed ctrl:no meta:no");
- callbackCalled = true;
- });
- wait(100);
- verify(callbackCalled);
+ compare(getPressedModifiers(), "alt:pressed ctrl:no meta:no");
keyRelease(Qt.Key_Alt)
titleSpy.wait()
- callbackCalled = false;
// Ctrl
// On mac Qt automatically translates Meta to Ctrl and vice versa.
@@ -78,36 +80,18 @@ TestWebEngineView {
// For testing we assume that the flag Qt::AA_MacDontSwapCtrlAndMeta is NOT set.
keyPress(Qt.platform.os == "osx" ? Qt.Key_Meta : Qt.Key_Control);
titleSpy.wait()
- runJavaScript("getPressedModifiers()", function(result) {
- compare(result, "alt:released ctrl:pressed meta:no");
- callbackCalled = true;
- });
- wait(100);
- verify(callbackCalled);
+ compare(getPressedModifiers(), "alt:released ctrl:pressed meta:no");
keyRelease(Qt.platform.os == "osx" ? Qt.Key_Meta : Qt.Key_Control);
titleSpy.wait()
- callbackCalled = false;
// Meta (Command on Mac)
keyPress(Qt.platform.os == "osx" ? Qt.Key_Control : Qt.Key_Meta);
titleSpy.wait()
- runJavaScript("getPressedModifiers()", function(result) {
- compare(result, "alt:released ctrl:released meta:pressed");
- callbackCalled = true;
- });
- wait(100);
- verify(callbackCalled);
+ compare(getPressedModifiers(), "alt:released ctrl:released meta:pressed");
keyRelease(Qt.platform.os == "osx" ? Qt.Key_Control : Qt.Key_Meta);
titleSpy.wait()
- callbackCalled = false;
- runJavaScript("getPressedModifiers()", function(result) {
- compare(result, "alt:released ctrl:released meta:released");
- callbackCalled = true;
- });
- wait(100);
- verify(callbackCalled);
- callbackCalled = false;
+ compare(getPressedModifiers(), "alt:released ctrl:released meta:released");
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 3ce03df70..2a43e1577 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -35,152 +35,249 @@ TestWebEngineView {
width: 400
height: 300
- property var lastUrl
- property bool watchProgress: false
- property int numLoadStarted: 0
- property int numLoadSucceeded: 0
+ property var loadRequestArray: []
- focus: true
-
- onLoadProgressChanged: {
- if (watchProgress && webEngineView.loadProgress != 100) {
- watchProgress = false
- url = ''
- }
+ onLoadingChanged: {
+ loadRequestArray.push({
+ "status": loadRequest.status,
+ "url": loadRequest.url,
+ "activeUrl": webEngineView.url
+ });
}
- onLoadingChanged: {
- if (loadRequest.status == WebEngineView.LoadStartedStatus)
- ++numLoadStarted
- if (loadRequest.status == WebEngineView.LoadSucceededStatus)
- ++numLoadSucceeded
+ function clear() {
+ // Reset loadStatus for waitForLoadSucceded
+ webEngineView.loadStatus = null;
+ loadRequestArray = [];
}
TestCase {
name: "WebEngineViewLoadUrl"
when: windowShown
+ function init() {
+ webEngineView.clear();
+ }
+
function test_loadIgnoreEmptyUrl() {
- var url = Qt.resolvedUrl("test1.html")
-
- webEngineView.url = url
- verify(webEngineView.waitForLoadSucceeded())
- compare(numLoadStarted, 1)
- compare(numLoadSucceeded, 1)
- compare(webEngineView.url, url)
-
- lastUrl = webEngineView.url
- webEngineView.url = ''
- wait(1000)
- compare(numLoadStarted, 1)
- compare(numLoadSucceeded, 1)
- compare(webEngineView.url, lastUrl)
-
- webEngineView.url = 'about:blank'
- verify(webEngineView.waitForLoadSucceeded())
- compare(numLoadStarted, 2)
- compare(numLoadSucceeded, 2)
- compare(webEngineView.url, 'about:blank')
+ var url = Qt.resolvedUrl("test1.html");
+ webEngineView.url = url;
+ verify(webEngineView.waitForLoadSucceeded());
+ compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus);
+ compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray.length, 2);
+ compare(webEngineView.url, url);
+ webEngineView.clear();
+
+ var lastUrl = webEngineView.url;
+ webEngineView.url = "";
+ wait(1000);
+ compare(loadRequestArray.length, 0);
+ compare(webEngineView.url, lastUrl);
+ webEngineView.clear();
+
+ var aboutBlank = "about:blank";
+ webEngineView.url = aboutBlank;
+ verify(webEngineView.waitForLoadSucceeded());
+ compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus);
+ compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray.length, 2);
+ compare(webEngineView.url, aboutBlank);
+ webEngineView.clear();
// It shouldn't interrupt any ongoing load when an empty url is used.
- watchProgress = true
- webEngineView.url = url
- webEngineView.waitForLoadSucceeded()
- compare(numLoadStarted, 3)
- compare(numLoadSucceeded, 3)
- verify(!watchProgress)
- compare(webEngineView.url, url)
+ var watchProgress = true;
+ var handleLoadProgress = function() {
+ if (webEngineView.loadProgress != 100) {
+ webEngineView.url = "";
+ watchProgress = false;
+ }
+ }
+ webEngineView.loadProgressChanged.connect(handleLoadProgress);
+ webEngineView.url = url;
+ verify(webEngineView.waitForLoadSucceeded());
+ compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus);
+ compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray.length, 2);
+ verify(!watchProgress);
+ compare(webEngineView.url, url);
+ webEngineView.loadProgressChanged.disconnect(handleLoadProgress);
+ webEngineView.clear();
}
function test_urlProperty() {
- WebEngine.settings.errorPageEnabled = false
+ WebEngine.settings.errorPageEnabled = false;
- var url = Qt.resolvedUrl("test1.html")
+ var loadRequest = null;
- webEngineView.url = url
- compare(webEngineView.url, url)
- verify(webEngineView.waitForLoadSucceeded())
- compare(webEngineView.url, url)
+ // Test succeeded load
+ var url = Qt.resolvedUrl("test1.html");
+ webEngineView.url = url;
+ tryCompare(loadRequestArray, "length", 2);
- var bogusSite = "http://www.somesitethatdoesnotexist.abc/"
- webEngineView.url = bogusSite
- compare(webEngineView.url, bogusSite)
- verify(webEngineView.waitForLoadFailed())
- compare(webEngineView.url, url)
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, url);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.activeUrl, url);
+ webEngineView.clear();
+
+ // Test failed load
+ var bogusSite = "http://www.somesitethatdoesnotexist.abc/";
+ webEngineView.url = bogusSite;
+ tryCompare(loadRequestArray, "length", 2);
+
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, bogusSite);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadFailedStatus);
+ compare(loadRequest.activeUrl, url);
+ webEngineView.clear();
+
+ // Test page redirection
+ var redirectUrl = Qt.resolvedUrl("redirect.html");
+ webEngineView.url = redirectUrl;
+ tryCompare(loadRequestArray, "length", 4);
- webEngineView.url = "about:blank" // Reset from previous test
- verify(webEngineView.waitForLoadSucceeded())
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, redirectUrl);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.activeUrl, redirectUrl);
+ loadRequest = loadRequestArray[2];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, redirectUrl);
+ loadRequest = loadRequestArray[3];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.activeUrl, url);
+ webEngineView.clear();
+ // Test clicking on a hyperlink
+ var linkUrl = Qt.resolvedUrl("link.html");
+ webEngineView.url = linkUrl;
+ tryCompare(loadRequestArray, "length", 2);
+
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, linkUrl);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.activeUrl, linkUrl);
+ webEngineView.clear();
+
+ var lastUrl = webEngineView.url;
+ mouseClick(webEngineView, 10, 10, Qt.LeftButton, Qt.NoModifiers, 50);
+ tryCompare(loadRequestArray, "length", 2);
+
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.url, url);
+ compare(loadRequest.activeUrl, lastUrl);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.url, url);
+ compare(loadRequest.activeUrl, url);
+ webEngineView.clear();
+ }
+
+ function test_loadDataUrl() {
+ WebEngine.settings.errorPageEnabled = false;
+
+ var loadRequest = null;
+
+ // Test load of a data URL
+ var dataUrl = "data:text/html,foo";
+ webEngineView.url = dataUrl;
+ tryCompare(loadRequestArray, "length", 2);
+
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, dataUrl);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.activeUrl, dataUrl);
+ webEngineView.clear();
+
+ // Test loadHtml after a failed load
+ var aboutBlank = "about:blank";
+ webEngineView.url = aboutBlank; // Reset from previous test
+ verify(webEngineView.waitForLoadSucceeded());
+ webEngineView.clear();
+
+ var bogusSite = "http://www.somesitethatdoesnotexist.abc/";
var handleLoadFailed = function(loadRequest) {
if (loadRequest.status == WebEngineView.LoadFailedStatus) {
- webEngineView.loadHtml("load failed", bogusSite)
- // Since the load did not succeed the active url is the
- // url of the previous successful load.
- compare(webEngineView.url, "about:blank")
- compare(loadRequest.url, bogusSite)
+ // loadHtml constructs data URL
+ webEngineView.loadHtml("load failed", bogusSite);
+ compare(loadRequest.url, bogusSite);
}
}
- webEngineView.loadingChanged.connect(handleLoadFailed)
+ webEngineView.loadingChanged.connect(handleLoadFailed);
webEngineView.url = bogusSite
- compare(webEngineView.url, bogusSite)
- verify(webEngineView.waitForLoadSucceeded())
- compare(webEngineView.url, bogusSite)
- webEngineView.loadingChanged.disconnect(handleLoadFailed)
-
- var dataUrl = "data:text/html,foo"
- webEngineView.url = dataUrl
- compare(webEngineView.url, dataUrl)
- verify(webEngineView.waitForLoadSucceeded()) // data:text/html,foo is loaded
- compare(webEngineView.url, dataUrl)
-
- var redirectUrl = Qt.resolvedUrl("redirect.html")
- webEngineView.url = redirectUrl
- compare(webEngineView.url, redirectUrl)
- verify(webEngineView.waitForLoadSucceeded()) // redirect.html is loaded
- compare(webEngineView.url, redirectUrl)
- verify(webEngineView.waitForLoadSucceeded()) // test1.html is loaded
- compare(webEngineView.url, url)
-
- var linkUrl = Qt.resolvedUrl("link.html")
- webEngineView.url = linkUrl
- compare(webEngineView.url, linkUrl)
- verify(webEngineView.waitForLoadSucceeded())
- compare(webEngineView.url, linkUrl)
-
- var handleLoadRequest = function(loadRequest) {
- if (loadRequest.status == WebEngineView.LoadStartedStatus) {
- compare(webEngineView.url, lastUrl)
- compare(loadRequest.url, url)
- }
- if (loadRequest.status == WebEngineView.LoadSuceededStatus) {
- compare(webEngineView.url, loadRequest.url)
- compare(webEngineView.url, url)
- }
- }
- lastUrl = webEngineView.url
- webEngineView.loadingChanged.connect(handleLoadRequest)
- mouseClick(webEngineView, 10, 10, Qt.LeftButton, Qt.NoModifiers, 50)
- verify(webEngineView.waitForLoadSucceeded())
- compare(webEngineView.url, url)
- webEngineView.loadingChanged.disconnect(handleLoadRequest)
+ tryCompare(loadRequestArray, "length", 4);
+ webEngineView.loadingChanged.disconnect(handleLoadFailed);
+
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, bogusSite);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadFailedStatus);
+ // Since the load did not succeed the active url is the
+ // URL of the previous successful load.
+ compare(loadRequest.activeUrl, aboutBlank);
+ loadRequest = loadRequestArray[2];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.activeUrl, aboutBlank);
+ loadRequest = loadRequestArray[3];
+ compare(loadRequest.status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequest.activeUrl, bogusSite);
+ webEngineView.clear();
+ }
+
+ function test_QTBUG_56661() {
+ var url = Qt.resolvedUrl("test1.html");
+
+ // Warm up phase
+ webEngineView.url = url;
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // Load data URL
+ var dataUrl = "data:text/html,foo";
+ webEngineView.url = dataUrl;
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // WebEngine should not try to execute user scripts in the
+ // render frame of the warm up phase otherwise the renderer
+ // crashes.
+ webEngineView.url = url;
+ verify(webEngineView.waitForLoadSucceeded());
}
function test_stopStatus() {
- var url = Qt.resolvedUrl("test1.html")
+ var loadRequest = null;
- var handleLoadRequest = function(loadRequest) {
- if (loadRequest.status == WebEngineView.LoadStoppedStatus) {
- compare(webEngineView.url, url)
- compare(loadRequest.url, url)
- }
+ var handleLoadStarted = function(loadRequest) {
+ if (loadRequest.status == WebEngineView.LoadStartedStatus)
+ webEngineView.stop();
}
- webEngineView.loadingChanged.connect(handleLoadRequest)
- webEngineView.url = url
- compare(webEngineView.url, url)
- webEngineView.stop()
- verify(webEngineView.waitForLoadStopped())
- compare(webEngineView.url, url)
- webEngineView.loadingChanged.disconnect(handleLoadRequest)
+ webEngineView.loadingChanged.connect(handleLoadStarted);
+ var url = Qt.resolvedUrl("test1.html");
+ webEngineView.url = url;
+ tryCompare(loadRequestArray, "length", 2);
+ webEngineView.loadingChanged.disconnect(handleLoadStarted);
+
+ loadRequest = loadRequestArray[0];
+ compare(loadRequest.status, WebEngineView.LoadStartedStatus);
+ compare(loadRequest.url, url);
+ compare(loadRequest.activeUrl, url);
+ loadRequest = loadRequestArray[1];
+ compare(loadRequest.status, WebEngineView.LoadStoppedStatus);
+ compare(loadRequest.url, url);
+ compare(loadRequest.activeUrl, url);
+ webEngineView.clear();
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
index 5013f2fbe..b1c94e601 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
@@ -83,9 +83,6 @@ TestWebEngineView {
when: windowShown
function init() {
- // Workaround for QTBUG-56223
- mouseClick(webEngineView, 0, 0)
-
attributes.clear()
navigationSpy.clear()
shouldIgnoreLinkClicks = false
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
new file mode 100644
index 000000000..754a9e018
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** 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
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 400
+
+ property var newViewRequest: null
+ property var dialog: null
+
+ SignalSpy {
+ id: newViewRequestedSpy
+ target: webEngineView
+ signalName: "newViewRequested"
+ }
+
+ onNewViewRequested: {
+ newViewRequest = {
+ "destination": request.destination,
+ "userInitiated": request.userInitiated
+ };
+
+ dialog = Qt.createQmlObject(
+ "import QtQuick.Window 2.0\n" +
+ "Window {\n" +
+ " width: 100; height: 100\n" +
+ " visible: true; flags: Qt.Dialog\n" +
+ " property alias webEngineView: webView\n" +
+ " TestWebEngineView { id: webView; anchors.fill: parent }\n" +
+ "}", webEngineView);
+
+ request.openIn(dialog.webEngineView);
+ }
+
+ TestCase {
+ id: test
+ name: "NewViewRequest"
+ when: windowShown
+
+ function init() {
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ newViewRequestedSpy.clear();
+ newViewRequest = null;
+ }
+
+ function cleanup() {
+ if (dialog)
+ dialog.destroy();
+ }
+
+ function test_jsWindowOpen() {
+ // Open an empty page in a new tab
+ webEngineView.loadHtml(
+ "<html><head><script>" +
+ " function popup() { window.open(''); }" +
+ "</script></head>" +
+ "<body onload='popup()'></body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(newViewRequestedSpy, "count", 1);
+
+ compare(newViewRequest.destination, WebEngineView.NewViewInTab);
+ verify(!newViewRequest.userInitiated);
+
+ verify(dialog.webEngineView.waitForLoadSucceeded);
+ compare(dialog.webEngineView.url, "");
+ newViewRequestedSpy.clear();
+ dialog.destroy();
+
+ // Open an empty page in a new dialog
+ webEngineView.loadHtml(
+ "<html><head><script>" +
+ " function popup() { window.open('', '_blank', 'width=200,height=100'); }" +
+ "</script></head>" +
+ "<body onload='popup()'></body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(newViewRequestedSpy, "count", 1);
+
+ compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
+ verify(!newViewRequest.userInitiated);
+ verify(dialog.webEngineView.waitForLoadSucceeded);
+ newViewRequestedSpy.clear();
+ dialog.destroy();
+
+ // Open an empty page in a new dialog by user
+ webEngineView.loadHtml(
+ "<html><head><script>" +
+ " function popup() { window.open('', '_blank', 'width=200,height=100'); }" +
+ "</script></head>" +
+ "<body onload=\"document.getElementById('popupButton').focus();\">" +
+ " <button id='popupButton' onclick='popup()'>Pop Up!</button>" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ verifyElementHasFocus("popupButton");
+ keyPress(Qt.Key_Enter);
+ tryCompare(newViewRequestedSpy, "count", 1);
+
+ compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
+ verify(newViewRequest.userInitiated);
+ verify(dialog.webEngineView.waitForLoadSucceeded);
+ newViewRequestedSpy.clear();
+ dialog.destroy();
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml
index aa3a6dc60..0c37d9569 100644
--- a/tests/auto/quick/qmltests/data/tst_settings.qml
+++ b/tests/auto/quick/qmltests/data/tst_settings.qml
@@ -56,7 +56,7 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("javascript.html");
verify(webEngineView.waitForLoadSucceeded());
- compare(webEngineView.title, "New Title");
+ tryCompare(webEngineView, "title", "New Title");
}
function test_javascriptDisabled() {
@@ -64,7 +64,7 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("javascript.html");
verify(webEngineView.waitForLoadSucceeded());
- compare(webEngineView.title, "Original Title");
+ tryCompare(webEngineView, "title", "Original Title");
}
function test_localStorageDisabled() {
@@ -73,7 +73,7 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("localStorage.html");
verify(webEngineView.waitForLoadSucceeded());
- compare(webEngineView.title, "Original Title");
+ tryCompare(webEngineView, "title", "Original Title");
}
function test_localStorageEnabled() {
@@ -84,7 +84,7 @@ TestWebEngineView {
verify(webEngineView.waitForLoadSucceeded());
webEngineView.reload();
verify(webEngineView.waitForLoadSucceeded());
- compare(webEngineView.title, "New Title");
+ tryCompare(webEngineView, "title", "New Title");
}
function test_settingsAffectCurrentViewOnly() {
@@ -100,8 +100,8 @@ TestWebEngineView {
webEngineView2.url = testUrl;
verify(webEngineView2.waitForLoadSucceeded());
- compare(webEngineView.title, "New Title");
- compare(webEngineView2.title, "New Title");
+ tryCompare(webEngineView, "title", "New Title");
+ tryCompare(webEngineView2, "title", "New Title");
webEngineView.settings.javascriptEnabled = false;
@@ -110,8 +110,8 @@ TestWebEngineView {
webEngineView2.url = testUrl;
verify(webEngineView2.waitForLoadSucceeded());
- compare(webEngineView.title, "Original Title");
- compare(webEngineView2.title, "New Title");
+ tryCompare(webEngineView, "title", "Original Title");
+ tryCompare(webEngineView2, "title", "New Title");
webEngineView2.destroy();
}
diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
index 87ef16aa2..906dc1658 100644
--- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
+++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
@@ -68,12 +68,10 @@ Item {
keyPress(Qt.Key_Left)
keyRelease(Qt.Key_Left)
- for (var i = 0; i < 20 && parentItem.releaseEvents.length < 3; i++)
- wait(100)
-
- compare(parentItem.pressEvents.length, 1)
+ tryCompare(parentItem.pressEvents, "length", 1)
compare(parentItem.pressEvents[0], Qt.Key_Left)
- compare(parentItem.releaseEvents.length, 3)
+
+ tryCompare(parentItem.releaseEvents, "length", 3)
compare(parentItem.releaseEvents[0], Qt.Key_A)
compare(parentItem.releaseEvents[1], Qt.Key_Left)
compare(parentItem.releaseEvents[2], Qt.Key_Left)
diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml
index 79b097b80..8076d99f8 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSource.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml
@@ -74,7 +74,7 @@ TestWebEngineView {
function test_viewSource() {
webEngineView.url = Qt.resolvedUrl("test1.html");
verify(webEngineView.waitForLoadSucceeded());
- compare(webEngineView.title, "Test page 1");
+ tryCompare(webEngineView, "title", "Test page 1");
// FIXME(pvarga): Reintroduce this check in the fix for QTBUG-56117
//verify(webEngineView.canViewSource, true);
@@ -83,14 +83,14 @@ TestWebEngineView {
tryCompare(newViewRequestedSpy, "count", 1);
verify(webEngineView.waitForLoadSucceeded());
// The first titleChanged signal is emitted by adoptWebContents()
- tryCompare(titleChangedSpy, "count", 2);
+ tryVerify(function() { return titleChangedSpy.count >= 2; });
compare(viewRequest.destination, WebEngineView.NewViewInTab);
verify(viewRequest.userInitiated);
// FIXME(pvarga): Reintroduce this check in the fix for QTBUG-56117
//verify(!webEngineView.canViewSource);
- compare(webEngineView.title, "test1.html");
+ tryCompare(webEngineView, "title", "test1.html");
compare(webEngineView.url, "view-source:" + Qt.resolvedUrl("test1.html"));
}
@@ -114,14 +114,14 @@ TestWebEngineView {
if (row.loadSucceed) {
verify(webEngineView.waitForLoadSucceeded());
- tryCompare(titleChangedSpy, "count", 1);
+ tryVerify(function() { return titleChangedSpy.count >= 1; });
} else {
verify(webEngineView.waitForLoadFailed());
- tryCompare(titleChangedSpy, "count", 2);
+ tryVerify(function() { return titleChangedSpy.count >= 2; });
}
compare(webEngineView.url, row.url);
- compare(webEngineView.title, row.title);
+ tryCompare(webEngineView, "title", row.title);
// FIXME(pvarga): Reintroduce this check in the fix for QTBUG-56117
//verify(!webEngineView.canViewSource);
}
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index 30c3aab30..4d4268324 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -39,12 +39,14 @@ OTHER_FILES += \
$$PWD/data/test3.html \
$$PWD/data/test4.html \
$$PWD/data/keyboardModifierMapping.html \
+ $$PWD/data/keyboardEvents.html \
$$PWD/data/titleupdate.js \
$$PWD/data/tst_desktopBehaviorLoadHtml.qml \
$$PWD/data/tst_download.qml \
$$PWD/data/tst_favicon.qml \
$$PWD/data/tst_faviconDownload.qml \
$$PWD/data/tst_filePicker.qml \
+ $$PWD/data/tst_findText.qml \
$$PWD/data/tst_focusOnNavigation.qml \
$$PWD/data/tst_formValidation.qml \
$$PWD/data/tst_geopermission.qml \
@@ -58,6 +60,7 @@ OTHER_FILES += \
$$PWD/data/tst_loadUrl.qml \
$$PWD/data/tst_navigationHistory.qml \
$$PWD/data/tst_navigationRequested.qml \
+ $$PWD/data/tst_newViewRequest.qml \
$$PWD/data/tst_properties.qml \
$$PWD/data/tst_runJavaScript.qml \
$$PWD/data/tst_scrollPosition.qml \
@@ -68,6 +71,7 @@ OTHER_FILES += \
$$PWD/data/tst_webchannel.qml \
$$PWD/data/tst_settings.qml \
$$PWD/data/tst_keyboardModifierMapping.qml \
+ $$PWD/data/tst_keyboardEvents.qml \
$$PWD/data/icons/favicon.png \
$$PWD/data/icons/gray128.png \
$$PWD/data/icons/gray16.png \
diff --git a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
index 63ca25396..3ed4bcc71 100644
--- a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
+++ b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
@@ -25,7 +25,7 @@
#include <qwebenginepage.h>
#include <qwidget.h>
-class tst_QWebEngineView : public QObject
+class tst_QWebEngineAccessibility : public QObject
{
Q_OBJECT
@@ -44,27 +44,27 @@ private Q_SLOTS:
// This will be called before the first test function is executed.
// It is only called once.
-void tst_QWebEngineView::initTestCase()
+void tst_QWebEngineAccessibility::initTestCase()
{
}
// This will be called after the last test function is executed.
// It is only called once.
-void tst_QWebEngineView::cleanupTestCase()
+void tst_QWebEngineAccessibility::cleanupTestCase()
{
}
// This will be called before each test function is executed.
-void tst_QWebEngineView::init()
+void tst_QWebEngineAccessibility::init()
{
}
// This will be called after every test function.
-void tst_QWebEngineView::cleanup()
+void tst_QWebEngineAccessibility::cleanup()
{
}
-void tst_QWebEngineView::noPage()
+void tst_QWebEngineAccessibility::noPage()
{
QWebEngineView webView;
webView.show();
@@ -80,7 +80,7 @@ void tst_QWebEngineView::noPage()
QCOMPARE(document->childCount(), 0);
}
-void tst_QWebEngineView::hierarchy()
+void tst_QWebEngineAccessibility::hierarchy()
{
QWebEngineView webView;
webView.setHtml("<html><body>" \
@@ -139,7 +139,7 @@ void tst_QWebEngineView::hierarchy()
QCOMPARE(input, child);
}
-void tst_QWebEngineView::text()
+void tst_QWebEngineAccessibility::text()
{
QWebEngineView webView;
webView.setHtml("<html><body>" \
@@ -207,7 +207,7 @@ void tst_QWebEngineView::text()
QCOMPARE(input3->text(QAccessible::Value), QStringLiteral("Good day!"));
}
-void tst_QWebEngineView::value()
+void tst_QWebEngineAccessibility::value()
{
QWebEngineView webView;
webView.setHtml("<html><body>" \
@@ -248,5 +248,5 @@ void tst_QWebEngineView::value()
static QByteArrayList params = QByteArrayList()
<< "--force-renderer-accessibility";
-W_QTEST_MAIN(tst_QWebEngineView, params)
+W_QTEST_MAIN(tst_QWebEngineAccessibility, params)
#include "tst_qwebengineaccessibility.moc"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 166c5a499..f16c42976 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -296,6 +296,7 @@ void tst_QWebEnginePage::cleanupFiles()
void tst_QWebEnginePage::initTestCase()
{
+ QLocale::setDefault(QLocale("en"));
cleanupFiles(); // In case there are old files from previous runs
// Set custom path since the CI doesn't install test plugins.
@@ -4992,6 +4993,8 @@ void tst_QWebEnginePage::viewSource()
QCOMPARE(page.createdWindows.size(), 1);
QTRY_COMPARE(page.createdWindows[0]->url().toString(), QStringLiteral("view-source:%1").arg(url.toString()));
+ // The requested URL should not be about:blank if the qrc scheme is supported
+ QTRY_COMPARE(page.createdWindows[0]->requestedUrl(), url);
QTRY_COMPARE(page.createdWindows[0]->title(), QStringLiteral("view-source:%1").arg(url.toString()));
QVERIFY(!page.createdWindows[0]->action(QWebEnginePage::ViewSource)->isEnabled());
}
@@ -5001,21 +5004,24 @@ void tst_QWebEnginePage::viewSourceURL_data()
QTest::addColumn<QUrl>("userInputUrl");
QTest::addColumn<bool>("loadSucceed");
QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QUrl>("requestedUrl");
QTest::addColumn<QString>("title");
- QTest::newRow("view-source:") << QUrl("view-source:") << true << QUrl("view-source:") << QString("view-source:");
- QTest::newRow("view-source:about:blank") << QUrl("view-source:about:blank") << true << QUrl("view-source:about:blank") << QString("view-source:about:blank");
+ QTest::newRow("view-source:") << QUrl("view-source:") << true << QUrl("view-source:") << QUrl("about:blank") << QString("view-source:");
+ QTest::newRow("view-source:about:blank") << QUrl("view-source:about:blank") << true << QUrl("view-source:about:blank") << QUrl("about:blank") << QString("view-source:about:blank");
- QUrl testLocalUrl = QUrl(QString("view-source:%1").arg(QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginepage/resources/test1.html")).toString()));
- QUrl testLocalUrlWithoutScheme = QUrl(QString("view-source:%1").arg(TESTS_SOURCE_DIR + QLatin1String("qwebenginepage/resources/test1.html")));
- QTest::newRow(testLocalUrl.toString().toStdString().c_str()) << testLocalUrl << true << testLocalUrl << QString("test1.html");
- QTest::newRow(testLocalUrlWithoutScheme.toString().toStdString().c_str()) << testLocalUrlWithoutScheme << true << testLocalUrl << QString("test1.html");
+ QString localFilePath = QString("%1qwebenginepage/resources/test1.html").arg(TESTS_SOURCE_DIR);
+ QUrl testLocalUrl = QUrl(QString("view-source:%1").arg(QUrl::fromLocalFile(localFilePath).toString()));
+ QUrl testLocalUrlWithoutScheme = QUrl(QString("view-source:%1").arg(localFilePath));
+ QTest::newRow(testLocalUrl.toString().toStdString().c_str()) << testLocalUrl << true << testLocalUrl << QUrl::fromLocalFile(localFilePath) << QString("test1.html");
+ QTest::newRow(testLocalUrlWithoutScheme.toString().toStdString().c_str()) << testLocalUrlWithoutScheme << true << testLocalUrl << QUrl::fromLocalFile(localFilePath) << QString("test1.html");
- QUrl testResourceUrl = QUrl("view-source:qrc:/resources/test1.html");
- QTest::newRow(testResourceUrl.toString().toStdString().c_str()) << testResourceUrl << true << testResourceUrl << testResourceUrl.toString();
+ QString resourcePath = QLatin1String("qrc:/resources/test1.html");
+ QUrl testResourceUrl = QUrl(QString("view-source:%1").arg(resourcePath));
+ QTest::newRow(testResourceUrl.toString().toStdString().c_str()) << testResourceUrl << true << testResourceUrl << QUrl(resourcePath) << testResourceUrl.toString();
- QTest::newRow("view-source:http://non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QString("http://non.existent/ is not available");
- QTest::newRow("view-source:non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QString("http://non.existent/ is not available");
+ QTest::newRow("view-source:http://non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("http://non.existent/ is not available");
+ QTest::newRow("view-source:non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("http://non.existent/ is not available");
}
void tst_QWebEnginePage::viewSourceURL()
@@ -5026,6 +5032,7 @@ void tst_QWebEnginePage::viewSourceURL()
QFETCH(QUrl, userInputUrl);
QFETCH(bool, loadSucceed);
QFETCH(QUrl, url);
+ QFETCH(QUrl, requestedUrl);
QFETCH(QString, title);
QWebEnginePage *page = new QWebEnginePage;
@@ -5037,6 +5044,7 @@ void tst_QWebEnginePage::viewSourceURL()
QCOMPARE(arguments.at(0).toBool(), loadSucceed);
QCOMPARE(page->url(), url);
+ QCOMPARE(page->requestedUrl(), requestedUrl);
QCOMPARE(page->title(), title);
QVERIFY(!page->action(QWebEnginePage::ViewSource)->isEnabled());
diff --git a/tests/auto/widgets/qwebenginespellcheck/dict/de-DE.aff b/tests/auto/widgets/qwebenginespellcheck/dict/de-DE.aff
new file mode 100644
index 000000000..ff8185771
--- /dev/null
+++ b/tests/auto/widgets/qwebenginespellcheck/dict/de-DE.aff
@@ -0,0 +1,5 @@
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzqESIANRTOLCDUGMPHBYFVKWZQ
+
+PFX Q Y 1
+PFX Q 0 q .
diff --git a/tests/auto/widgets/qwebenginespellcheck/dict/de-DE.dic b/tests/auto/widgets/qwebenginespellcheck/dict/de-DE.dic
new file mode 100644
index 000000000..d10ae2600
--- /dev/null
+++ b/tests/auto/widgets/qwebenginespellcheck/dict/de-DE.dic
@@ -0,0 +1,14 @@
+15
+du/Q
+er/Q
+es/Q
+ich/Q
+ihr/Q
+liebe/Q
+lieben/Q
+liebst/Q
+liebt/Q
+qt/Q
+sie/Q
+Sie/Q
+wir/Q
diff --git a/tests/auto/widgets/qwebenginespellcheck/qwebenginespellcheck.pro b/tests/auto/widgets/qwebenginespellcheck/qwebenginespellcheck.pro
index 437aad937..a36c82e20 100644
--- a/tests/auto/widgets/qwebenginespellcheck/qwebenginespellcheck.pro
+++ b/tests/auto/widgets/qwebenginespellcheck/qwebenginespellcheck.pro
@@ -2,7 +2,9 @@ include(../tests.pri)
DISTFILES += \
dict/en-US.dic \
- dict/en-US.aff
+ dict/en-US.aff \
+ dict/de-DE.dic \
+ dict/de-DE.aff \
qtPrepareTool(CONVERT_TOOL, qwebengine_convert_dict)
@@ -13,7 +15,7 @@ debug_and_release {
DICTIONARIES_DIR = qtwebengine_dictionaries
}
-dict.files = $$PWD/dict/en-US.dic
+dict.files = $$PWD/dict/en-US.dic $$PWD/dict/de-DE.dic
dictoolbuild.input = dict.files
dictoolbuild.output = $${DICTIONARIES_DIR}/${QMAKE_FILE_BASE}.bdic
dictoolbuild.commands = $${CONVERT_TOOL} ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
diff --git a/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp b/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp
index 534d40f45..4db5b9477 100644
--- a/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp
+++ b/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp
@@ -73,8 +73,10 @@ private Q_SLOTS:
void cleanup();
void initTestCase();
void spellCheckLanguage();
+ void spellCheckLanguages();
void spellCheckEnabled();
void spellcheck();
+ void spellcheck_data();
private:
void load();
@@ -86,14 +88,14 @@ void tst_QWebEngineSpellcheck::initTestCase()
QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
QVERIFY(profile);
QVERIFY(!profile->isSpellCheckEnabled());
- QVERIFY(profile->spellCheckLanguage().isEmpty());
+ QVERIFY(profile->spellCheckLanguages().isEmpty());
}
void tst_QWebEngineSpellcheck::init()
{
QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
profile->setSpellCheckEnabled(false);
- profile->setSpellCheckLanguage(QString::null);
+ profile->setSpellCheckLanguages(QStringList());
m_view = new WebView();
}
@@ -113,10 +115,19 @@ void tst_QWebEngineSpellcheck::spellCheckLanguage()
{
QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
QVERIFY(profile);
- profile->setSpellCheckLanguage("en-US");
- QVERIFY(profile->spellCheckLanguage() == "en-US");
+ profile->setSpellCheckLanguages({"en-US"});
+ QVERIFY(profile->spellCheckLanguages() == QStringList({"en-US"}));
}
+void tst_QWebEngineSpellcheck::spellCheckLanguages()
+{
+ QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
+ QVERIFY(profile);
+ profile->setSpellCheckLanguages({"en-US","de-DE"});
+ QVERIFY(profile->spellCheckLanguages() == QStringList({"en-US","de-DE"}));
+}
+
+
void tst_QWebEngineSpellcheck::spellCheckEnabled()
{
QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
@@ -127,9 +138,12 @@ void tst_QWebEngineSpellcheck::spellCheckEnabled()
void tst_QWebEngineSpellcheck::spellcheck()
{
+ QFETCH(QStringList, languages);
+ QFETCH(QStringList, suggestions);
+
QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
QVERIFY(profile);
- profile->setSpellCheckLanguage("en-US");
+ profile->setSpellCheckLanguages(languages);
profile->setSpellCheckEnabled(true);
load();
@@ -166,8 +180,7 @@ void tst_QWebEngineSpellcheck::spellcheck()
QVERIFY(m_view->data().misspelledWord() == "lovee");
// check suggestions
- QStringList expected {"love", "loves"};
- QVERIFY(m_view->data().spellCheckerSuggestions() == expected);
+ QVERIFY(m_view->data().spellCheckerSuggestions() == suggestions);
// check replace word
m_view->page()->replaceMisspelledWord("love");
@@ -175,5 +188,13 @@ void tst_QWebEngineSpellcheck::spellcheck()
QTRY_VERIFY(evaluateJavaScriptSync(m_view->page(), "text();").toString() == text);
}
+void tst_QWebEngineSpellcheck::spellcheck_data()
+{
+ QTest::addColumn<QStringList>("languages");
+ QTest::addColumn<QStringList>("suggestions");
+ QTest::newRow("en-US") << QStringList({"en-US"}) << QStringList({"love", "loves"});
+ QTest::newRow("en-US,de-DE") << QStringList({"en-US","de-DE"}) << QStringList({"love", "liebe", "loves"});
+}
+
QTEST_MAIN(tst_QWebEngineSpellcheck)
#include "tst_qwebenginespellcheck.moc"
diff --git a/tests/auto/widgets/qwebengineview/resources/keyboardEvents.html b/tests/auto/widgets/qwebengineview/resources/keyboardEvents.html
new file mode 100644
index 000000000..d536d849f
--- /dev/null
+++ b/tests/auto/widgets/qwebengineview/resources/keyboardEvents.html
@@ -0,0 +1,98 @@
+<html>
+<head>
+ <style>
+ div {
+ width: 300px;
+ margin-bottom: 10px;
+ }
+
+ #div_container {
+ display: inline-block;
+ }
+
+ #div_container div {
+ width: 100px;
+ height: 100px;
+ border: 2px solid black;
+ padding: 10px;
+ margin: 0 10px 0 10px;
+ float: left;
+ }
+
+ #div_container div:focus {
+ border: 2px solid red;
+ }
+
+ #form_container span {
+ display: block;
+ padding-bottom: 10px;
+ }
+
+ #form_container label {
+ float: left;
+ text-align: right;
+ width: 50px;
+ margin-right: 20px;
+ }
+ </style>
+</head>
+
+<body onload="document.getElementById('first_div').focus()">
+ <div id="div_container">
+ <div id="first_div" tabindex="0">First</div>
+ <div id="second_div" tabindex="0">Second</div>
+ </div>
+
+ <div id="form_container">
+ <form><fieldset>
+ <legend>Form</legend>
+
+ <span>
+ <label for="text_input">text</label>
+ <input id="text_input" type="text" />
+ </span>
+
+ <span>
+ <input id="radio1" type="radio" name="radio">radio1</input>
+ <input id="radio2" type="radio" name="radio">radio2</input>
+ </span>
+
+ <span>
+ <input id="checkbox1" type="checkbox" name="checkbox1" checked="true">checkbox1</input>
+ <input id="checkbox2" type="checkbox" name="checkbox2" checked="true">checkbox2</input>
+ </span>
+
+ <span>
+ <label for="number_input">number</label>
+ <input id="number_input" type="number" min="0" max="10" value="5" />
+ </span>
+
+ <span>
+ <label for="range_input">range</label>
+ <input id="range_input" type="range" min="0" max="10" value="5" />
+ </span>
+
+ <span>
+ <label for="search_input">search</label>
+ <input id="search_input" type="search" value="test" />
+ </span>
+
+ <input id="submit_button" type="submit" value="Submit" />
+ </fieldset></form>
+ </div>
+
+ <div>
+ <select id="combobox">
+ <option value="a">a</option>
+ <option value="b">b</option>
+ <option value="c">c</option>
+ </select>
+ </div>
+
+ <div>
+ <a id="first_hyperlink" href="">First</a>
+ <br />
+ <a id="second_hyperlink" href="">Second</a>
+ </div>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 156c56933..9966ad9ee 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -82,6 +82,7 @@ private Q_SLOTS:
void changeLocale();
void inputMethodsTextFormat_data();
void inputMethodsTextFormat();
+ void keyboardEvents();
};
// This will be called before the first test function is executed.
@@ -924,5 +925,94 @@ void tst_QWebEngineView::inputMethodsTextFormat()
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), string);
}
+void tst_QWebEngineView::keyboardEvents()
+{
+ QWebEngineView view;
+ view.show();
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.load(QUrl("qrc:///resources/keyboardEvents.html"));
+ QVERIFY(loadFinishedSpy.wait());
+
+ QStringList elements;
+ elements << "first_div" << "second_div";
+ elements << "text_input" << "radio1" << "checkbox1" << "checkbox2";
+ elements << "number_input" << "range_input" << "search_input";
+ elements << "submit_button" << "combobox" << "first_hyperlink" << "second_hyperlink";
+
+ // Iterate over the elements of the test page with the Tab key. This tests whether any
+ // element blocks the in-page navigation by Tab.
+ for (const QString &elementId : elements) {
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), elementId);
+ QTest::keyPress(view.focusProxy(), Qt::Key_Tab);
+ }
+
+ // Move back to the radio buttons with the Shift+Tab key combination
+ for (int i = 0; i < 10; ++i)
+ QTest::keyPress(view.focusProxy(), Qt::Key_Tab, Qt::ShiftModifier);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("radio2"));
+
+ // Test the Space key by checking a radio button
+ QVERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('radio2').checked").toBool());
+ QTest::keyClick(view.focusProxy(), Qt::Key_Space);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('radio2').checked").toBool());
+
+ // Test the Left key by switching the radio button
+ QVERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('radio1').checked").toBool());
+ QTest::keyPress(view.focusProxy(), Qt::Key_Left);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("radio1"));
+ QVERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('radio2').checked").toBool());
+ QVERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('radio1').checked").toBool());
+
+ // Test the Space key by unchecking a checkbox
+ evaluateJavaScriptSync(view.page(), "document.getElementById('checkbox1').focus()");
+ QVERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('checkbox1').checked").toBool());
+ QTest::keyClick(view.focusProxy(), Qt::Key_Space);
+ QTRY_VERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('checkbox1').checked").toBool());
+
+ // Test the Up and Down keys by changing the value of a spinbox
+ evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').focus()");
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').value").toInt(), 5);
+ QTest::keyPress(view.focusProxy(), Qt::Key_Up);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').value").toInt(), 6);
+ QTest::keyPress(view.focusProxy(), Qt::Key_Down);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').value").toInt(), 5);
+
+ // Test the Left, Right, Home, PageUp, End and PageDown keys by changing the value of a slider
+ evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').focus()");
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("5"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_Left);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("4"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_Right);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("5"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_Home);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("0"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_PageUp);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("1"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_End);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("10"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_PageDown);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("9"));
+
+ // Test the Escape key by removing the content of a search field
+ evaluateJavaScriptSync(view.page(), "document.getElementById('search_input').focus()");
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('search_input').value").toString(), QStringLiteral("test"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_Escape);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('search_input').value").toString().isEmpty());
+
+ // Test the alpha keys by changing the values in a combobox
+ evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').focus()");
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("a"));
+ QTest::keyPress(view.focusProxy(), Qt::Key_B);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("b"));
+ // Must wait with the second key press to simulate selection of another element
+ QTest::keyPress(view.focusProxy(), Qt::Key_C, Qt::NoModifier, 1000);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("c"));
+
+ // Test the Enter key by loading a page with a hyperlink
+ evaluateJavaScriptSync(view.page(), "document.getElementById('first_hyperlink').focus()");
+ QTest::keyPress(view.focusProxy(), Qt::Key_Enter);
+ QVERIFY(loadFinishedSpy.wait());
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
index b32b533c2..4809bbebf 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
@@ -5,5 +5,6 @@
<file>resources/input_types.html</file>
<file>resources/scrolltest_page.html</file>
<file>resources/basic_printing_page.html</file>
+ <file>resources/keyboardEvents.html</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 2f5416701..c7096b6b6 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -13,7 +13,10 @@ SUBDIRS += \
qwebenginesettings \
qwebengineview
-# QTBUG-53135, osx does not use hunspell
-!contains(WEBENGINE_CONFIG, no_spellcheck):!osx:!cross_compile {
- SUBDIRS += qwebenginespellcheck
+!contains(WEBENGINE_CONFIG, use_spellchecker):!cross_compile {
+ !contains(WEBENGINE_CONFIG, use_native_spellchecker) {
+ SUBDIRS += qwebenginespellcheck
+ } else {
+ message("Spellcheck test will not be built because it depends on usage of Hunspell dictionaries.")
+ }
}
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 16f56dbe9..edf95846c 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -1,6 +1,7 @@
TEMPLATE = subdirs
SUBDIRS += \
- widgets
+ widgets \
+ quick
!qtHaveModule(webenginewidgets): SUBDIRS -= widgets
diff --git a/tests/manual/quick/faviconbrowser/AddressBar.qml b/tests/manual/quick/faviconbrowser/AddressBar.qml
new file mode 100644
index 000000000..7122b2862
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/AddressBar.qml
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+
+Rectangle {
+ id: root
+
+ property int progress: 0
+ property url iconUrl: ""
+ property url pageUrl: ""
+
+ signal accepted(url addressUrl)
+
+ clip: true
+
+ onActiveFocusChanged: {
+ if (activeFocus)
+ addressField.forceActiveFocus();
+ }
+
+ Rectangle {
+ width: addressField.width / 100 * root.progress
+ height: root.height
+
+ visible: root.progress < 100
+
+ color: "#b6dca6"
+ radius: root.radius
+ }
+
+ TextField {
+ id: addressField
+ anchors.fill: parent
+
+ Image {
+ anchors.verticalCenter: addressField.verticalCenter
+ x: 5; z: parent.z + 1
+ width: 16; height: 16
+ sourceSize: Qt.size(width, height)
+ source: root.iconUrl
+ visible: root.progress == 100
+ }
+
+ Text {
+ text: root.progress < 0 ? "" : root.progress + "%"
+ x: 5; z: parent.z + 1
+ font.bold: true
+ anchors.verticalCenter: parent.verticalCenter
+
+ visible: root.progress < 100
+ }
+
+ style: TextFieldStyle {
+ padding.left: 30
+
+ background: Rectangle {
+ color: "transparent"
+ border.color: "black"
+ border.width: 1
+ radius: root.radius
+ }
+ }
+
+ onActiveFocusChanged: {
+ if (activeFocus)
+ selectAll();
+ else
+ deselect();
+ }
+
+ text: root.pageUrl
+ onAccepted: root.accepted(utils.fromUserInput(text))
+ }
+}
diff --git a/tests/manual/quick/faviconbrowser/FaviconPanel.qml b/tests/manual/quick/faviconbrowser/FaviconPanel.qml
new file mode 100644
index 000000000..ce768b82d
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/FaviconPanel.qml
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.1
+
+Item {
+ id: root
+
+ property url iconUrl: ""
+ property int iconSize: 128
+ property int iconMinimumSize: 8
+ property int iconMaximumSize: 256
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: 2
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: 2
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: (parent.width - 2 * parent.spacing) / 3
+
+ border.color: "black"
+ border.width: 1
+ clip: true
+
+ Text {
+ z: parent.z + 1
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ font.bold: true
+
+ text: "faviconImage"
+ }
+
+ Image {
+ id: faviconImage
+ anchors.centerIn: parent
+
+ width: root.iconSize
+ height: width
+ sourceSize: Qt.size(width, height)
+
+ source: root.iconUrl
+
+ onStatusChanged: {
+ if (status == Image.Ready) {
+ grabToImage(function(result) {
+ grabImage.source = result.url;
+ });
+ }
+
+ if (status == Image.Null)
+ grabImage.source = "";
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: (parent.width - 2 * parent.spacing) / 3
+
+ border.color: "black"
+ border.width: 1
+ clip: true
+
+ Text {
+ z: parent.z + 1
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ font.bold: true
+
+ text: "grabImage"
+ }
+
+ Image {
+ id: grabImage
+ anchors.centerIn: parent
+
+ width: root.iconSize
+ height: width
+
+ onStatusChanged: {
+ if (status == Image.Ready || status == Image.Null)
+ faviconCanvas.requestPaint();
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: (parent.width - 2 * parent.spacing) / 3
+
+ border.color: "black"
+ border.width: 1
+ clip: true
+
+ Text {
+ z: parent.z + 1
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ font.bold: true
+
+ text: "faviconCanvas"
+ }
+
+ Canvas {
+ id: faviconCanvas
+ anchors.centerIn: parent
+
+ width: root.iconSize
+ height: width
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ ctx.clearRect(0, 0, width, height);
+
+ if (grabImage.source == "")
+ return;
+
+ ctx.drawImage(grabImage, 0, 0, width, height);
+
+ var imageData = ctx.getImageData(width/2, height/2, width/2, height/2);
+ var pixel = imageData.data;
+
+ verbose.append("pixel(" + width/2 + ", " + height/2 + "): " + pixel[0] + ", " + pixel[1] + ", " + pixel[2]);
+ }
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: 100
+
+ Slider {
+ id: faviconSizeSlider
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.bottom: faviconSizeSpin.top
+
+ orientation: Qt.Vertical
+ minimumValue: root.iconMinimumSize
+ maximumValue: root.iconMaximumSize
+ stepSize: 1
+ tickmarksEnabled: true
+ value: root.iconSize
+
+ onValueChanged: {
+ if (pressed && value != root.iconSize)
+ root.iconSize = value;
+ }
+ }
+
+ SpinBox {
+ id: faviconSizeSpin
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+
+ minimumValue: root.iconMinimumSize
+ maximumValue: root.iconMaximumSize
+ value: root.iconSize
+
+ onEditingFinished: {
+ if (value != root.iconSize)
+ root.iconSize = value;
+ }
+ }
+ }
+
+ TextArea {
+ id: verbose
+
+ Layout.fillHeight: true
+ Layout.preferredWidth: 310
+
+ readOnly: true
+ tabChangesFocus: true
+
+ font.family: "Monospace"
+ font.pointSize: 12
+
+ textFormat: TextEdit.RichText
+ frameVisible: false
+
+ style: TextAreaStyle {
+ backgroundColor: "lightgray"
+ }
+ }
+ }
+}
diff --git a/tests/manual/quick/faviconbrowser/faviconbrowser.pro b/tests/manual/quick/faviconbrowser/faviconbrowser.pro
new file mode 100644
index 000000000..d4368ab3e
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/faviconbrowser.pro
@@ -0,0 +1,23 @@
+QT += qml quick webengine
+qtHaveModule(widgets) {
+ QT += widgets # QApplication is required to get native styling with QtQuickControls
+}
+
+TARGET = faviconbrowser
+TEMPLATE = app
+
+
+SOURCES = \
+ main.cpp
+
+HEADERS = \
+ utils.h
+
+OTHER_FILES += \
+ main.qml \
+ AddressBar.qml \
+ FaviconPanel.qml
+
+RESOURCES += \
+ faviconbrowser.qrc
+
diff --git a/tests/manual/quick/faviconbrowser/faviconbrowser.qrc b/tests/manual/quick/faviconbrowser/faviconbrowser.qrc
new file mode 100644
index 000000000..95d0dc2c4
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/faviconbrowser.qrc
@@ -0,0 +1,17 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>AddressBar.qml</file>
+ <file>FaviconPanel.qml</file>
+ </qresource>
+ <qresource prefix="test">
+ <file alias="favicon-multi-gray.html">../../../auto/quick/qmltests/data/favicon-multi-gray.html</file>
+ <file alias="favicon-candidates-gray.html">../../../auto/quick/qmltests/data/favicon-candidates-gray.html</file>
+ <file alias="icons/grayicons.ico">../../../auto/quick/qmltests/data/icons/grayicons.ico</file>
+ <file alias="icons/gray16.png">../../../auto/quick/qmltests/data/icons/gray16.png</file>
+ <file alias="icons/gray32.png">../../../auto/quick/qmltests/data/icons/gray32.png</file>
+ <file alias="icons/gray64.png">../../../auto/quick/qmltests/data/icons/gray64.png</file>
+ <file alias="icons/gray128.png">../../../auto/quick/qmltests/data/icons/gray128.png</file>
+ <file alias="icons/gray255.png">../../../auto/quick/qmltests/data/icons/gray255.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/quick/faviconbrowser/main.cpp b/tests/manual/quick/faviconbrowser/main.cpp
new file mode 100644
index 000000000..b75be2483
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/main.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "utils.h"
+
+#ifndef QT_NO_WIDGETS
+#include <QtWidgets/QApplication>
+typedef QApplication Application;
+#else
+#include <QtGui/QGuiApplication>
+typedef QGuiApplication Application;
+#endif
+#include <QtQml/QQmlApplicationEngine>
+#include <QtQml/QQmlContext>
+#include <QtWebEngine/qtwebengineglobal.h>
+
+int main(int argc, char **argv)
+{
+ Application app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine appEngine;
+ Utils utils;
+ appEngine.rootContext()->setContextProperty("utils", &utils);
+ appEngine.load(QUrl("qrc:/main.qml"));
+
+ return app.exec();
+}
diff --git a/tests/manual/quick/faviconbrowser/main.qml b/tests/manual/quick/faviconbrowser/main.qml
new file mode 100644
index 000000000..1ad5fc2e8
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/main.qml
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.1
+import QtWebEngine 1.3
+import Qt.labs.settings 1.0
+
+ApplicationWindow {
+ width: 1300
+ height: 900
+ visible: true
+
+ Item {
+ id: bookmarkUrls
+
+ property url multiTest: Qt.resolvedUrl("qrc:/test/favicon-multi-gray.html")
+ property url candidatesTest: Qt.resolvedUrl("qrc:/test/favicon-candidates-gray.html")
+ property url aboutBlank: Qt.resolvedUrl("about:blank")
+ property url qtHome: Qt.resolvedUrl("http://www.qt.io/")
+ }
+
+ Settings {
+ id: appSettings
+
+ property alias autoLoadIconsForPage: autoLoadIconsForPage.checked
+ property alias touchIconsEnabled: touchIconsEnabled.checked
+ }
+
+ SplitView {
+ anchors.fill: parent
+ orientation: Qt.Vertical
+
+ FaviconPanel {
+ id: faviconPanel
+
+ Layout.fillWidth: true
+ Layout.minimumHeight: 200
+
+ Layout.margins: 2
+
+ iconUrl: webEngineView && webEngineView.icon
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.topMargin: 2
+
+ AddressBar {
+ id: addressBar
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 5
+ Layout.rightMargin: 5
+ height: 25
+
+ color: "white"
+ radius: 4
+
+ progress: webEngineView && webEngineView.loadProgress
+ iconUrl: webEngineView && webEngineView.icon
+ pageUrl: webEngineView && webEngineView.url
+
+ onAccepted: webEngineView.url = addressUrl
+ }
+
+ Rectangle {
+ id: toolBar
+
+ Layout.fillWidth: true
+ Layout.leftMargin: 5
+ Layout.rightMargin: 5
+ Layout.preferredHeight: 25
+
+ RowLayout {
+ anchors.verticalCenter: parent.verticalCenter
+
+ Button {
+ text: "Multi-sized Favicon Test"
+ onClicked: webEngineView.url = bookmarkUrls.multiTest
+ enabled: webEngineView.url != bookmarkUrls.multiTest
+ }
+
+ Button {
+ text: "Candidate Favicons Test"
+ onClicked: webEngineView.url = bookmarkUrls.candidatesTest
+ enabled: webEngineView.url != bookmarkUrls.candidatesTest
+ }
+
+ Button {
+ text: "About Blank"
+ onClicked: webEngineView.url = bookmarkUrls.aboutBlank
+ enabled: webEngineView.url != bookmarkUrls.aboutBlank
+ }
+
+ Button {
+ text: "Qt Home Page"
+ onClicked: webEngineView.url = bookmarkUrls.qtHome
+ enabled: webEngineView.url != bookmarkUrls.qtHome
+ }
+ }
+
+ ToolButton {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+
+ menu: Menu {
+ MenuItem {
+ id: autoLoadIconsForPage
+ text: "Icons On"
+ checkable: true
+ checked: WebEngine.settings.autoLoadIconsForPage
+
+ onCheckedChanged: webEngineView.reload()
+ }
+
+ MenuItem {
+ id: touchIconsEnabled
+ text: "Touch Icons On"
+ checkable: true
+ checked: WebEngine.settings.touchIconsEnabled
+ enabled: autoLoadIconsForPage.checked
+
+ onCheckedChanged: webEngineView.reload()
+ }
+ }
+ }
+ }
+
+ WebEngineView {
+ id: webEngineView
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ settings.autoLoadIconsForPage: appSettings.autoLoadIconsForPage
+ settings.touchIconsEnabled: appSettings.touchIconsEnabled
+
+ Component.onCompleted: webEngineView.url = bookmarkUrls.multiTest
+ }
+ }
+ }
+}
diff --git a/tests/manual/quick/faviconbrowser/utils.h b/tests/manual/quick/faviconbrowser/utils.h
new file mode 100644
index 000000000..79aa38cc7
--- /dev/null
+++ b/tests/manual/quick/faviconbrowser/utils.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QUrl>
+
+class Utils : public QObject {
+ Q_OBJECT
+public:
+ Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
+};
+
+inline QUrl Utils::fromUserInput(const QString& userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+#endif // UTILS_H
diff --git a/tests/manual/quick/quick.pro b/tests/manual/quick/quick.pro
new file mode 100644
index 000000000..5251c4b42
--- /dev/null
+++ b/tests/manual/quick/quick.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ faviconbrowser