summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/core/core.pro7
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro1
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt23
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt23
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key28
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key28
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp98
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc8
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp53
-rw-r--r--tests/auto/quick/dialogs/dialogs.pro2
-rw-r--r--tests/auto/quick/dialogs/server.cpp13
-rw-r--r--tests/auto/quick/dialogs/server.h2
-rw-r--r--tests/auto/quick/dialogs/tst_dialogs.cpp18
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp38
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST9
-rw-r--r--tests/auto/quick/qmltests/data/multifileupload.html2
-rw-r--r--tests/auto/quick/qmltests/data/singlefileupload.html2
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml20
-rw-r--r--tests/auto/quick/qmltests/data/tst_filePicker.qml106
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml4
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml5
-rw-r--r--tests/auto/quick/qmltests/data/tst_notification.qml122
-rw-r--r--tests/auto/quick/qmltests/data/tst_profile.qml66
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickwebengineview/qquickwebengineview.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp13
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp2
-rw-r--r--tests/auto/quick/quick.pro6
-rw-r--r--tests/auto/quick/tests.pri4
-rw-r--r--tests/auto/shared/data/notification.html70
-rw-r--r--tests/auto/widgets/accessibility/tst_accessibility.cpp2
-rw-r--r--tests/auto/widgets/offscreen/offscreen.pro6
-rw-r--r--tests/auto/widgets/offscreen/test.html7
-rw-r--r--tests/auto/widgets/offscreen/tst_offscreen.cpp61
-rw-r--r--tests/auto/widgets/offscreen/tst_offscreen.qrc6
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp25
-rw-r--r--tests/auto/widgets/proxy/proxy.pro9
-rw-r--r--tests/auto/widgets/proxy/proxy_server.cpp90
-rw-r--r--tests/auto/widgets/proxy/proxy_server.h59
-rw-r--r--tests/auto/widgets/proxy/tst_proxy.cpp69
-rw-r--r--tests/auto/widgets/proxypac/proxypac.pro25
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp271
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST9
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp1543
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc3
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp78
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp4
-rw-r--r--tests/auto/widgets/qwebengineview/resources/image2.pngbin0 -> 14743 bytes
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp17
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc1
-rw-r--r--tests/auto/widgets/widgets.pro15
-rw-r--r--tests/manual/widgets/inputmethods/testview.cpp11
-rw-r--r--tests/manual/widgets/webgl/main.cpp184
-rw-r--r--tests/manual/widgets/webgl/webgl.pro6
-rw-r--r--tests/manual/widgets/widgets.pro3
-rw-r--r--tests/quicktestbrowser/ApplicationRoot.qml1
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml12
-rw-r--r--tests/quicktestbrowser/FeaturePermissionBar.qml29
60 files changed, 1848 insertions, 1484 deletions
diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro
index c1b2147bd..1dc5e052c 100644
--- a/tests/auto/core/core.pro
+++ b/tests/auto/core/core.pro
@@ -1,8 +1,9 @@
TEMPLATE = subdirs
+QT_FOR_CONFIG += network-private
SUBDIRS += \
qwebenginecookiestore \
- qwebengineurlrequestinterceptor \
+ qwebengineurlrequestinterceptor
+
+qtConfig(ssl): SUBDIRS += qwebengineclientcertificatestore
-# QTBUG-60268
-boot2qt: SUBDIRS = ""
diff --git a/tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro b/tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro
new file mode 100644
index 000000000..e99c7f493
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro
@@ -0,0 +1 @@
+include(../tests.pri)
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt
new file mode 100644
index 000000000..1c7a4e6a1
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID6zCCAtOgAwIBAgIUR7/FZjFjCH94EgGF1VOOca1p8PUwDQYJKoZIhvcNAQEL
+BQAwgYQxCzAJBgNVBAYTAkVVMREwDwYDVQQIDAhIRUxTSU5LSTERMA8GA1UEBwwI
+SEVMU0lOS0kxFzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MQ4wDAYDVQQDDAVxdC5p
+bzEmMCQGCSqGSIb3DQEJARYXdmlqaXRoLmtpbmlAY2xheXNvbC5jb20wHhcNMTkw
+MjE5MTIzNjE5WhcNMjAwMjE5MTIzNjE5WjCBhDELMAkGA1UEBhMCRVUxETAPBgNV
+BAgMCEhFTFNJTktJMREwDwYDVQQHDAhIRUxTSU5LSTEXMBUGA1UECgwOVGhlIFF0
+IENvbXBhbnkxDjAMBgNVBAMMBXF0LmlvMSYwJAYJKoZIhvcNAQkBFhd2aWppdGgu
+a2luaUBjbGF5c29sLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AOprCpRWsPUda98sp2iQse8bUcwaaRaWl2LqKXu9ELpeInS1dq+v8/NMx7c67N2B
++1l5dOM1CPsIZ27mIL2Y04fy58lGOtwtpJg5MnR50Vl8lG/NxoAWjc2XJYhhVHfJ
+k+KOME2Z4gMGU/2UoMkN/la/sSDFtApJKhYgRwjvPdDXDNr/QxpNLmSaYwd+Bx/P
+MqEEcUkk+tGHWI+XTvUuFczSGpjTZ+QdgYg4w/WjDD0z+cSOJ553EoeswRZHY35O
+pqwgIBMFwoUPpXb5TfOm6fBeb8i8MbReR1NV2XXPQ2aPcmuY9Cmi8Tol+sXy0MvY
+Yd16eZb0eD5oIGr9UjvfJMsCAwEAAaNTMFEwHQYDVR0OBBYEFHJG773IyFWSDBvD
+tvm1fmP5UbEfMB8GA1UdIwQYMBaAFHJG773IyFWSDBvDtvm1fmP5UbEfMA8GA1Ud
+EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAcaPiAufSZwrALeT1BRiBAj
+TdeC2ly1EBw8BwmEhVmma9GRslZzxcTUiZ+W3aYdPOFFDXE+HyAKY2WBQ1iETpIa
+oeqJKzBTzXXXnXT3Wu9BCD928SH8Srtays9yEZO1DRtSKcBrsipdH3KKu3kkAIVL
+GJ4igY2+2EO+64usMROzaL0WiNexHLPCm9KkURPvGRE3GJULYHEEw15ClYryJI5A
+fwVbcMKhQAQipIgrdoPe6aXfTeELD2RpRvU9nMKTelJI5czx4dYGRXVjjF21qiTr
+ov7+d2rXx/133K13kmeeMzOIJkDX3QJwlcKvegygU6QfJwnkRM7ZUAXGTlt3jW0=
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt
new file mode 100644
index 000000000..cd3ee969e
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID4zCCAsugAwIBAgIUcEB7LtzUwdKmEY5b8yDuC/rvMLswDQYJKoZIhvcNAQEL
+BQAwgYAxCzAJBgNVBAYTAklOMRIwEAYDVQQIDAlLYXJuYXRha2ExEjAQBgNVBAcM
+CUJBTkdBTE9SRTEQMA4GA1UECgwHQ2xheXNvbDEUMBIGA1UEAwwLY2xheXNvbC5j
+b20xITAfBgkqhkiG9w0BCQEWEnZpaml0aEBjbGF5c29sLmNvbTAeFw0xOTAyMTkx
+MjM4NDhaFw0yMDAyMTkxMjM4NDhaMIGAMQswCQYDVQQGEwJJTjESMBAGA1UECAwJ
+S2FybmF0YWthMRIwEAYDVQQHDAlCQU5HQUxPUkUxEDAOBgNVBAoMB0NsYXlzb2wx
+FDASBgNVBAMMC2NsYXlzb2wuY29tMSEwHwYJKoZIhvcNAQkBFhJ2aWppdGhAY2xh
+eXNvbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9pvbiJJnL
+oe5YA6MCUryOYiTmj3PVdPpKMrBe2sdzvO0cx2NXpxWERK9QNnFaJb4fTY+j9fgv
+ru1tsIH3AbnDbXfpEPSD4DmpSXiKgB2+KZhA82ZerJendxqaXaj2BgTG2Tc++Chk
+0wzx/3KRSb97mgPKJK5yNwx3KQjeXAhR5Mkwmmf+ZUfoYHRu4BNneYs7qX9rEPDl
+vrd3AaPTgjapz7EEnSO19BrZHgLWFsM0Kni2vux1jHq1wYRXRTaOG0MrNuvuHuNC
+2j5C+N/MPcuuN9izbshrlteIi2a4526V4Hp1KX1BKAI2LgI+ufzdDEkuPs/u28J7
+tGiXjAmf4YUBAgMBAAGjUzBRMB0GA1UdDgQWBBQFfq9BP0BwBToA5U6gfNaxPDFt
+3jAfBgNVHSMEGDAWgBQFfq9BP0BwBToA5U6gfNaxPDFt3jAPBgNVHRMBAf8EBTAD
+AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBmruPekYCAAgHig66OBEHcl2jCp+MH1dmW
+amM5ET3X0mC588S4+JXCVOOh2XJ2ZSRiy0syPbGd0lG6niX5h35gsqSx9uZyXW/+
+KcTf+LsaxZNusLFtAOExnYuTeeAzofMvIGQpujMhD0p/gk8s64gXnlJZZh8S1OGV
+3Me8PV/cat0nuGpLi/0CYj2lAquG0LfeoGZAp+JHAMJTl/xyK4B/KMvbZ7USK9zz
+gqwLag93s4vBW0dpgu+g80GGhb0bF2ZFjD+j8I0i9OjFbTWxAiHomofQ6Qx12eVY
+rfJs/kVG86cOLJarFHBadjlLz4pu1/sp97TsohFYDy7isRbOQdO2
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key
new file mode 100644
index 000000000..ff9ce14df
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDqawqUVrD1HWvf
+LKdokLHvG1HMGmkWlpdi6il7vRC6XiJ0tXavr/PzTMe3OuzdgftZeXTjNQj7CGdu
+5iC9mNOH8ufJRjrcLaSYOTJ0edFZfJRvzcaAFo3NlyWIYVR3yZPijjBNmeIDBlP9
+lKDJDf5Wv7EgxbQKSSoWIEcI7z3Q1wza/0MaTS5kmmMHfgcfzzKhBHFJJPrRh1iP
+l071LhXM0hqY02fkHYGIOMP1oww9M/nEjieedxKHrMEWR2N+TqasICATBcKFD6V2
++U3zpunwXm/IvDG0XkdTVdl1z0Nmj3JrmPQpovE6JfrF8tDL2GHdenmW9Hg+aCBq
+/VI73yTLAgMBAAECggEAXfjLJOwbxCcnNzAPbDuVGOU6xTdRKVz1ExILzy7bpdpW
+tbKJAaTnhoEhDrLwgVu6BwRJd0urbfbQgASA24CIS9d0U5tzvRAPC3biYw7yfY0T
+dD5pdK+V6PTOdv2Nfvev8QJPGsy1bcD7qowKaI7ThrMRrrGSmwz5ciU+VLaTcUP/
+u8H22Wq+nZZGDtzmAgmHLZzOt79QlBDGsO4y15mss46AKan+ameI+iUjrRzSxZAO
+uT+YHPezWE6M8lYSntvmDFxxhkrdHC8qDsmI+AChs+ELu30zsbbj7fdH1esS9/7q
+PLfd0rHv3H3IfR7nvr0wIyX7DIUI3DhuGRvnRS8wAQKBgQD9vrzppukAIfoawlQW
+XFhDFAC89nReMx7T1r68E8VU4Ng/61KeV+sP269jbPHC0K2/bzHbth4im05oZkcZ
+ZaPWeKGmYCUr+lnV6148iFPeVKX4KROvsgIvJ4LVpJUNO4V5Jg2jQcVlkPN2yc7G
+EssVH4ywREedtCFMui1lGJ46wQKBgQDsgFXP/EM0uijSWqZ2it/tdFeeS7F3Uu+V
+2vErnP/xH8i1BkV2t8sLYeAVNW7fEmHcEx3DrZJ2yH3J3h7MivY5g5su1iXHHcRn
+ux9bnb6uzKYS8PRxVnJVjSg9X9q1q6Tsh6Dia5wKHf60rX3MEi7UsJ36uKNKeC3H
++4zh5tq+iwKBgQDQjbmlbRsqkcKHxdro+gNNNp6YsRPZ7LhUsrbXzIQvDBKRDrA8
+FtTLlutjk8JtNajoo9Ld26SPGwjpw86CMEjl2QY7weArcjvuF+K/a+lK3lX/Tnuw
+t2UWLqpZQEmFs7szZLRmz4MXxHhm1N2PbRjfhqvSoHwgQVHxR0BSTFaYwQKBgQDQ
+8+Zdd4UtXdjZWcw/ah3En4kWS8xFH9qcbS+tl+4t7SYYgqz24hYcPWKNeoM1xfj+
+R0mB7KY+Go/AvmY51AEN+bAvJneEQFGaUKK5AFtL93Y3v/pI9NbZrXjDGSCUaE2z
+yXUk92yLJ8s1eR9vIRWNR2qc7WsgTaQtT5w+rwfPVwKBgQC3udM2j59yDCoAOk3g
+Myz3PU9I3gLk+yQ2yHWRjE0Cundr3zQ7PqlsITUe9xhUfj+soBsRw7yeg5/wYcVJ
+F3hDmAOFb54pW912sD9CQbkhJMX6oVuSegUghPrXDhgiJ9i3TArc9xOKoER4A1s6
+N10tV3NPQprnu2m4jTBykPUJBw==
+-----END PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key
new file mode 100644
index 000000000..f4ae0d2d0
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9pvbiJJnLoe5Y
+A6MCUryOYiTmj3PVdPpKMrBe2sdzvO0cx2NXpxWERK9QNnFaJb4fTY+j9fgvru1t
+sIH3AbnDbXfpEPSD4DmpSXiKgB2+KZhA82ZerJendxqaXaj2BgTG2Tc++Chk0wzx
+/3KRSb97mgPKJK5yNwx3KQjeXAhR5Mkwmmf+ZUfoYHRu4BNneYs7qX9rEPDlvrd3
+AaPTgjapz7EEnSO19BrZHgLWFsM0Kni2vux1jHq1wYRXRTaOG0MrNuvuHuNC2j5C
++N/MPcuuN9izbshrlteIi2a4526V4Hp1KX1BKAI2LgI+ufzdDEkuPs/u28J7tGiX
+jAmf4YUBAgMBAAECggEADLcnEl512UtQGaKUyVEWx00ZQEQZ9hPTvCnN3W45tS7T
+jvxnUrcnICkiv/QGgY7KQnsGyG1zaG8ICDSvYgpBlDLAuWWjnzvnYcxFQrP4Somr
+ZZ9sG6jiuh2oMPVaoLQimdpyc8xbmPb1hTwlSExzhCv9WQ5Ai/PY6BxeNdphzGu2
+sNXm0+BBiwX+UdoVYg9nNEzJe8x1xKIjIw4CWk61ZclLsoScjNOZE7RJ3oqXeYnw
+EqBVqAJTZHYpS3e1LxsstOsZfI4kxdbnGjBydz1aHSP19tycY39kUFmjNq6oiSlv
+22+B1WdZ87POXTF0ISL8l+9HIVOKBCeuDmZ+KgS7KQKBgQD6FunVLHxVtQPS2/e0
+yvtHFqSBHuzL2FMIt6vfl4VhQ6QZ5aNPhbGv1WNcb9Z3pqLPp7zRgIPz63l6yHDT
+xTJEjCAseMoJIb/7ji1/RYE1eOhf3ie1BAuAxjdZ8rNVliZ2i3bt5aOUf4MOQdqE
+HY3/yXqMr1qPJThbyTk4bB3V1wKBgQDCImT4UvQqheMFF9Yev6MhUljm9XOjamk/
+v54pW4De7NR2J+4dR+enEHeO0EKCE+olAXfGztChbY4ytkW5bh5BndGCiYLq6NdS
+X4a1Bf1pM6y9/+QxHIQ99G+TGyfoiTmMT1eZNXZAF4MZN36Qe/Y0P9YlJmnRXDY9
+n8yM4+Tw5wKBgHGr0ITQP4NFT4Ob768BQ81AAW2e/Mp6fONNeJWcbUeUUxZiRiRz
+BByDxTHSs4yW9RGlkDE5VMCdmw2v5Xib/QkjF8ye6lXUPUq9iPh8Qwpm9lf8xdeF
+CyVw8t+zbMfOA5WGNnxTEFMC0jK8w/Gg7VYB4e3oFiVSKZeuko+OtNDpAoGAWFwZ
+QuFW2sfnpVjND1/AGxmE91I+mOGFGAvaLA7G4DBBH6pa+Z7RtDuNf0YRD22LA97g
+Km/Vi7P2peRKZfTV9p2jT1vRZ6Qk5QwvntMkHS707+G5dhT5p81Kv1T73B4hQFiY
+kVZBBTjuZZrZk1+olu17RZtvTGhBE9lY28OaX38CgYEAirReFhouOZc7Ng9gCfTM
+XYzIVZszQ8l8dD2fPhbYw9qSRNvST28s4lLtyRPvoKCpmlUMm5F6Xb65rvICMxc3
+DPnB9iLY6fLY7tETVeV9DEOXki3hoZQ4qkI7OIVbZQn1rA1Du95ZZEGdgE5eEMOC
+SQ9g3B7NYJT3Zs8rkxKajWM=
+-----END PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
new file mode 100644
index 000000000..6d51bf7af
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
+#include <QtWebEngineWidgets/qwebengineprofile.h>
+
+class tst_QWebEngineClientCertificateStore : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineClientCertificateStore();
+ ~tst_QWebEngineClientCertificateStore();
+
+private Q_SLOTS:
+ void addAndListCertificates();
+ void removeAndClearCertificates();
+};
+
+tst_QWebEngineClientCertificateStore::tst_QWebEngineClientCertificateStore()
+{
+}
+
+tst_QWebEngineClientCertificateStore::~tst_QWebEngineClientCertificateStore()
+{
+}
+
+void tst_QWebEngineClientCertificateStore::addAndListCertificates()
+{
+ // Load QSslCertificate
+ QFile certFile(":/resources/certificate.crt");
+ certFile.open(QIODevice::ReadOnly);
+ const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
+
+ // Load QSslKey
+ QFile keyFile(":/resources/privatekey.key");
+ keyFile.open(QIODevice::ReadOnly);
+ const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ // Load second QSslCertificate
+ QFile certFileSecond(":/resources/certificate1.crt");
+ certFileSecond.open(QIODevice::ReadOnly);
+ const QSslCertificate certSecond(certFileSecond.readAll(), QSsl::Pem);
+
+ // Load second QSslKey
+ QFile keyFileSecond(":/resources/privatekey1.key");
+ keyFileSecond.open(QIODevice::ReadOnly);
+ const QSslKey sslKeySecond(keyFileSecond.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ // Add certificates to in-memory store
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(certSecond, sslKeySecond);
+
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+}
+
+void tst_QWebEngineClientCertificateStore::removeAndClearCertificates()
+{
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+
+ // Remove one certificate from in-memory store
+ auto list = QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates();
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->remove(list[0]);
+ QCOMPARE(1, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+
+ // Remove all certificates in-memory store
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->clear();
+ QCOMPARE(0, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+}
+
+QTEST_MAIN(tst_QWebEngineClientCertificateStore)
+#include "tst_qwebengineclientcertificatestore.moc"
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc
new file mode 100644
index 000000000..db481fef6
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/certificate.crt</file>
+ <file>resources/privatekey.key</file>
+ <file>resources/certificate1.crt</file>
+ <file>resources/privatekey1.key</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index b24c05a37..4ff33dbac 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -205,7 +205,7 @@ void tst_QWebEngineCookieStore::basicFilter()
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QTRY_COMPARE(cookieAddedSpy.count(), 2);
- QTRY_COMPARE(accessTested.loadAcquire(), 2);
+ QTRY_COMPARE(accessTested.loadAcquire(), 2); // FIXME?
client->deleteAllCookies();
QTRY_COMPARE(cookieRemovedSpy.count(), 2);
@@ -214,7 +214,7 @@ void tst_QWebEngineCookieStore::basicFilter()
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QTRY_COMPARE(accessTested.loadAcquire(), 4);
+ QTRY_COMPARE(accessTested.loadAcquire(), 4); // FIXME?
// Test cookies are NOT added:
QTest::qWait(100);
QCOMPARE(cookieAddedSpy.count(), 2);
@@ -234,7 +234,7 @@ void tst_QWebEngineCookieStore::html5featureFilter()
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QCOMPARE(accessTested.loadAcquire(), 0);
+ QCOMPARE(accessTested.loadAcquire(), 0); // FIXME?
QTest::ignoreMessage(QtCriticalMsg, QRegularExpression(".*Uncaught SecurityError.*sessionStorage.*"));
page.runJavaScript("sessionStorage.test = 5;");
QTRY_COMPARE(accessTested.loadAcquire(), 1);
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 653a1e421..7d3ad1440 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -54,7 +54,9 @@ private Q_SLOTS:
void cleanupTestCase();
void interceptRequest();
void ipv6HostEncoding();
+ void requestedUrl_data();
void requestedUrl();
+ void setUrlSameUrl_data();
void setUrlSameUrl();
void firstPartyUrl();
void firstPartyUrlNestedIframes_data();
@@ -112,6 +114,7 @@ public:
void interceptRequest(QWebEngineUrlRequestInfo &info) override
{
+ QVERIFY(QThread::currentThread() == QCoreApplication::instance()->thread());
// Since 63 we also intercept some unrelated blob requests..
if (info.requestUrl().scheme() == QLatin1String("blob"))
return;
@@ -133,10 +136,7 @@ public:
// Skip import documents and sandboxed documents.
// See Document::SiteForCookies() in chromium/third_party/blink/renderer/core/dom/document.cc.
- //
- // TODO: Change this to empty URL during the next chromium update:
- // https://chromium-review.googlesource.com/c/chromium/src/+/1213082/
- return requestInfo.firstPartyUrl == QUrl("data:,");
+ return requestInfo.firstPartyUrl == QUrl("");
}
QList<RequestInfo> getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceType type)
@@ -178,7 +178,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
QWebEngineProfile profile;
profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -208,7 +208,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
- profile.setRequestInterceptor(&observer);
+ profile.setUrlRequestInterceptor(&observer);
page.load(QUrl("qrc:///resources/__placeholder__"));
QTRY_COMPARE(loadSpy.count(), 1);
success = loadSpy.takeFirst().takeFirst();
@@ -241,7 +241,7 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
{
QWebEngineProfile profile;
LocalhostContentProvider contentProvider;
- profile.setRequestInterceptor(&contentProvider);
+ profile.setUrlRequestInterceptor(&contentProvider);
QWebEnginePage page(&profile);
QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));
@@ -259,14 +259,27 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
QCOMPARE(contentProvider.requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml"));
}
+void tst_QWebEngineUrlRequestInterceptor::requestedUrl_data()
+{
+ QTest::addColumn<bool>("interceptInPage");
+
+ QTest::newRow("Profile intercept") << false;
+ QTest::newRow("Page intercept") << true;
+}
+
void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
{
+ QFETCH(bool, interceptInPage);
+
QWebEngineProfile profile;
profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ if (!interceptInPage)
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
+ if (interceptInPage)
+ page.setUrlRequestInterceptor(&interceptor);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
@@ -283,19 +296,29 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("http://abcdef.abcdef"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 15000);
QCOMPARE(interceptor.requestInfos.at(3).requestUrl, QUrl("http://abcdef.abcdef/"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
}
+void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl_data()
+{
+ requestedUrl_data();
+}
+
void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
{
+ QFETCH(bool, interceptInPage);
+
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ if (!interceptInPage)
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
+ if (interceptInPage)
+ page.setUrlRequestInterceptor(&interceptor);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
@@ -324,7 +347,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
{
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
@@ -358,7 +381,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -419,7 +442,7 @@ void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -437,7 +460,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
{
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -516,7 +539,7 @@ void tst_QWebEngineUrlRequestInterceptor::passRefererHeader()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(true);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
diff --git a/tests/auto/quick/dialogs/dialogs.pro b/tests/auto/quick/dialogs/dialogs.pro
index e262c3814..29d509b20 100644
--- a/tests/auto/quick/dialogs/dialogs.pro
+++ b/tests/auto/quick/dialogs/dialogs.pro
@@ -1,5 +1,5 @@
include(../tests.pri)
-QT += webengine webengine-private
+QT += core-private webengine webengine-private
HEADERS += \
server.h \
diff --git a/tests/auto/quick/dialogs/server.cpp b/tests/auto/quick/dialogs/server.cpp
index dc9cfe582..dfc7c97ad 100644
--- a/tests/auto/quick/dialogs/server.cpp
+++ b/tests/auto/quick/dialogs/server.cpp
@@ -33,7 +33,6 @@
Server::Server(QObject *parent) : QObject(parent)
{
- m_data.clear();
connect(&m_server, &QTcpServer::newConnection, this, &Server::handleNewConnection);
}
@@ -42,6 +41,11 @@ bool Server::isListening()
return m_server.isListening();
}
+void Server::setReply(const QByteArray &reply)
+{
+ m_reply = reply;
+}
+
void Server::run()
{
if (!m_server.listen(QHostAddress::LocalHost, 5555))
@@ -69,12 +73,7 @@ void Server::handleReadReady()
if (!m_data.endsWith("\r\n\r\n"))
return;
- if (m_data.contains(QByteArrayLiteral("OPEN_AUTH")))
- socket->write("HTTP/1.1 401 Unauthorized\nWWW-Authenticate: "
- "Basic realm=\"Very Restricted Area\"\r\n\r\n");
- if (m_data.contains(QByteArrayLiteral("OPEN_PROXY")))
- socket->write("HTTP/1.1 407 Proxy Auth Required\nProxy-Authenticate: "
- "Basic realm=\"Proxy requires authentication\"\r\n\r\n");
+ socket->write(m_reply);
m_data.clear();
socket->disconnectFromHost();
}
diff --git a/tests/auto/quick/dialogs/server.h b/tests/auto/quick/dialogs/server.h
index 24da47523..fa9a73811 100644
--- a/tests/auto/quick/dialogs/server.h
+++ b/tests/auto/quick/dialogs/server.h
@@ -40,6 +40,7 @@ public:
explicit Server(QObject *parent = nullptr);
bool isListening();
+ void setReply(const QByteArray &reply);
public slots:
void run();
@@ -50,6 +51,7 @@ private slots:
private:
QByteArray m_data;
+ QByteArray m_reply;
QTcpServer m_server;
};
diff --git a/tests/auto/quick/dialogs/tst_dialogs.cpp b/tests/auto/quick/dialogs/tst_dialogs.cpp
index f3a041b62..eee6b2bb6 100644
--- a/tests/auto/quick/dialogs/tst_dialogs.cpp
+++ b/tests/auto/quick/dialogs/tst_dialogs.cpp
@@ -26,7 +26,6 @@
**
****************************************************************************/
-#include "qtwebengineglobal.h"
#include "testhandler.h"
#include "server.h"
#include <QtWebEngine/private/qquickwebenginedialogrequests_p.h>
@@ -146,12 +145,19 @@ void tst_Dialogs::authenticationDialogRequested_data()
QTest::addColumn<QUrl>("url");
QTest::addColumn<QQuickWebEngineAuthenticationDialogRequest::AuthenticationType>("type");
QTest::addColumn<QString>("realm");
- QTest::newRow("Http Authentication Dialog") << QUrl("http://localhost:5555/OPEN_AUTH")
+ QTest::addColumn<QByteArray>("reply");
+ QTest::newRow("Http Authentication Dialog") << QUrl("http://localhost:5555/")
<< QQuickWebEngineAuthenticationDialogRequest::AuthenticationTypeHTTP
- << QStringLiteral("Very Restricted Area");
- QTest::newRow("Proxy Authentication Dialog") << QUrl("http://localhost.:5555/OPEN_PROXY")
+ << QStringLiteral("Very Restricted Area")
+ << QByteArrayLiteral("HTTP/1.1 401 Unauthorized\nWWW-Authenticate: "
+ "Basic realm=\"Very Restricted Area\"\r\n\r\n");
+ QTest::newRow("Proxy Authentication Dialog")<< QUrl("http://qt.io/")
<< QQuickWebEngineAuthenticationDialogRequest::AuthenticationTypeProxy
- << QStringLiteral("Proxy requires authentication");
+ << QStringLiteral("Proxy requires authentication")
+ << QByteArrayLiteral("HTTP/1.1 407 Proxy Auth Required\nProxy-Authenticate: "
+ "Basic realm=\"Proxy requires authentication\"\r\n"
+ "content-length: 0\r\n\r\n");
+
}
void tst_Dialogs::authenticationDialogRequested()
@@ -160,7 +166,9 @@ void tst_Dialogs::authenticationDialogRequested()
QFETCH(QQuickWebEngineAuthenticationDialogRequest::AuthenticationType, type);
QFETCH(QString, realm);
+ QFETCH(QByteArray, reply);
Server server;
+ server.setReply(reply);
server.run();
QTRY_VERIFY2(server.isListening(), "Could not setup authentication server");
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 59973f7d0..90b768ac7 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -35,11 +35,13 @@
#include <QtTest/QtTest>
#include <QtWebEngine/QQuickWebEngineProfile>
#include <QtWebEngine/QQuickWebEngineScript>
+#include <QtWebEngineCore/QWebEngineNotification>
#include <QtWebEngineCore/QWebEngineQuotaRequest>
#include <QtWebEngineCore/QWebEngineRegisterProtocolHandlerRequest>
#include <private/qquickwebengineview_p.h>
#include <private/qquickwebengineaction_p.h>
#include <private/qquickwebenginecertificateerror_p.h>
+#include <private/qquickwebengineclientcertificateselection_p.h>
#include <private/qquickwebenginedialogrequests_p.h>
#include <private/qquickwebenginedownloaditem_p.h>
#include <private/qquickwebenginehistory_p.h>
@@ -60,6 +62,8 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
<< &QQuickWebEngineView::staticMetaObject
<< &QQuickWebEngineAction::staticMetaObject
<< &QQuickWebEngineCertificateError::staticMetaObject
+ << &QQuickWebEngineClientCertificateOption::staticMetaObject
+ << &QQuickWebEngineClientCertificateSelection::staticMetaObject
<< &QQuickWebEngineDownloadItem::staticMetaObject
<< &QQuickWebEngineHistory::staticMetaObject
<< &QQuickWebEngineHistoryListModel::staticMetaObject
@@ -79,6 +83,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
<< &QQuickWebEngineContextMenuRequest::staticMetaObject
<< &QWebEngineQuotaRequest::staticMetaObject
<< &QWebEngineRegisterProtocolHandlerRequest::staticMetaObject
+ << &QWebEngineNotification::staticMetaObject
;
static QList<const char *> knownEnumNames = QList<const char *>();
@@ -86,12 +91,15 @@ static QList<const char *> knownEnumNames = QList<const char *>();
static const QStringList hardcodedTypes = QStringList()
<< "QJSValue"
<< "QQmlListProperty<QQuickWebEngineScript>"
+ << "QQmlListProperty<QQuickWebEngineClientCertificateOption>"
+ << "const QQuickWebEngineClientCertificateOption*"
<< "QQmlWebChannel*"
// Ignore the testSupport types without making a fuss.
<< "QQuickWebEngineTestSupport*"
<< "QQuickWebEngineErrorPage*"
<< "const QQuickWebEngineContextMenuData*"
<< "QWebEngineCookieStore*"
+ << "Qt::LayoutDirection"
;
static const QStringList expectedAPI = QStringList()
@@ -132,6 +140,17 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineCertificateError.overridable --> bool"
<< "QQuickWebEngineCertificateError.rejectCertificate() --> void"
<< "QQuickWebEngineCertificateError.url --> QUrl"
+ << "QQuickWebEngineClientCertificateOption.issuer --> QString"
+ << "QQuickWebEngineClientCertificateOption.subject --> QString"
+ << "QQuickWebEngineClientCertificateOption.effectiveDate --> QDateTime"
+ << "QQuickWebEngineClientCertificateOption.expiryDate --> QDateTime"
+ << "QQuickWebEngineClientCertificateOption.isSelfSigned --> bool"
+ << "QQuickWebEngineClientCertificateOption.select() --> void"
+ << "QQuickWebEngineClientCertificateSelection.host --> QUrl"
+ << "QQuickWebEngineClientCertificateSelection.certificates --> QQmlListProperty<QQuickWebEngineClientCertificateOption>"
+ << "QQuickWebEngineClientCertificateSelection.select(int) --> void"
+ << "QQuickWebEngineClientCertificateSelection.select(const QQuickWebEngineClientCertificateOption*) --> void"
+ << "QQuickWebEngineClientCertificateSelection.selectNone() --> void"
<< "QQuickWebEngineColorDialogRequest.accepted --> bool"
<< "QQuickWebEngineColorDialogRequest.color --> QColor"
<< "QQuickWebEngineContextMenuRequest.CanUndo --> EditFlags"
@@ -303,6 +322,9 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.clearHttpCache() --> void"
<< "QQuickWebEngineProfile.downloadFinished(QQuickWebEngineDownloadItem*) --> void"
<< "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadItem*) --> void"
+ << "QQuickWebEngineProfile.downloadPath --> QString"
+ << "QQuickWebEngineProfile.downloadPathChanged() --> void"
+ << "QQuickWebEngineProfile.presentNotification(QWebEngineNotification*) --> void"
<< "QQuickWebEngineProfile.httpAcceptLanguage --> QString"
<< "QQuickWebEngineProfile.httpAcceptLanguageChanged() --> void"
<< "QQuickWebEngineProfile.httpCacheMaximumSize --> int"
@@ -323,6 +345,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.spellCheckLanguagesChanged() --> void"
<< "QQuickWebEngineProfile.storageName --> QString"
<< "QQuickWebEngineProfile.storageNameChanged() --> void"
+ << "QQuickWebEngineProfile.useForGlobalCertificateVerification --> bool"
+ << "QQuickWebEngineProfile.useForGlobalCertificateVerificationChanged() --> void"
<< "QQuickWebEngineProfile.userScripts --> QQmlListProperty<QQuickWebEngineScript>"
<< "QQuickWebEngineScript.ApplicationWorld --> ScriptWorldId"
<< "QQuickWebEngineScript.Deferred --> InjectionPoint"
@@ -392,6 +416,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.localContentCanAccessRemoteUrlsChanged() --> void"
<< "QQuickWebEngineSettings.localStorageEnabled --> bool"
<< "QQuickWebEngineSettings.localStorageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.pdfViewerEnabled --> bool"
+ << "QQuickWebEngineSettings.pdfViewerEnabledChanged() --> void"
<< "QQuickWebEngineSettings.playbackRequiresUserGesture --> bool"
<< "QQuickWebEngineSettings.playbackRequiresUserGestureChanged() --> void"
<< "QQuickWebEngineSettings.pluginsEnabled --> bool"
@@ -585,6 +611,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.NewViewInTab --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInWindow --> NewViewDestination"
<< "QQuickWebEngineView.NoErrorDomain --> ErrorDomain"
+ << "QQuickWebEngineView.Notifications --> Feature"
<< "QQuickWebEngineView.NoWebAction --> WebAction"
<< "QQuickWebEngineView.NormalTerminationStatus --> RenderProcessTerminationStatus"
<< "QQuickWebEngineView.Note --> PrintedPageSizeId"
@@ -699,6 +726,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.runJavaScript(QString,uint,QJSValue) --> void"
<< "QQuickWebEngineView.scrollPosition --> QPointF"
<< "QQuickWebEngineView.scrollPositionChanged(QPointF) --> void"
+ << "QQuickWebEngineView.selectClientCertificate(QQuickWebEngineClientCertificateSelection*) --> void"
<< "QQuickWebEngineView.setActiveFocusOnPress(bool) --> void"
<< "QQuickWebEngineView.settings --> QQuickWebEngineSettings*"
<< "QQuickWebEngineView.stop() --> void"
@@ -727,6 +755,16 @@ static const QStringList expectedAPI = QStringList()
<< "QWebEngineRegisterProtocolHandlerRequest.origin --> QUrl"
<< "QWebEngineRegisterProtocolHandlerRequest.reject() --> void"
<< "QWebEngineRegisterProtocolHandlerRequest.scheme --> QString"
+ << "QWebEngineNotification.origin --> QUrl"
+ << "QWebEngineNotification.title --> QString"
+ << "QWebEngineNotification.message --> QString"
+ << "QWebEngineNotification.tag --> QString"
+ << "QWebEngineNotification.language --> QString"
+ << "QWebEngineNotification.direction --> Qt::LayoutDirection"
+ << "QWebEngineNotification.show() --> void"
+ << "QWebEngineNotification.click() --> void"
+ << "QWebEngineNotification.close() --> void"
+ << "QWebEngineNotification.closed() --> void"
;
static bool isCheckedEnum(const QByteArray &typeName)
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index dfafbaea4..957911c3b 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -4,15 +4,6 @@ osx
[WebViewGeopermission::test_geoPermissionRequest]
osx
-[WebEngineViewSingleFileUpload::test_acceptDirectory]
-*
-
-[WebEngineViewSingleFileUpload::test_acceptMultipleFilesSelection]
-*
-
-[WebEngineViewSingleFileUpload::test_acceptSingleFileSelection]
-*
-
[WebViewFindText::test_findTextInterruptedByLoad]
*
diff --git a/tests/auto/quick/qmltests/data/multifileupload.html b/tests/auto/quick/qmltests/data/multifileupload.html
index 1f788a377..d41ea15c0 100644
--- a/tests/auto/quick/qmltests/data/multifileupload.html
+++ b/tests/auto/quick/qmltests/data/multifileupload.html
@@ -1,7 +1,7 @@
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<title> Mutli-file Upload </title>
+<title> Failed to Upload </title>
<script src = "./titleupdate.js">
</script>
</head>
diff --git a/tests/auto/quick/qmltests/data/singlefileupload.html b/tests/auto/quick/qmltests/data/singlefileupload.html
index 6cfef7ade..ac91c2c0d 100644
--- a/tests/auto/quick/qmltests/data/singlefileupload.html
+++ b/tests/auto/quick/qmltests/data/singlefileupload.html
@@ -1,7 +1,7 @@
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<title> Single File Upload </title>
+<title> Failed to Upload </title>
<script src = "./titleupdate.js">
</script>
</head>
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 019ebd9dc..5eb704cce 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -28,7 +28,8 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.5
+import QtWebEngine 1.9
+import Qt.labs.platform 1.0
TestWebEngineView {
id: webEngineView
@@ -42,6 +43,12 @@ TestWebEngineView {
property var downloadState: []
property var downloadInterruptReason: null
+ function urlToPath(url) {
+ var path = url.toString()
+ path = path.replace(/^(file:\/{2})/,"")
+ return path
+ }
+
SignalSpy {
id: downLoadRequestedSpy
target: testDownloadProfile
@@ -135,5 +142,16 @@ TestWebEngineView {
tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadCancelled)
tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadItem.UserCanceled)
}
+
+ function test_downloadLocation() {
+ var tmpPath = urlToPath(StandardPaths.writableLocation(StandardPaths.TempLocation));
+ var downloadPath = urlToPath(StandardPaths.writableLocation(StandardPaths.DownloadLocation));
+
+ testDownloadProfile.downloadPath = tmpPath;
+ compare(testDownloadProfile.downloadPath, tmpPath);
+
+ testDownloadProfile.downloadPath = downloadPath;
+ compare(testDownloadProfile.downloadPath, downloadPath);
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml
index 655789bb3..2f813b966 100644
--- a/tests/auto/quick/qmltests/data/tst_filePicker.qml
+++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml
@@ -70,16 +70,61 @@ TestWebEngineView {
webEngineView.waitForLoadSucceeded()
}
- function test_acceptSingleFileSelection() {
- webEngineView.url = Qt.resolvedUrl("singlefileupload.html")
- verify(webEngineView.waitForLoadSucceeded())
+ function test_acceptSingleFileSelection_data() {
+ return [
+ { tag: "/test.txt)", input: "/test.txt", passDefaultDialog: false, passCustomDialog: true },
+ { tag: "/tést.txt", input: "/tést.txt", passDefaultDialog: false, passCustomDialog: true },
+ { tag: "file:///test.txt", input: "file:///test.txt", passDefaultDialog: true, passCustomDialog: false },
+ { tag: "file:///tést.txt", input: "file:///tést.txt", passDefaultDialog: true, passCustomDialog: false },
+ { tag: "file:///t%C3%A9st.txt", input: "file:///t%C3%A9st.txt", passDefaultDialog: true, passCustomDialog: false },
+ { tag: "file://test.txt", input: "file://test.txt", passDefaultDialog: false, passCustomDialog: false },
+ { tag: "file:/test.txt", input: "file:/test.txt", passDefaultDialog: true, passCustomDialog: false },
+ { tag: "file:test//test.txt", input: "file:test//test.txt", passDefaultDialog: false, passCustomDialog: false },
+ { tag: "http://test.txt", input: "http://test.txt", passDefaultDialog: false, passCustomDialog: false },
+ { tag: "qrc:/test.txt", input: "qrc:/test.txt", passDefaultDialog: false, passCustomDialog: false },
+ ];
+ }
- FilePickerParams.selectFiles = true
- FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test1.html"))
+ function test_acceptSingleFileSelection(row) {
+ var expectedFileName;
- keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
- tryCompare(FilePickerParams, "filePickerOpened", true)
- tryCompare(webEngineView, "title", "test1.html")
+ // Default dialog (expects URL).
+ expectedFileName = "Failed to Upload";
+ if (row.passDefaultDialog)
+ expectedFileName = row.input.slice(row.input.lastIndexOf('/') + 1);
+
+ 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);
+ tryCompare(webEngineView, "title", decodeURIComponent(expectedFileName));
+
+
+ // Custom dialog (expects absolute path).
+ var finished = false;
+
+ expectedFileName = "Failed to Upload";
+ if (row.passCustomDialog)
+ expectedFileName = row.input.slice(row.input.lastIndexOf('/') + 1);
+
+ 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; });
+ tryCompare(webEngineView, "title", expectedFileName);
+ webEngineView.fileDialogRequested.disconnect(acceptedFileHandler);
}
function test_acceptMultipleFilesSelection() {
@@ -102,9 +147,10 @@ TestWebEngineView {
FilePickerParams.selectFiles = true
FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data"))
- keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
+ keyClick(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
tryCompare(FilePickerParams, "filePickerOpened", true)
- tryCompare(webEngineView, "title", "data")
+ // Check that the title is a file list (eg. "test1.html,test2.html")
+ tryVerify(function() { return webEngineView.title.match("^([^,]+,)+[^,]+$"); })
}
function test_reject() {
@@ -116,5 +162,45 @@ TestWebEngineView {
wait(100)
compare(titleSpy.count, 0)
}
+
+ function test_acceptMultipleFilesWithCustomDialog_data() {
+ return [
+ { tag: "path", input: ["/test1.txt", "/test2.txt"], expectedValueForDefaultDialog: "Failed to Upload", expectedValueForCustomDialog: "test1.txt,test2.txt" },
+ { tag: "file", input: ["file:///test1.txt", "file:///test2.txt"], expectedValueForDefaultDialog: "test1.txt,test2.txt", expectedValueForCustomDialog: "Failed to Upload" },
+ { tag: "mixed", input: ["file:///test1.txt", "/test2.txt"], expectedValueForDefaultDialog: "test1.txt", expectedValueForCustomDialog: "test2.txt" },
+ ];
+ }
+
+ function test_acceptMultipleFilesWithCustomDialog(row) {
+ // Default dialog (expects URL).
+ 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.expectedValueForDefaultDialog);
+
+
+ // Custom dialog (expects absolute path).
+ 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.expectedValueForCustomDialog);
+ webEngineView.fileDialogRequested.disconnect(acceptedFileHandler);
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index dfcfd586f..1ec574fae 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -116,7 +116,7 @@ TestWebEngineView {
webEngineView.clear()
webEngineView.findText("bla", findFlags, webEngineView.findTextCallback)
- tryCompare(webEngineView, "matchCount", 100)
+ tryCompare(webEngineView, "matchCount", 100, 20000)
verify(!findFailed)
}
@@ -172,7 +172,7 @@ TestWebEngineView {
webEngineView.clear()
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
- tryCompare(webEngineView, "matchCount", 0)
+ tryCompare(webEngineView, "matchCount", 0, 20000)
verify(findFailed)
runJavaScript("document.body.innerHTML = 'blahellobla'");
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 4becbb620..a671c2ec7 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -98,7 +98,8 @@ TestWebEngineView {
verify(dialog.webEngineView.waitForLoadSucceeded());
compare(dialog.webEngineView.url, "");
- compare(newViewRequest.requestedUrl, 'about:blank');
+ // https://chromium-review.googlesource.com/c/chromium/src/+/1300395
+ compare(newViewRequest.requestedUrl, 'about:blank#blocked');
newViewRequestedSpy.clear();
dialog.destroy();
@@ -129,8 +130,8 @@ TestWebEngineView {
verify(webEngineView.waitForLoadSucceeded());
verifyElementHasFocus("popupButton");
keyPress(Qt.Key_Enter);
- compare(newViewRequest.requestedUrl, url);
tryCompare(newViewRequestedSpy, "count", 1);
+ compare(newViewRequest.requestedUrl, url);
compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
verify(newViewRequest.userInitiated);
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
new file mode 100644
index 000000000..773bf4a8e
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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
+
+TestWebEngineView {
+ id: view
+ width: 320
+ height: 320
+
+ property bool permissionRequested: false
+ property bool grantPermission: false
+ property url securityOrigin: ''
+
+ signal consoleMessage(string message)
+
+ SignalSpy {
+ id: spyRequest
+ target: view
+ signalName: 'featurePermissionRequested'
+ }
+
+ onFeaturePermissionRequested: {
+ if (feature === WebEngineView.Notifications) {
+ view.permissionRequested = true
+ view.securityOrigin = securityOrigin
+ view.grantFeaturePermission(securityOrigin, feature, grantPermission)
+ }
+ }
+
+ TestCase {
+ name: 'WebEngineNotification'
+ when: windowShown
+
+ function resolverUrl(html) {
+ return Qt.resolvedUrl('../../../shared/data/' + html)
+ }
+
+ function init() {
+ permissionRequested = false
+ spyRequest.clear()
+ }
+
+ function test_request_data() {
+ return [
+ { tag: 'grant', grant: true, permission: 'granted' },
+ { tag: 'deny', grant: false, permission: 'denied' },
+ ]
+ }
+
+ function test_request(data) {
+ grantPermission = data.grant
+
+ view.url = resolverUrl('notification.html')
+ verify(view.waitForLoadSucceeded())
+
+ view.runJavaScript('resetPermission()')
+ let result = {}
+
+ view.runJavaScript('getPermission()', function (permission) { result.permission = permission })
+ tryCompare(result, 'permission', 'default')
+
+ view.runJavaScript('requestPermission()')
+ spyRequest.wait()
+ verify(permissionRequested)
+ compare(spyRequest.count, 1)
+
+ view.runJavaScript('getPermission()', function (permission) { result.permission = permission })
+ tryCompare(result, 'permission', data.permission)
+ }
+
+ function test_notification() {
+ grantPermission = true
+
+ view.url = resolverUrl('notification.html')
+ view.waitForLoadSucceeded()
+
+ view.runJavaScript('requestPermission()')
+ spyRequest.wait()
+ verify(permissionRequested)
+
+ let title = 'Title', message = 'Message', notification = null
+ view.profile.presentNotification.connect(function (n) { notification = n })
+
+ view.runJavaScript('sendNotification("' + title + '", "' + message + '")')
+ tryVerify(function () { return notification !== null })
+ compare(notification.title, title)
+ compare(notification.message, message)
+ compare(notification.direction, Qt.RightToLeft)
+ compare(notification.origin, securityOrigin)
+ compare(notification.tag, 'tst')
+ compare(notification.language, 'de')
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_profile.qml b/tests/auto/quick/qmltests/data/tst_profile.qml
new file mode 100644
index 000000000..ee7fa4e99
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_profile.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.9
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 300
+
+
+ WebEngineProfile {
+ id: profile1
+ }
+ WebEngineProfile {
+ id: profile2
+ }
+ property bool profile1UsedForGlobalCertificateVerification: profile1.useForGlobalCertificateVerification
+
+ TestCase {
+ name: "WebEngineProfile"
+
+ function test_useForGlobalCertificateVerification() {
+ verify(!profile1.useForGlobalCertificateVerification);
+ verify(!profile2.useForGlobalCertificateVerification);
+ verify(!webEngineView.profile1UsedForGlobalCertificateVerification);
+
+ profile1.useForGlobalCertificateVerification = true;
+ verify(profile1.useForGlobalCertificateVerification);
+ verify(!profile2.useForGlobalCertificateVerification);
+ verify(webEngineView.profile1UsedForGlobalCertificateVerification);
+
+ profile2.useForGlobalCertificateVerification = true;
+ verify(!webEngineView.profile1UsedForGlobalCertificateVerification);
+ verify(!profile1.useForGlobalCertificateVerification);
+ verify(profile2.useForGlobalCertificateVerification);
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index a2b05e091..00e884e11 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -67,6 +67,8 @@ OTHER_FILES += \
$$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 \
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index 76cb18c1e..166a6894e 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -9,8 +9,9 @@ windows
[basicRenderingSanity]
*
+
[javascriptClipboard:default]
opensuse-leap
+
[javascriptClipboard:canPaste]
opensuse-leap
-
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
index c253bc2a6..38c130aa3 100644
--- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
+++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
@@ -1,6 +1,6 @@
include(../tests.pri)
exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
-QT_PRIVATE += webengine-private gui-private webenginecore-private
+QT_PRIVATE += core_private gui-private webengine-private webenginecore-private
HEADERS += ../shared/util.h
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 007acb8b0..74c04635f 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -31,6 +31,7 @@
#include <QScopedPointer>
#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qregularexpression.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
@@ -40,6 +41,7 @@
#include <QtGui/private/qinputmethod_p.h>
#include <QtWebEngine/private/qquickwebengineview_p.h>
#include <QtWebEngine/private/qquickwebenginesettings_p.h>
+#include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
#include <qpa/qplatforminputcontext.h>
#include <functional>
@@ -876,7 +878,7 @@ public:
setAcceptHoverEvents(true);
}
- bool event(QEvent *event) Q_DECL_OVERRIDE
+ bool event(QEvent *event) override
{
switch (event->type()) {
case QEvent::TabletPress:
@@ -999,8 +1001,9 @@ void tst_QQuickWebEngineView::changeLocale()
viewDE->setUrl(url);
QVERIFY(waitForLoadFailed(viewDE.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
- errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
QLocale::setDefault(QLocale("en"));
@@ -1008,8 +1011,9 @@ void tst_QQuickWebEngineView::changeLocale()
viewEN->setUrl(url);
QVERIFY(waitForLoadFailed(viewEN.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").isNull());
- errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
// Reset error page
@@ -1020,8 +1024,9 @@ void tst_QQuickWebEngineView::changeLocale()
viewDE->setUrl(url);
QVERIFY(waitForLoadFailed(viewDE.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
- errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index 2b9742b99..b587f3b27 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -46,7 +46,7 @@ public:
Qt::QueuedConnection);
}
- virtual void exposeEvent(QExposeEvent *e) Q_DECL_OVERRIDE {
+ virtual void exposeEvent(QExposeEvent *e) override {
QQuickView::exposeEvent(e);
emit _q_exposeChanged();
}
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 50a6a8587..81b62b4e7 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -1,5 +1,5 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
-QT_FOR_CONFIG += webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) # workaround for QTBUG-68093
+QT_FOR_CONFIG += webengine-private
TEMPLATE = subdirs
@@ -18,4 +18,4 @@ qtConfig(webengine-testsupport) {
}
# QTBUG-66055
-boot2qt: SUBDIRS -= inspectorserver qquickwebenginedefaultsurfaceformat qquickwebengineview qmltests dialogs qtbug-70248
+boot2qt: SUBDIRS -= inspectorserver qquickwebengineview qmltests
diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri
index f7104ad9c..1bf69da43 100644
--- a/tests/auto/quick/tests.pri
+++ b/tests/auto/quick/tests.pri
@@ -1,5 +1,5 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
-QT_FOR_CONFIG += webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) # workaround for QTBUG-68093
+QT_FOR_CONFIG += webengine-private
TEMPLATE = app
diff --git a/tests/auto/shared/data/notification.html b/tests/auto/shared/data/notification.html
new file mode 100644
index 000000000..1d1e9c411
--- /dev/null
+++ b/tests/auto/shared/data/notification.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<html>
+<head>
+<title>Desktop Notifications Demo</title>
+<script>
+ function resetPermission() { document.Notification = 'default' }
+
+ function getPermission() { return document.Notification }
+
+ function sendNotification(title, body) {
+ let notification = new Notification(title, { body: body, dir: 'rtl', lang: 'de', tag: 'tst' })
+ notification.onclick = function() { console.info('onclick') }
+ notification.onclose = function() { console.info('onclose') }
+ notification.onerror = function(error) { console.info('onerror: ' + error) }
+ notification.onshow = function() { console.info('onshow') }
+ }
+
+ function makeNotification() {
+ let title = document.getElementById("title").value
+ let body = document.getElementById("body").value
+ console.log('making notification:', title)
+ sendNotification(title, body)
+ }
+
+ function requestPermission(callback) {
+ Notification.requestPermission().then(function (permission) {
+ document.Notification = permission
+ if (callback)
+ callback(permission)
+ })
+ }
+
+ function displayNotification() {
+ console.info('notifications are ' + document.Notification)
+
+ let state = document.getElementById('state')
+
+ if (document.Notification === 'denied') {
+ state.innerHTML = 'Notifications disabled'
+ } else if (document.Notification === 'granted') {
+ makeNotification()
+ state.innerHTML = 'notification created'
+ } else {
+ state.innerHTML = 'requesting permission...'
+ requestPermission(function (permission) {
+ console.info('notifications request: ' + permission)
+ if (permission === 'granted') {
+ makeNotification()
+ state.innerHTML = 'permission granted, notification created'
+ } else if (permission === 'denied')
+ state.innerHTML = 'Notifications are disabled'
+ })
+ }
+ }
+
+ document.addEventListener("DOMContentLoaded", function() {
+ document.Notification = Notification.permission
+ })
+</script>
+</head>
+<body>
+ <form name="NotificationForm" id="notificationForm">
+ Title: <input type="text" id="title" placeholder="Notification title" value='sample title'><br>
+ Body: <input type="text" id="body" placeholder="Notification body" value='default body'><br>
+ <input type="button" value="Display Notification" onclick="displayNotification()"><br>
+ <input type="button" value="Reset Permission" onclick="resetPermission()">
+ </form>
+ <div id='state'></div>
+</body>
+</html>
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index 6efbf53ed..b0165cfbc 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -134,7 +134,7 @@ void tst_Accessibility::hierarchy()
QVERIFY(windowRect.contains(inputRect));
QPoint inputCenter = inputRect.center();
QAccessibleInterface *hitTest = view;
- QAccessibleInterface *child = Q_NULLPTR;
+ QAccessibleInterface *child = nullptr;
while (hitTest) {
child = hitTest;
hitTest = hitTest->childAt(inputCenter.x(), inputCenter.y());
diff --git a/tests/auto/widgets/offscreen/offscreen.pro b/tests/auto/widgets/offscreen/offscreen.pro
new file mode 100644
index 000000000..b8e5632f9
--- /dev/null
+++ b/tests/auto/widgets/offscreen/offscreen.pro
@@ -0,0 +1,6 @@
+include(../tests.pri)
+QT += webengine
+qpa.name = QT_QPA_PLATFORM
+qpa.value = offscreen
+QT_TOOL_ENV += qpa
+
diff --git a/tests/auto/widgets/offscreen/test.html b/tests/auto/widgets/offscreen/test.html
new file mode 100644
index 000000000..55063539f
--- /dev/null
+++ b/tests/auto/widgets/offscreen/test.html
@@ -0,0 +1,7 @@
+<html>
+<head><title>TEST</title></head>
+<body>
+Eat me !
+</body>
+</html>
+
diff --git a/tests/auto/widgets/offscreen/tst_offscreen.cpp b/tests/auto/widgets/offscreen/tst_offscreen.cpp
new file mode 100644
index 000000000..7573b0537
--- /dev/null
+++ b/tests/auto/widgets/offscreen/tst_offscreen.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "qtwebengineglobal.h"
+#include <QTest>
+#include <QSignalSpy>
+#include <QWebEngineProfile>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+class tst_OffScreen : public QObject {
+ Q_OBJECT
+public:
+ tst_OffScreen(){}
+
+private slots:
+ void offscreen();
+};
+
+void tst_OffScreen::offscreen()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ view.setPage(&page);
+ page.load(QUrl("qrc:/test.html"));
+ view.show();
+ QTRY_COMPARE(view.isVisible(), true);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count() > 0, true, 20000);
+ QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), true);
+}
+
+#include "tst_offscreen.moc"
+QTEST_MAIN(tst_OffScreen)
+
diff --git a/tests/auto/widgets/offscreen/tst_offscreen.qrc b/tests/auto/widgets/offscreen/tst_offscreen.qrc
new file mode 100644
index 000000000..8a998fe85
--- /dev/null
+++ b/tests/auto/widgets/offscreen/tst_offscreen.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>test.html</file>
+</qresource>
+</RCC>
+
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index 21afead1d..c1307c5e6 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -350,7 +350,7 @@ void tst_Origins::jsUrlOrigin()
QCOMPARE(eval(QSL("new URL(\"qrc:/crysis.css\").origin")), QVariant(QSL("qrc://")));
QCOMPARE(eval(QSL("new URL(\"qrc://foo.com/crysis.css\").origin")), QVariant(QSL("qrc://")));
- // Same with unregistered schemes.
+ // Unregistered schemes behaves like opaque origins.
QCOMPARE(eval(QSL("new URL(\"tst:/banana\").origin")), QVariant(QSL("tst://")));
QCOMPARE(eval(QSL("new URL(\"tst://foo.com/banana\").origin")), QVariant(QSL("tst://")));
@@ -613,8 +613,6 @@ private:
// Try opening a WebSocket from pages loaded over various URL schemes.
void tst_Origins::webSocket()
{
- const int kAbnormalClosure = 1006;
-
EchoServer echoServer;
QWebChannel channel;
channel.registerObject(QSL("echoServer"), &echoServer);
@@ -627,9 +625,9 @@ void tst_Origins::webSocket()
QVERIFY(load(QSL("qrc:/resources/websocket.html")));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
- // Only registered schemes can open WebSockets.
+ // Unregistered schemes can also open WebSockets (since Chromium 71)
QVERIFY(load(QSL("tst:/resources/websocket.html")));
- QTRY_COMPARE(eval(QSL("result")), QVariant(kAbnormalClosure));
+ QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
// Even an insecure registered scheme can open WebSockets.
QVERIFY(load(QSL("PathSyntax:/resources/websocket.html")));
@@ -648,11 +646,10 @@ void tst_Origins::dedicatedWorker()
QTRY_VERIFY(eval(QSL("done")).toBool());
QCOMPARE(eval(QSL("result")), QVariant(42));
- // Unregistered schemes cannot create Workers.
+ // Unregistered schemes can also create Workers (since Chromium 71)
QVERIFY(load(QSL("tst:/resources/dedicatedWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
- QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("Access to dedicated workers is denied to origin 'tst://'")));
+ QCOMPARE(eval(QSL("result")), QVariant(42));
// Even an insecure registered scheme can create Workers.
QVERIFY(load(QSL("PathSyntax:/resources/dedicatedWorker.html")));
@@ -773,15 +770,9 @@ void tst_Origins::createObjectURL()
QVERIFY(load(QSL("qrc:/resources/createObjectURL.html")));
QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:qrc:")));
- // Illegal for unregistered schemes (renderer gets terminated).
- qRegisterMetaType<QWebEnginePage::RenderProcessTerminationStatus>("RenderProcessTerminationStatus");
- QSignalSpy loadFinishedSpy(m_page, &QWebEnginePage::loadFinished);
- QSignalSpy renderProcessTerminatedSpy(m_page, &QWebEnginePage::renderProcessTerminated);
- m_page->load(QSL("tst:/resources/createObjectURL.html"));
- QVERIFY(!renderProcessTerminatedSpy.empty() || renderProcessTerminatedSpy.wait(20000));
- QVERIFY(renderProcessTerminatedSpy.front().value(0).value<QWebEnginePage::RenderProcessTerminationStatus>()
- != QWebEnginePage::NormalTerminationStatus);
- QVERIFY(loadFinishedSpy.empty());
+ // Also legal for unregistered schemes (since Chromium 71)
+ QVERIFY(load(QSL("tst:/resources/createObjectURL.html")));
+ QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:")));
}
QTEST_MAIN(tst_Origins)
diff --git a/tests/auto/widgets/proxy/proxy.pro b/tests/auto/widgets/proxy/proxy.pro
new file mode 100644
index 000000000..802dfad05
--- /dev/null
+++ b/tests/auto/widgets/proxy/proxy.pro
@@ -0,0 +1,9 @@
+include(../tests.pri)
+QT += core-private webengine webengine-private
+
+HEADERS += \
+ proxy_server.h
+
+SOURCES += \
+ proxy_server.cpp
+
diff --git a/tests/auto/widgets/proxy/proxy_server.cpp b/tests/auto/widgets/proxy/proxy_server.cpp
new file mode 100644
index 000000000..55f014914
--- /dev/null
+++ b/tests/auto/widgets/proxy/proxy_server.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "proxy_server.h"
+#include <QDataStream>
+#include <QTcpSocket>
+#include <QDebug>
+
+ProxyServer::ProxyServer(QObject *parent) : QObject(parent)
+{
+ connect(&m_server, &QTcpServer::newConnection, this, &ProxyServer::handleNewConnection);
+}
+
+void ProxyServer::setCredentials(const QByteArray &user, const QByteArray password)
+{
+ m_auth.append(user);
+ m_auth.append(QChar(':'));
+ m_auth.append(password);
+ m_auth = m_auth.toBase64();
+}
+
+bool ProxyServer::isListening()
+{
+ return m_server.isListening();
+}
+
+void ProxyServer::run()
+{
+ if (!m_server.listen(QHostAddress::LocalHost, 5555))
+ qFatal("Could not start the test server");
+}
+
+void ProxyServer::handleNewConnection()
+{
+ // do one connection at the time
+ Q_ASSERT(m_data.isEmpty());
+ QTcpSocket *socket = m_server.nextPendingConnection();
+ Q_ASSERT(socket);
+ connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
+ connect(socket, &QAbstractSocket::readyRead, this, &ProxyServer::handleReadReady);
+}
+
+void ProxyServer::handleReadReady()
+{
+ QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
+ Q_ASSERT(socket);
+
+ m_data.append(socket->readAll());
+
+ if (!m_data.endsWith("\r\n\r\n"))
+ return;
+
+ if (!m_data.contains(QByteArrayLiteral("Proxy-Authorization: Basic"))) {
+ socket->write("HTTP/1.1 407 Proxy Authentication Required\nProxy-Authenticate: "
+ "Basic realm=\"Proxy requires authentication\"\r\n"
+ "content-length: 0\r\n"
+ "\r\n");
+ return;
+ }
+
+ if (m_data.contains(m_auth)) {
+ emit success();
+ }
+ m_data.clear();
+}
diff --git a/tests/auto/widgets/proxy/proxy_server.h b/tests/auto/widgets/proxy/proxy_server.h
new file mode 100644
index 000000000..cb7c30600
--- /dev/null
+++ b/tests/auto/widgets/proxy/proxy_server.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#ifndef PROXY_SERVER_H
+#define PROXY_SERVER_H
+
+#include <QObject>
+#include <QTcpServer>
+
+class ProxyServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit ProxyServer(QObject *parent = nullptr);
+ void setCredentials(const QByteArray &user, const QByteArray password);
+ bool isListening();
+
+public slots:
+ void run();
+
+private slots:
+ void handleNewConnection();
+ void handleReadReady();
+
+signals:
+ void success();
+private:
+ QByteArray m_data;
+ QTcpServer m_server;
+ QByteArray m_auth;
+};
+
+#endif // PROXY_SERVER_H
diff --git a/tests/auto/widgets/proxy/tst_proxy.cpp b/tests/auto/widgets/proxy/tst_proxy.cpp
new file mode 100644
index 000000000..5f5dec016
--- /dev/null
+++ b/tests/auto/widgets/proxy/tst_proxy.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "proxy_server.h"
+#include <QTest>
+#include <QSignalSpy>
+#include <QNetworkProxy>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+
+class tst_Proxy : public QObject {
+ Q_OBJECT
+public:
+ tst_Proxy(){}
+
+private slots:
+ void proxyAuthentication();
+};
+
+void tst_Proxy::proxyAuthentication()
+{
+ QByteArray user(QByteArrayLiteral("test"));
+ QByteArray password(QByteArrayLiteral("pass"));
+ QNetworkProxy proxy;
+ proxy.setType(QNetworkProxy::HttpProxy);
+ proxy.setHostName("localhost");
+ proxy.setPort(5555);
+ proxy.setUser(user);
+ proxy.setPassword(password);
+ QNetworkProxy::setApplicationProxy(proxy);
+ ProxyServer server;
+ server.setCredentials(user,password);
+ server.run();
+ QTRY_VERIFY2(server.isListening(), "Could not setup authentication server");
+ QWebEnginePage page;
+ QSignalSpy successSpy(&server, &ProxyServer::success);
+ page.load(QUrl("http://www.qt.io"));
+ QTRY_VERIFY2(successSpy.count() > 0, "Could not get authentication token");
+}
+
+#include "tst_proxy.moc"
+QTEST_MAIN(tst_Proxy)
+
diff --git a/tests/auto/widgets/proxypac/proxypac.pro b/tests/auto/widgets/proxypac/proxypac.pro
index 00ae90977..4dbcd9365 100644
--- a/tests/auto/widgets/proxypac/proxypac.pro
+++ b/tests/auto/widgets/proxypac/proxypac.pro
@@ -3,26 +3,9 @@ QT += webengine
HEADERS += proxyserver.h
SOURCES += proxyserver.cpp
-# QTBUG-71229
-xgd_desktop.name=XDG_CURRENT_DESKTOP
-xgd_desktop.value=KDE
-QT_TOOL_ENV += xgd_desktop
+proxy_pac.name = QTWEBENGINE_CHROMIUM_FLAGS
+boot2qt:proxy_pac.value = "--single-process --no-sandbox --proxy-pac-url=file://$$PWD/proxy.pac"
+else: proxy_pac.value = --proxy-pac-url="file://$$PWD/proxy.pac"
-kde_home.name=KDEHOME
-kde_home.value=$$OUT_PWD
-QT_TOOL_ENV += kde_home
-
-PROXY_CONFIG= \
- "[Proxy Settings]" \
- "Proxy Config Script=$$PWD/proxy.pac" \
- "ProxyType=2"
-
-mkpath($$OUT_PWD/share/config)
-KDE_FILE = $$OUT_PWD/share/config/kioslaverc
-
-!build_pass {
- write_file($$KDE_FILE, PROXY_CONFIG)
-}
-
-QMAKE_DISTCLEAN += $$KDE_FILE
+QT_TOOL_ENV += proxy_pac
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index 9732de85c..bc474457a 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -31,6 +31,7 @@
#include <QStandardPaths>
#include <QTemporaryDir>
#include <QTest>
+#include <QRegularExpression>
#include <QWebEngineDownloadItem>
#include <QWebEnginePage>
#include <QWebEngineProfile>
@@ -70,6 +71,12 @@ private Q_SLOTS:
void downloadFileNot2();
void downloadDeleted();
void downloadDeletedByProfile();
+ void downloadUniqueFilename_data();
+ void downloadUniqueFilename();
+ void downloadUniqueFilenameWithTimestamp();
+ void downloadToDefaultLocation();
+ void downloadToNonExistentDir();
+ void downloadToReadOnlyDir();
void downloadPathValidation();
private:
@@ -136,6 +143,8 @@ void tst_QWebEngineDownloadItem::cleanup()
QTRY_COMPARE(m_requestedDownloads.count(), 0);
QCOMPARE(m_finishedDownloads.count(), 0);
QVERIFY(m_server->stop());
+ // Set download path to default.
+ m_profile->setDownloadPath("");
}
void tst_QWebEngineDownloadItem::cleanupTestCase()
@@ -845,6 +854,268 @@ void tst_QWebEngineDownloadItem::downloadDeletedByProfile()
QTRY_COMPARE(downloadItem.isNull(), true);
}
+void tst_QWebEngineDownloadItem::downloadUniqueFilename_data()
+{
+ QTest::addColumn<QString>("baseName");
+ QTest::addColumn<QString>("extension");
+
+ QTest::newRow("txt") << QString("test(1.test)") << QString("txt");
+ QTest::newRow("tar.gz") << QString("test(1.test)") << QString("tar.gz");
+}
+
+void tst_QWebEngineDownloadItem::downloadUniqueFilename()
+{
+ QFETCH(QString, baseName);
+ QFETCH(QString, extension);
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->type(), QWebEngineDownloadItem::Attachment);
+ QCOMPARE(item->isSavePageDownload(), false);
+ downloadedFilePath = item->path();
+ downloadFinished = true;
+ });
+ });
+
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + "." + extension);
+
+ for (int i = 1; i <= 2; ++i) {
+ downloadFinished = false;
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension);
+ }
+}
+
+void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
+{
+ // Set up HTTP server
+ QString baseName("test(1.test)");
+ QString extension("txt");
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->page(), m_page);
+ downloadFinished = true;
+ downloadedFilePath = item->path();
+ });
+ });
+
+ // Create the first empty file without uniquifier.
+ {
+ QFile file(m_profile->downloadPath() + "/" + fileName);
+ file.open(QIODevice::ReadWrite);
+ }
+
+ // Create 99 empty files with uniquifier.
+ for (int i = 1; i < 100; i++) {
+ QFile file(m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension);
+ file.open(QIODevice::ReadWrite);
+ }
+
+ // Create 100th (kMaxUniqueFiles) empty file with uniquifier.
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (100)." + extension);
+
+ // Check if the downloaded files are suffixed with timestamp after the 100th download.
+ for (int i = 101; i < 103; i++) {
+ downloadFinished = false;
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QRegularExpression fileNameCheck("^.*" + QRegularExpression::escape(baseName) + " - (.*)[.]" + QRegularExpression::escape(extension) + "$");
+ QRegularExpressionMatch match = fileNameCheck.match(downloadedFilePath);
+ QVERIFY(match.hasMatch());
+ // ISO 8601 Date and time in UTC
+ QRegExp timestamp("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9])([0-5][0-9])([0-5][0-9])([.][0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9])[0-5][0-9])?$");
+ QVERIFY(timestamp.exactMatch(match.captured(1)));
+ }
+}
+
+void tst_QWebEngineDownloadItem::downloadToDefaultLocation()
+{
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+
+ QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+
+ m_profile->setDownloadPath("");
+ QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+
+ m_profile->setDownloadPath(tmpDir.path());
+ QCOMPARE(m_profile->downloadPath(), tmpDir.path());
+
+ m_profile->setDownloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+ QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+}
+
+void tst_QWebEngineDownloadItem::downloadToNonExistentDir()
+{
+ QString baseName("test(1.test)");
+ QString extension("txt");
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->page(), m_page);
+ downloadFinished = true;
+ downloadedFilePath = item->path();
+ });
+ });
+
+ // Set a non-existent directory for the default download location.
+ QString nonExistentDownloadPath(m_profile->downloadPath() + "/non_existent_dir");
+ m_profile->setDownloadPath(nonExistentDownloadPath);
+ QCOMPARE(m_profile->downloadPath(), nonExistentDownloadPath);
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, nonExistentDownloadPath + "/" + fileName);
+}
+
+void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
+{
+#ifdef Q_OS_WIN
+ QSKIP("Cannot change file permissions on Windows.");
+#endif
+ QString baseName("test(1.test)");
+ QString extension("txt");
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadAccepted = false;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ QPointer<QWebEngineDownloadItem> downloadItem;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ downloadItem = item;
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ downloadFinished = true;
+ });
+ downloadAccepted = true;
+ });
+
+ // Change permission for directory.
+ QFile(m_profile->downloadPath()).setPermissions(QFileDevice::ReadOwner);
+ QVERIFY(QFile(m_profile->downloadPath()).exists());
+
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadAccepted);
+
+ QVERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadInterrupted);
+ QCOMPARE(downloadItem->isFinished(), false);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileAccessDenied);
+ QVERIFY(!QFile(downloadedFilePath).exists());
+
+ // Clear m_requestedDownloads explicitly because download is accepted but never finished.
+ m_requestedDownloads.clear();
+ QVERIFY(!downloadFinished);
+ QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner);
+}
+
void tst_QWebEngineDownloadItem::downloadPathValidation()
{
const QString fileName = "test.txt";
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 228efd61c..e6d50da39 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -1,9 +1,3 @@
-[comboBoxPopupPositionAfterMove]
-*
-
-[comboBoxPopupPositionAfterChildMove]
-*
-
[macCopyUnicodeToClipboard]
osx
@@ -18,3 +12,6 @@ windows
[getUserMediaRequestDesktopVideoManyRequests]
windows
+
+[runJavaScriptFromSlot]
+osx
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 098bae9de..dd1140a4f 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -34,7 +34,6 @@
#include <QOpenGLWidget>
#include <QPaintEngine>
#include <QPushButton>
-#include <QRegExp>
#include <QScreen>
#include <QStateMachine>
#include <QtGui/QClipboard>
@@ -50,6 +49,7 @@
#include <qwebenginedownloaditem.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
+#include <qwebenginenotification.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
#include <qwebenginequotarequest.h>
@@ -90,11 +90,8 @@ public Q_SLOTS:
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
- void thirdPartyCookiePolicy();
void comboBoxPopupPositionAfterMove();
void comboBoxPopupPositionAfterChildMove();
- void contextMenuCopy();
- void contextMenuPopulatedOnce();
void acceptNavigationRequest();
void acceptNavigationRequestNavigationType();
void geolocationRequestJS_data();
@@ -103,26 +100,13 @@ private Q_SLOTS:
void actionStates();
void pasteImage();
void popupFormSubmission();
- void userStyleSheet();
- void userStyleSheetFromLocalFileUrl();
- void userStyleSheetFromQrcUrl();
- void modified();
- void contextMenuCrash();
- void updatePositionDependentActionsCrash();
void callbackSpyDeleted();
void multipleProfilesAndLocalStorage();
- void cursorMovements();
void textSelection();
- void textEditing();
void backActionUpdate();
- void testOptionalJSObjects();
- void testLocalStorageVisibility();
- void testEnablePersistentStorage();
+ void localStorageVisibility();
void consoleOutput();
- void errorPageExtension();
- void errorPageExtensionLoadFinished();
void userAgentNewlineStripping();
- void undoActionHaveCustomText();
void renderWidgetHostViewNotShowTopLevel();
void getUserMediaRequest_data();
void getUserMediaRequest();
@@ -134,30 +118,19 @@ private Q_SLOTS:
void crashTests_LazyInitializationOfMainFrame();
- void screenshot_data();
- void screenshot();
-
#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
void acceleratedWebGLScreenshotWithoutView();
void unacceleratedWebGLScreenshotWithoutView();
#endif
void testJSPrompt();
- void testStopScheduledPageRefresh();
void findText();
void findTextResult();
void findTextSuccessiveShouldCallAllCallbacks();
- void supportedContentType();
- // [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT
- // https://bugs.webkit.org/show_bug.cgi?id=79040
- // void infiniteLoopJS();
void deleteQWebEngineViewTwice();
- void renderOnRepaintRequestedShouldNotRecurse();
void loadSignalsOrder_data();
void loadSignalsOrder();
void openWindowDefaultSize();
- void cssMediaTypeGlobalSetting();
- void cssMediaTypePageSetting();
#ifdef Q_OS_MAC
void macCopyUnicodeToClipboard();
@@ -165,12 +138,12 @@ private Q_SLOTS:
void runJavaScript();
void runJavaScriptDisabled();
+ void runJavaScriptFromSlot();
void fullScreenRequested();
void quotaRequested();
// Tests from tst_QWebEngineFrame
- void horizontalScrollAfterBack();
void symmetricUrl();
void progressSignal();
void urlChange();
@@ -182,8 +155,6 @@ private Q_SLOTS:
void setHtmlWithStylesheetResource();
void setHtmlWithBaseURL();
void setHtmlWithJSAlert();
- void inputFieldFocus();
- void hitTestContent();
void baseUrl_data();
void baseUrl();
void scrollPosition();
@@ -191,7 +162,6 @@ private Q_SLOTS:
void evaluateWillCauseRepaint();
void setContent_data();
void setContent();
- void setCacheLoadControlAttribute();
void setUrlWithPendingLoads();
void setUrlToEmpty();
void setUrlToInvalid();
@@ -227,6 +197,11 @@ private Q_SLOTS:
void triggerActionWithoutMenu();
void dynamicFrame();
+ void notificationRequest_data();
+ void notificationRequest();
+ void sendNotification();
+ void contentsSize();
+
private:
static QPoint elementCenter(QWebEnginePage *page, const QString &id);
@@ -368,18 +343,6 @@ private:
bool m_allowGeolocation;
};
-// [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT
-// https://bugs.webkit.org/show_bug.cgi?id=79040
-/*
-void tst_QWebEnginePage::infiniteLoopJS()
-{
- JSTestPage newPage(m_view);
- m_view->setPage(&newPage);
- m_view->setHtml(QString("<html><body>test</body></html>"), QUrl());
- m_view->page()->evaluateJavaScript("var run = true; var a = 1; while (run) { a++; }");
-}
-*/
-
void tst_QWebEnginePage::geolocationRequestJS_data()
{
QTest::addColumn<bool>("allowed");
@@ -659,170 +622,6 @@ protected:
}
};
-void tst_QWebEnginePage::userStyleSheet()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
-
- m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64,"
- + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64()));
- m_view->setHtml("<p>hello world</p>");
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(networkManager->requestedUrls.count() >= 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
-#endif
-}
-
-void tst_QWebEnginePage::userStyleSheetFromLocalFileUrl()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
-
- QUrl styleSheetUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginepage/resources/user.css"));
- m_page->settings()->setUserStyleSheetUrl(styleSheetUrl);
- m_view->setHtml("<p>hello world</p>");
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(networkManager->requestedUrls.count() >= 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
-#endif
-}
-
-void tst_QWebEnginePage::userStyleSheetFromQrcUrl()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
-
- m_page->settings()->setUserStyleSheetUrl(QUrl("qrc:///resources/user.css"));
- m_view->setHtml("<p>hello world</p>");
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(networkManager->requestedUrls.count() >= 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
-#endif
-}
-
-void tst_QWebEnginePage::modified()
-{
-#if !defined(QWEBENGINEPAGE_ISMODIFIED)
- QSKIP("QWEBENGINEPAGE_ISMODIFIED");
-#else
- m_page->setUrl(QUrl("data:text/html,<body>blub"));
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- m_page->setUrl(QUrl("data:text/html,<body id=foo contenteditable>blah"));
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(!m_page->isModified());
-
- m_page->runJavaScript("document.getElementById('foo').focus()");
- evaluateJavaScriptSync(m_page, "document.execCommand('InsertText', true, 'Test');");
-
- QVERIFY(m_page->isModified());
-
- evaluateJavaScriptSync(m_page, "document.execCommand('Undo', true);");
-
- QVERIFY(!m_page->isModified());
-
- evaluateJavaScriptSync(m_page, "document.execCommand('Redo', true);");
-
- QVERIFY(m_page->isModified());
-
- QVERIFY(m_page->history()->canGoBack());
- QVERIFY(!m_page->history()->canGoForward());
- QCOMPARE(m_page->history()->count(), 2);
- QVERIFY(m_page->history()->backItem().isValid());
- QVERIFY(!m_page->history()->forwardItem().isValid());
-
- m_page->history()->back();
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(!m_page->history()->canGoBack());
- QVERIFY(m_page->history()->canGoForward());
-
- QVERIFY(!m_page->isModified());
-
- QCOMPARE(m_page->history()->currentItemIndex(), 0);
-
- m_page->history()->setMaximumItemCount(3);
- QCOMPARE(m_page->history()->maximumItemCount(), 3);
-
- QVariant variant("string test");
- m_page->history()->currentItem().setUserData(variant);
- QVERIFY(m_page->history()->currentItem().userData().toString() == "string test");
-
- m_page->setUrl(QUrl("data:text/html,<body>This is second page"));
- m_page->setUrl(QUrl("data:text/html,<body>This is third page"));
- QCOMPARE(m_page->history()->count(), 2);
- m_page->setUrl(QUrl("data:text/html,<body>This is fourth page"));
- QCOMPARE(m_page->history()->count(), 2);
- m_page->setUrl(QUrl("data:text/html,<body>This is fifth page"));
- QSignalSpy spy(m_page, &QWebEnginePage::saveFrameStateRequested);
- QVERIFY(spy.wait());
-#endif
-}
-
-// https://bugs.webkit.org/show_bug.cgi?id=51331
-void tst_QWebEnginePage::updatePositionDependentActionsCrash()
-{
-#if !defined(QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS)
- QSKIP("QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS");
-#else
- QWebEngineView view;
- view.setHtml("<p>test");
- QPoint pos(0, 0);
- view.page()->updatePositionDependentActions(pos);
- QMenu* contextMenu = 0;
- const QList<QObject *> children = view.children();
- for (QObject *child : children) {
- contextMenu = qobject_cast<QMenu*>(child);
- if (contextMenu)
- break;
- }
- QVERIFY(!contextMenu);
-#endif
-}
-
-// https://bugs.webkit.org/show_bug.cgi?id=20357
-void tst_QWebEnginePage::contextMenuCrash()
-{
-#if !defined(QWEBENGINEPAGE_SWALLOWCONTEXTMENUEVENT)
- QSKIP("QWEBENGINEPAGE_SWALLOWCONTEXTMENUEVENT");
-#else
- QWebEngineView view;
- view.setHtml("<p>test");
- QPoint pos(0, 0);
- QContextMenuEvent event(QContextMenuEvent::Mouse, pos);
- view.page()->swallowContextMenuEvent(&event);
- view.page()->updatePositionDependentActions(pos);
- QMenu* contextMenu = 0;
- const QList<QObject *> children = view.children();
- for (QObject *child : children) {
- contextMenu = qobject_cast<QMenu*>(child);
- if (contextMenu)
- break;
- }
- QVERIFY(contextMenu);
- delete contextMenu;
-#endif
-}
-
void tst_QWebEnginePage::multipleProfilesAndLocalStorage()
{
QDir dir(tmpDirPath());
@@ -895,204 +694,6 @@ public:
}
};
-void tst_QWebEnginePage::cursorMovements()
-{
-#if !defined(QWEBENGINEPAGE_SELECTEDTEXT)
- QSKIP("QWEBENGINEPAGE_SELECTEDTEXT");
-#else
- QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage);
- QString content("<html><body><p id=one>The quick brown fox</p><p id=two>jumps over the lazy dog</p><p>May the source<br/>be with you!</p></body></html>");
- page->setHtml(content);
-
- // this will select the first paragraph
- QString script = "var range = document.createRange(); " \
- "var node = document.getElementById(\"one\"); " \
- "range.selectNode(node); " \
- "getSelection().addRange(range);";
- evaluateJavaScriptSync(page.data(), script);
- QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
-
- QRegExp regExp(" style=\".*\"");
- regExp.setMinimal(true);
- QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>"));
-
- // these actions must exist
- QVERIFY(page->action(QWebEnginePage::MoveToNextChar) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToPreviousChar) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToNextWord) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToPreviousWord) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToNextLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToPreviousLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToStartOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToEndOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToStartOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToEndOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToStartOfDocument) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToEndOfDocument) != 0);
-
- // right now they are disabled because contentEditable is false
- QCOMPARE(page->action(QWebEnginePage::MoveToNextChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfDocument)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfDocument)->isEnabled(), false);
-
- // make it editable before navigating the cursor
- page->setContentEditable(true);
-
- // here the actions are enabled after contentEditable is true
- QCOMPARE(page->action(QWebEnginePage::MoveToNextChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfDocument)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfDocument)->isEnabled(), true);
-
- // cursor will be before the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be between 'j' and 'u' in the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 1);
-
- // cursor will be between 'u' and 'm' in the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 2);
-
- // cursor will be after the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 5);
-
- // cursor will be after the word "lazy"
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 19);
-
- // cursor will be between 'z' and 'y' in "lazy"
- page->triggerAction(QWebEnginePage::MoveToPreviousChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 18);
-
- // cursor will be between 'a' and 'z' in "lazy"
- page->triggerAction(QWebEnginePage::MoveToPreviousChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 17);
-
- // cursor will be before the word "lazy"
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 15);
-
- // cursor will be before the word "quick"
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 4);
-
- // cursor will be between 'p' and 's' in the word "jumps"
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 4);
-
- // cursor will be before the word "jumps"
- page->triggerAction(QWebEnginePage::MoveToStartOfLine);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be after the word "dog"
- page->triggerAction(QWebEnginePage::MoveToEndOfLine);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 23);
-
- // cursor will be between 'w' and 'n' in "brown"
- page->triggerAction(QWebEnginePage::MoveToStartOfLine);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 14);
-
- // cursor will be after the word "fox"
- page->triggerAction(QWebEnginePage::MoveToEndOfLine);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 19);
-
- // cursor will be before the word "The"
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be after the word "you!"
- page->triggerAction(QWebEnginePage::MoveToEndOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
-
- // cursor will be before the word "be"
- page->triggerAction(QWebEnginePage::MoveToStartOfBlock);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be after the word "you!"
- page->triggerAction(QWebEnginePage::MoveToEndOfBlock);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
-
- // try to move before the document start
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- page->triggerAction(QWebEnginePage::MoveToPreviousChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // try to move past the document end
- page->triggerAction(QWebEnginePage::MoveToEndOfDocument);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
- page->triggerAction(QWebEnginePage::MoveToEndOfDocument);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
-#endif
-}
-
void tst_QWebEnginePage::textSelection()
{
QWebEngineView view;
@@ -1107,35 +708,6 @@ void tst_QWebEnginePage::textSelection()
// these actions must exist
QVERIFY(page->action(QWebEnginePage::SelectAll) != 0);
-#if defined(QWEBENGINEPAGE_SELECTACTIONS)
- QVERIFY(page->action(QWebEnginePage::SelectNextChar) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectPreviousChar) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectNextWord) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectPreviousWord) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectNextLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectPreviousLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectStartOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectEndOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectStartOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectEndOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectStartOfDocument) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectEndOfDocument) != 0);
-
- // right now they are disabled because contentEditable is false and
- // there isn't an existing selection to modify
- QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), false);
-#endif
// ..but SelectAll is awalys enabled
QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), true);
@@ -1150,173 +722,10 @@ void tst_QWebEnginePage::textSelection()
"getSelection().addRange(range);";
evaluateJavaScriptSync(page, selectScript);
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
-#if defined(QWEBENGINEPAGE_SELECTEDHTML)
- QRegExp regExp(" style=\".*\"");
- regExp.setMinimal(true);
- QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>"));
-#endif
// Make sure hasSelection returns true, since there is selected text now...
QCOMPARE(page->hasSelection(), true);
-
-#if defined(QWEBENGINEPAGE_SELECTACTIONS)
- // here the actions are enabled after a selection has been created
- QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true);
-
- // make it editable before navigating the cursor
- page->setContentEditable(true);
-
- // cursor will be before the word "The", this makes sure there is a charet
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // here the actions are enabled after contentEditable is true
- QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true);
-#endif
}
-void tst_QWebEnginePage::textEditing()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage);
- QString content("<html><body><p id=one>The quick brown fox</p>" \
- "<p id=two>jumps over the lazy dog</p>" \
- "<p>May the source<br/>be with you!</p></body></html>");
- page->setHtml(content);
-
- // these actions must exist
- QVERIFY(page->action(QWebEnginePage::Cut) != 0);
- QVERIFY(page->action(QWebEnginePage::Copy) != 0);
- QVERIFY(page->action(QWebEnginePage::Paste) != 0);
- QVERIFY(page->action(QWebEnginePage::DeleteStartOfWord) != 0);
- QVERIFY(page->action(QWebEnginePage::DeleteEndOfWord) != 0);
- QVERIFY(page->action(QWebEnginePage::SetTextDirectionDefault) != 0);
- QVERIFY(page->action(QWebEnginePage::SetTextDirectionLeftToRight) != 0);
- QVERIFY(page->action(QWebEnginePage::SetTextDirectionRightToLeft) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleBold) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleItalic) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleUnderline) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertParagraphSeparator) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertLineSeparator) != 0);
- QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle) != 0);
- QVERIFY(page->action(QWebEnginePage::RemoveFormat) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleStrikethrough) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleSubscript) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleSuperscript) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertUnorderedList) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertOrderedList) != 0);
- QVERIFY(page->action(QWebEnginePage::Indent) != 0);
- QVERIFY(page->action(QWebEnginePage::Outdent) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignCenter) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignJustified) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignLeft) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignRight) != 0);
-
- // right now they are disabled because contentEditable is false
- QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::Paste)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::DeleteStartOfWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::DeleteEndOfWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionDefault)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionLeftToRight)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionRightToLeft)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleBold)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleItalic)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleUnderline)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertParagraphSeparator)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertLineSeparator)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleStrikethrough)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleSubscript)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleSuperscript)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertUnorderedList)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertOrderedList)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::Indent)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::Outdent)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignCenter)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignJustified)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignLeft)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignRight)->isEnabled(), false);
-
- // Select everything
- page->triggerAction(QWebEnginePage::SelectAll);
-
- // make sure it is enabled since there is a selection
- QCOMPARE(page->action(QWebEnginePage::Copy)->isEnabled(), true);
-
- // make it editable before navigating the cursor
- page->setContentEditable(true);
-
- // clear the selection
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // make sure it is disabled since there isn't a selection
- QCOMPARE(page->action(QWebEnginePage::Copy)->isEnabled(), false);
-
- // here the actions are enabled after contentEditable is true
- QCOMPARE(page->action(QWebEnginePage::Paste)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::DeleteStartOfWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::DeleteEndOfWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionDefault)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionLeftToRight)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionRightToLeft)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleBold)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleItalic)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleUnderline)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertParagraphSeparator)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertLineSeparator)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleStrikethrough)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleSubscript)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleSuperscript)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertUnorderedList)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertOrderedList)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::Indent)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::Outdent)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignCenter)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignJustified)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignLeft)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignRight)->isEnabled(), true);
-
- // make sure these are disabled since there isn't a selection
- QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), false);
-
- // make sure everything is selected
- page->triggerAction(QWebEnginePage::SelectAll);
-
- // this is only true if there is an editable selection
- QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), true);
-#endif
-}
void tst_QWebEnginePage::backActionUpdate()
{
@@ -1337,243 +746,39 @@ void tst_QWebEnginePage::backActionUpdate()
QVERIFY(action->isEnabled());
}
-#if defined(QWEBENGINEPAGE_SETTINGS)
-static inline bool testFlag(QWebEnginePage& webPage, QWebEngineSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue)
-{
- webPage.settings()->setAttribute(settingAttribute, settingValue);
- return evaluateJavaScriptSync(&webPage, QString("(window.%1 != undefined)").arg(jsObjectName)).toBool();
-}
-#endif
-
-void tst_QWebEnginePage::testOptionalJSObjects()
+void tst_QWebEnginePage::localStorageVisibility()
{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINSETTINGS");
-#else
- // Once a feature is enabled and the JS object is accessed turning off the setting will not turn off
- // the visibility of the JS object any more. For this reason this test uses two QWebEnginePage instances.
- // Part of the test is to make sure that the QWebEnginePage instances do not interfere with each other so turning on
- // a feature for one instance will not turn it on for another.
-
- QWebEnginePage webPage1;
- QWebEnginePage webPage2;
-
- webPage1.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
- webPage2.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
-
- QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue);
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", true), true);
- QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue);
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), true);
-
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::LocalStorageEnabled, "localStorage", true), true);
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), true);
-#endif
-}
-
-#if defined(QWEBENGINEPAGE_SETTINGS)
-static inline bool checkLocalStorageVisibility(QWebEnginePage& webPage, bool localStorageEnabled)
-{
- webPage.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, localStorageEnabled);
- return evaluateJavaScriptSync(&webPage, QString("(window.localStorage != undefined)")).toBool();
-}
-#endif
-
-void tst_QWebEnginePage::testLocalStorageVisibility()
-{
-#if !defined(QWEBENGINEPAGE_SETTINGS)
- QSKIP("QWEBENGINEPAGE_SETTINGS");
-#else
- // Local storage's visibility depends on its security origin, which depends on base url.
- // Initially, it will test it with base urls that get a globally unique origin, which may not
- // be able to use local storage even if the feature is enabled. Then later the same test is
- // done but with urls that would get a valid origin, so local storage could be used.
- // Before every test case it checks if local storage is not already visible.
-
- QWebEnginePage webPage;
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl());
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("invalid"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("://misparsed.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("about:blank"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("data:text/html,test"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("file:///"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("https://www.example.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("ftp://files.example.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("file:///path/to/index.html"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-#endif
-}
-
-void tst_QWebEnginePage::testEnablePersistentStorage()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- QWebEnginePage webPage;
-
- // By default all persistent options should be disabled
- QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::LocalStorageEnabled), false);
- QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled), false);
- QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled), false);
- QVERIFY(webPage.settings()->iconDatabasePath().isEmpty());
-
- QWebEngineSettings::enablePersistentStorage();
-
-
- QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::LocalStorageEnabled), true);
- QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled), true);
- QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled), true);
-
- QTRY_VERIFY(!webPage.settings()->offlineStoragePath().isEmpty());
- QTRY_VERIFY(!webPage.settings()->offlineWebApplicationCachePath().isEmpty());
- QTRY_VERIFY(!webPage.settings()->iconDatabasePath().isEmpty());
-#endif
-}
-
-
-#if defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
-class ErrorPage : public QWebEnginePage
-{
-public:
-
- ErrorPage(QWidget* parent = 0): QWebEnginePage(parent)
- {
- }
-
- virtual bool supportsExtension(Extension extension) const
- {
- return extension == ErrorPageExtension;
- }
-
- virtual bool extension(Extension, const ExtensionOption* option, ExtensionReturn* output)
- {
- ErrorPageExtensionReturn* errorPage = static_cast<ErrorPageExtensionReturn*>(output);
-
- errorPage->contentType = "text/html";
- errorPage->content = "error";
- return true;
- }
-};
-#endif
-
-void tst_QWebEnginePage::errorPageExtension()
-{
-#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
- QSKIP("QWEBENGINEPAGE_ERRORPAGEEXTENSION");
-#else
- ErrorPage page;
- m_view->setPage(&page);
-
- QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
-
- m_view->setUrl(QUrl("data:text/html,foo"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
-
- page.setUrl(QUrl("http://non.existent/url"));
- QTRY_COMPARE(spyLoadFinished.count(), 2);
- QCOMPARE(toPlainTextSync(&page), QString("error"));
- QCOMPARE(page.history()->count(), 2);
- QCOMPARE(page.history()->currentItem().url(), QUrl("http://non.existent/url"));
- QCOMPARE(page.history()->canGoBack(), true);
- QCOMPARE(page.history()->canGoForward(), false);
-
- page.triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(page.history()->canGoBack(), false);
- QTRY_COMPARE(page.history()->canGoForward(), true);
-
- page.triggerAction(QWebEnginePage::Forward);
- QTRY_COMPARE(page.history()->canGoBack(), true);
- QTRY_COMPARE(page.history()->canGoForward(), false);
-
- page.triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(page.history()->canGoBack(), false);
- QTRY_COMPARE(page.history()->canGoForward(), true);
- QTRY_COMPARE(page.history()->currentItem().url(), QUrl("data:text/html,foo"));
-
- m_view->setPage(0);
-#endif
-}
-
-void tst_QWebEnginePage::errorPageExtensionLoadFinished()
-{
-#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
- QSKIP("QWEBENGINEPAGE_ERRORPAGEEXTENSION");
-#else
- ErrorPage page;
- m_view->setPage(&page);
-
- QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
- QSignalSpy spyFrameLoadFinished(m_view->page(), SIGNAL(loadFinished(bool)));
-
- m_view->setUrl(QUrl("data:text/html,foo"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QTRY_COMPARE(spyFrameLoadFinished.count(), 1);
-
- const bool loadSucceded = spyLoadFinished.at(0).at(0).toBool();
- QVERIFY(loadSucceded);
- const bool frameLoadSucceded = spyFrameLoadFinished.at(0).at(0).toBool();
- QVERIFY(frameLoadSucceded);
-
- m_view->page()->setUrl(QUrl("http://non.existent/url"));
- QTRY_COMPARE(spyLoadFinished.count(), 2);
- QTRY_COMPARE(spyFrameLoadFinished.count(), 2);
-
- const bool nonExistantLoadSucceded = spyLoadFinished.at(1).at(0).toBool();
- QVERIFY(nonExistantLoadSucceded);
- const bool nonExistantFrameLoadSucceded = spyFrameLoadFinished.at(1).at(0).toBool();
- QVERIFY(nonExistantFrameLoadSucceded);
-
- m_view->setPage(0);
-#endif
+ QWebEngineProfile profile;
+ QWebEnginePage webPage1(&profile);
+ QWebEnginePage webPage2(&profile);
+
+ webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+ webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
+
+ QSignalSpy loadSpy1(&webPage1, &QWebEnginePage::loadFinished);
+ QSignalSpy loadSpy2(&webPage2, &QWebEnginePage::loadFinished);
+ webPage1.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
+ webPage2.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
+ QTRY_COMPARE(loadSpy1.count(), 1);
+ QTRY_COMPARE(loadSpy2.count(), 1);
+
+ // The attribute determines the visibility of the window.localStorage object.
+ QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+ QVERIFY(!evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
+
+ // Switching the feature off does not actively remove the object from webPage1.
+ webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
+ webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+ QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+ QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
+
+ // The object disappears only after reloading.
+ webPage1.triggerAction(QWebEnginePage::Reload);
+ webPage2.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy1.count(), 2);
+ QTRY_COMPARE(loadSpy2.count(), 2);
+ QVERIFY(!evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+ QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
}
void tst_QWebEnginePage::userAgentNewlineStripping()
@@ -1598,70 +803,9 @@ void tst_QWebEnginePage::crashTests_LazyInitializationOfMainFrame()
webPage.selectedText();
}
{
-#if defined(QWEBENGINEPAGE_SELECTEDHTML)
- QWebEnginePage webPage;
- webPage.selectedHtml();
-#endif
- }
- {
QWebEnginePage webPage;
webPage.triggerAction(QWebEnginePage::Back, true);
}
- {
-#if defined(QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS)
- QWebEnginePage webPage;
- QPoint pos(10,10);
- webPage.updatePositionDependentActions(pos);
-#endif
- }
-}
-
-#if defined(QWEBENGINEPAGE_RENDER)
-static void takeScreenshot(QWebEnginePage* page)
-{
- page->setViewportSize(page->contentsSize());
- QImage image(page->viewportSize(), QImage::Format_ARGB32);
- QPainter painter(&image);
- page->render(&painter);
- painter.end();
-}
-#endif
-
-void tst_QWebEnginePage::screenshot_data()
-{
- QTest::addColumn<QString>("html");
- QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>";
- QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>");
- QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode='transparent'></embed></body></html>");
-}
-
-void tst_QWebEnginePage::screenshot()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- if (!QDir(TESTS_SOURCE_DIR).exists())
- W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);
-
- QDir::setCurrent(TESTS_SOURCE_DIR);
-
- QFETCH(QString, html);
- QWebEnginePage page;
- page.settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
- page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
- QVERIFY(spyFinished.wait(2000));
-
- // take screenshot without a view
- takeScreenshot(&page);
-
- QWebEngineView view;
- view.setPage(&page);
-
- // take screenshot when attached to a view
- takeScreenshot(&page);
-
- QDir::setCurrent(QApplication::applicationDirPath());
-#endif
}
#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
@@ -1760,37 +904,6 @@ void tst_QWebEnginePage::testJSPrompt()
QVERIFY(res);
}
-void tst_QWebEnginePage::testStopScheduledPageRefresh()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- // Without QWebEnginePage::StopScheduledPageRefresh
- QWebEnginePage page1;
- page1.setNetworkAccessManager(new TestNetworkManager(&page1));
- page1.setHtml("<html><head>"
- "<meta http-equiv=\"refresh\"content=\"0;URL=qrc:///resources/index.html\">"
- "</head><body><h1>Page redirects immediately...</h1>"
- "</body></html>");
- QSignalSpy spyFinished(&page1, &QWebEnginePage::loadFinished);
- QVERIFY(spyFinished.wait();
- QTest::qWait(500);
- QCOMPARE(page1.url(), QUrl(QLatin1String("qrc:///resources/index.html")));
-
- // With QWebEnginePage::StopScheduledPageRefresh
- QWebEnginePage page2;
- page2.setNetworkAccessManager(new TestNetworkManager(&page2));
- page2.setHtml("<html><head>"
- "<meta http-equiv=\"refresh\"content=\"1;URL=qrc:///resources/index.html\">"
- "</head><body><h1>Page redirect test with 1 sec timeout...</h1>"
- "</body></html>");
- page2.triggerAction(QWebEnginePage::StopScheduledPageRefresh);
- QTest::qWait(1500);
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118673", Continue);
- QCOMPARE(page2.url().toString(), QLatin1String("about:blank"));
-#endif
-}
-
void tst_QWebEnginePage::findText()
{
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
@@ -1890,95 +1003,6 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
QVERIFY(spy5.wasCalled());
}
-#if defined(QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES)
-static QString getMimeTypeForExtension(const QString &ext)
-{
- QMimeType mimeType = QMimeDatabase().mimeTypeForFile(QStringLiteral("filename.") + ext.toLower(), QMimeDatabase::MatchExtension);
- if (mimeType.isValid() && !mimeType.isDefault())
- return mimeType.name();
-
- return QString();
-}
-#endif
-
-void tst_QWebEnginePage::supportedContentType()
-{
-#if !defined(QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES)
- QSKIP("QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES");
-#else
- QStringList contentTypes;
-
- // Add supported non image types...
- contentTypes << "text/html" << "text/xml" << "text/xsl" << "text/plain" << "text/"
- << "application/xml" << "application/xhtml+xml" << "application/vnd.wap.xhtml+xml"
- << "application/rss+xml" << "application/atom+xml" << "application/json";
-
-#if ENABLE_MHTML
- contentTypes << "application/x-mimearchive";
-#endif
-
- // Add supported image types...
- const QList<QByteArray> supportedImageFormats = QImageWriter::supportedImageFormats();
- for (const QByteArray &imageType : supportedImageFormats) {
- const QString mimeType = getMimeTypeForExtension(imageType);
- if (!mimeType.isEmpty())
- contentTypes << mimeType;
- }
-
- // Get the mime types supported by webengine...
- const QStringList supportedContentTypes = m_page->supportedContentTypes();
-
- for (const QString &mimeType : qAsConst(contentTypes))
- QVERIFY2(supportedContentTypes.contains(mimeType), QString("'%1' is not a supported content type!").arg(mimeType).toLatin1());
-
- for (const QString &mimeType : qAsConst(contentTypes))
- QVERIFY2(m_page->supportsContentType(mimeType), QString("Cannot handle content types '%1'!").arg(mimeType).toLatin1());
-#endif
-}
-
-void tst_QWebEnginePage::thirdPartyCookiePolicy()
-{
-#if !defined(DUMPRENDERTREESUPPORTQT)
- QSKIP("DUMPRENDERTREESUPPORTQT");
-#else
- QWebEngineSettings::globalSettings()->setThirdPartyCookiePolicy(QWebEngineSettings::AlwaysBlockThirdPartyCookies);
- m_page->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
- QVERIFY(m_page->networkAccessManager()->cookieJar());
-
- // These are all first-party cookies, so should pass.
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.com"), QUrl("http://example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.com"), QUrl("http://doc.example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://aaa.www.example.com"), QUrl("http://doc.example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.com"), QUrl("http://www.example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.co.uk"), QUrl("http://example.co.uk")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.co.uk"), QUrl("http://doc.example.co.uk")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://aaa.www.example.co.uk"), QUrl("http://doc.example.co.uk")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.co.uk"), QUrl("http://www.example.co.uk")));
-
- // These are all third-party cookies, so should fail.
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.com"), QUrl("http://slashdot.org")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.com"), QUrl("http://anotherexample.com")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://anotherexample.com"), QUrl("http://example.com")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.co.uk"), QUrl("http://slashdot.co.uk")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.co.uk"), QUrl("http://anotherexample.co.uk")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://anotherexample.co.uk"), QUrl("http://example.co.uk")));
-#endif
-}
-
static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
{
const auto tlws = QGuiApplication::topLevelWindows();
@@ -1992,9 +1016,8 @@ static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
{
- QScreen *screen = QGuiApplication::primaryScreen();
QWebEngineView view;
- view.move(screen->availableGeometry().topLeft());
+ view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
view.resize(640, 480);
view.show();
@@ -2010,18 +1033,29 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
QWindow *popup = nullptr;
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
+ QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
// Close the popup by clicking somewhere into the page.
QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
+ auto jsViewPosition = [&view]() {
+ QLatin1String script("(function() { return [window.screenX, window.screenY]; })()");
+ QVariantList posList = evaluateJavaScriptSync(view.page(), script).toList();
+ return QPoint(posList.at(0).toInt(), posList.at(1).toInt());
+ };
+
// Move the top-level QWebEngineView a little and check the popup's position.
const QPoint offset(12, 13);
- view.move(screen->availableGeometry().topLeft() + offset);
+ view.move(view.pos() + offset);
+ QTRY_COMPARE(jsViewPosition(), view.pos());
QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
elementCenter(view.page(), "foo"));
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
+ QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + offset, popup->position());
}
@@ -2031,7 +1065,6 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
mainWidget.setLayout(new QHBoxLayout);
QWidget spacer;
- spacer.setMinimumWidth(50);
mainWidget.layout()->addWidget(&spacer);
QWebEngineView view;
@@ -2054,6 +1087,8 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
QWindow *popup = nullptr;
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
+ QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
// Close the popup by clicking somewhere into the page.
@@ -2061,11 +1096,22 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
view.mapTo(view.window(), QPoint(1, 1)));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
+ int originalViewWidth = view.size().width();
+ auto jsViewWidth = [&view]() {
+ QLatin1String script("(function() { return window.innerWidth; })()");
+ int viewWidth = evaluateJavaScriptSync(view.page(), script).toInt();
+ return viewWidth;
+ };
+
// Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView.
- spacer.setMinimumWidth(100);
+ const int offset = 50;
+ spacer.setMinimumWidth(spacer.size().width() + offset);
+ QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset);
+
QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
view.mapTo(view.window(), elementCenter(view.page(), "foo")));
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + QPoint(50, 0), popup->position());
}
@@ -2084,66 +1130,6 @@ void tst_QWebEnginePage::macCopyUnicodeToClipboard()
}
#endif
-void tst_QWebEnginePage::contextMenuCopy()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
-
- view.setHtml("<a href=\"http://www.google.com\">You cant miss this</a>");
-
- view.page()->triggerAction(QWebEnginePage::SelectAll);
- QVERIFY(!view.page()->selectedText().isEmpty());
-
- QWebEngineElement link = view.page()->mainFrame()->findFirstElement("a");
- QPoint pos(link.geometry().center());
- QContextMenuEvent event(QContextMenuEvent::Mouse, pos);
- view.page()->swallowContextMenuEvent(&event);
- view.page()->updatePositionDependentActions(pos);
-
- QList<QMenu*> contextMenus = view.findChildren<QMenu*>();
- QVERIFY(!contextMenus.isEmpty());
- QMenu* contextMenu = contextMenus.first();
- QVERIFY(contextMenu);
-
- QList<QAction *> list = contextMenu->actions();
- int index = list.indexOf(view.page()->action(QWebEnginePage::Copy));
- QVERIFY(index != -1);
-#endif
-}
-
-// https://bugs.webkit.org/show_bug.cgi?id=62139
-void tst_QWebEnginePage::contextMenuPopulatedOnce()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
-
- view.setHtml("<input type=\"text\">");
-
- QWebEngineElement link = view.page()->mainFrame()->findFirstElement("input");
- QPoint pos(link.geometry().center());
- QContextMenuEvent event(QContextMenuEvent::Mouse, pos);
- view.page()->swallowContextMenuEvent(&event);
- view.page()->updatePositionDependentActions(pos);
-
- QList<QMenu*> contextMenus = view.findChildren<QMenu*>();
- QVERIFY(!contextMenus.isEmpty());
- QMenu* contextMenu = contextMenus.first();
- QVERIFY(contextMenu);
-
- QList<QAction *> list = contextMenu->actions();
- QStringList entries;
- while (!list.isEmpty()) {
- QString entry = list.takeFirst()->text();
- QVERIFY(!entries.contains(entry));
- entries << entry;
- }
-#endif
-}
-
void tst_QWebEnginePage::deleteQWebEngineViewTwice()
{
for (int i = 0; i < 2; ++i) {
@@ -2157,62 +1143,6 @@ void tst_QWebEnginePage::deleteQWebEngineViewTwice()
}
}
-#if defined(QWEBENGINEPAGE_RENDER)
-class RepaintRequestedRenderer : public QObject {
- Q_OBJECT
-public:
- RepaintRequestedRenderer(QWebEnginePage* page, QPainter* painter)
- : m_page(page)
- , m_painter(painter)
- , m_recursionCount(0)
- {
- connect(m_page, SIGNAL(repaintRequested(QRect)), this, SLOT(onRepaintRequested(QRect)));
- }
-
-Q_SIGNALS:
- void finished();
-
-private Q_SLOTS:
- void onRepaintRequested(const QRect& rect)
- {
- QCOMPARE(m_recursionCount, 0);
-
- m_recursionCount++;
- m_page->render(m_painter, rect);
- m_recursionCount--;
-
- QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
- }
-
-private:
- QWebEnginePage* m_page;
- QPainter* m_painter;
- int m_recursionCount;
-};
-#endif
-
-void tst_QWebEnginePage::renderOnRepaintRequestedShouldNotRecurse()
-{
-#if !defined(QWEBENGINEPAGE_RENDER)
- QSKIP("QWEBENGINEPAGE_RENDER");
-#else
- QSize viewportSize(720, 576);
- QWebEnginePage page;
-
- QImage image(viewportSize, QImage::Format_ARGB32);
- QPainter painter(&image);
-
- page.setPreferredContentsSize(viewportSize);
- page.setViewportSize(viewportSize);
- RepaintRequestedRenderer r(&page, &painter);
-
- page.setHtml("zalan loves trunk", QUrl());
-
- QSignalSpy spyFinished(&r, &RepaintRequestedRenderer::finished);
- QVERIFY(spyFinished.wait());
-#endif
-}
-
class SpyForLoadSignalsOrder : public QStateMachine {
Q_OBJECT
public:
@@ -2271,24 +1201,6 @@ void tst_QWebEnginePage::loadSignalsOrder()
QTRY_VERIFY(loadSpy.isFinished());
}
-void tst_QWebEnginePage::undoActionHaveCustomText()
-{
-#if !defined(QWEBENGINEPAGE_UNDOACTION)
- QSKIP("QWEBENGINEPAGE_UNDOACTION");
-#else
- m_page->setHtml("<div id=test contenteditable></div>");
- evaluateJavaScriptSync(m_page, "document.getElementById('test').focus()");
-
- evaluateJavaScriptSync(m_page, "document.execCommand('insertText', true, 'Test');");
- QString typingActionText = m_page->action(QWebEnginePage::Undo)->text();
-
- evaluateJavaScriptSync(m_page, "document.execCommand('indent', true);");
- QString alignActionText = m_page->action(QWebEnginePage::Undo)->text();
-
- QVERIFY(typingActionText != alignActionText);
-#endif
-}
-
void tst_QWebEnginePage::renderWidgetHostViewNotShowTopLevel()
{
QWebEnginePage page;
@@ -2607,68 +1519,6 @@ void tst_QWebEnginePage::openWindowDefaultSize()
QCOMPARE(requestedGeometry.height(), 100);
}
-void tst_QWebEnginePage::cssMediaTypeGlobalSetting()
-{
-#if !defined(QWEBENGINESETTINGS_SETCSSMEDIATYPE)
- QSKIP("QWEBENGINESETTINGS_SETCSSMEDIATYPE");
-#else
- QString testHtml("<style>@media tv {body{background-color:red;}}@media handheld {body{background-color:green;}}@media screen {body{background-color:blue;}}</style>");
- QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
-
- QWebEngineSettings::globalSettings()->setCSSMediaType("tv");
- // Clear page specific setting to read from global setting
- m_view->page()->settings()->setCSSMediaType(QString());
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 1);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('tv').matches == true").toBool());
- QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "tv");
-
- QWebEngineSettings::globalSettings()->setCSSMediaType("handheld");
- // Clear page specific setting to read from global setting
- m_view->page()->settings()->setCSSMediaType(QString());
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 2);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('handheld').matches == true").toBool());
- QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "handheld");
-
- QWebEngineSettings::globalSettings()->setCSSMediaType("screen");
- // Clear page specific setting to read from global setting
- m_view->page()->settings()->setCSSMediaType(QString());
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 3);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('screen').matches == true").toBool());
- QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "screen");
-#endif
-}
-
-void tst_QWebEnginePage::cssMediaTypePageSetting()
-{
-#if !defined(QWEBENGINESETTINGS_SETCSSMEDIATYPE)
- QSKIP("QWEBENGINESETTINGS_SETCSSMEDIATYPE");
-#else
- QString testHtml("<style>@media tv {body{background-color:red;}}@media handheld {body{background-color:green;}}@media screen {body{background-color:blue;}}</style>");
- QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
-
- m_view->page()->settings()->setCSSMediaType("tv");
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 1);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('tv').matches == true").toBool());
- QVERIFY(m_view->page()->settings()->cssMediaType() == "tv");
-
- m_view->page()->settings()->setCSSMediaType("handheld");
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 2);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('handheld').matches == true").toBool());
- QVERIFY(m_view->page()->settings()->cssMediaType() == "handheld");
-
- m_view->page()->settings()->setCSSMediaType("screen");
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 3);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('screen').matches == true").toBool());
- QVERIFY(m_view->page()->settings()->cssMediaType() == "screen");
-#endif
-}
-
class JavaScriptCallbackBase
{
public:
@@ -2701,7 +1551,7 @@ public:
JavaScriptCallback() { }
JavaScriptCallback(const QVariant& _expected) : expected(_expected) { }
- void check(const QVariant& result) Q_DECL_OVERRIDE
+ void check(const QVariant& result) override
{
QVERIFY(result.isValid());
QCOMPARE(result, expected);
@@ -2714,7 +1564,7 @@ private:
class JavaScriptCallbackNull : public JavaScriptCallbackBase
{
public:
- void check(const QVariant& result) Q_DECL_OVERRIDE
+ void check(const QVariant& result) override
{
QVERIFY(result.isNull());
// FIXME: Returned null values are currently invalid QVariants.
@@ -2725,7 +1575,7 @@ public:
class JavaScriptCallbackUndefined : public JavaScriptCallbackBase
{
public:
- void check(const QVariant& result) Q_DECL_OVERRIDE
+ void check(const QVariant& result) override
{
QVERIFY(result.isNull());
QVERIFY(!result.isValid());
@@ -2836,6 +1686,28 @@ void tst_QWebEnginePage::runJavaScriptDisabled()
QVariant(2));
}
+// Based on https://bugreports.qt.io/browse/QTBUG-73876
+void tst_QWebEnginePage::runJavaScriptFromSlot()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ page.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine' size='50' />"
+ "</body></html>");
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+
+ QVariant result(-1);
+ connect(&page, &QWebEnginePage::selectionChanged, [&]() {
+ result = evaluateJavaScriptSync(&page, QStringLiteral("2+2"));
+ });
+ evaluateJavaScriptSync(&page, QStringLiteral("const input = document.getElementById('input1');"
+ "input.focus();"
+ "input.select();"));
+ QTRY_COMPARE(result, QVariant(4));
+}
+
void tst_QWebEnginePage::fullScreenRequested()
{
JavaScriptCallbackWatcher watcher;
@@ -3262,55 +2134,6 @@ void tst_QWebEnginePage::setHtmlWithJSAlert()
QCOMPARE(toHtmlSync(&page), html);
}
-void tst_QWebEnginePage::inputFieldFocus()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
- view.setHtml("<html><body><input type=\"text\"></input></body></html>");
- view.resize(400, 100);
- view.show();
- QTest::qWaitForWindowExposed(&view);
- view.activateWindow();
- view.setFocus();
- QTRY_VERIFY(view.hasFocus());
-
- // double the flashing time, should at least blink once already
- int delay = qApp->cursorFlashTime() * 2;
-
- // focus the lineedit and check if it blinks
- bool autoSipEnabled = qApp->autoSipEnabled();
- qApp->setAutoSipEnabled(false);
- const QWebEngineElement inputElement = view.page()->documentElement().findFirst(QLatin1String("input[type=text]"));
- QTest::mouseClick(&view, Qt::LeftButton, 0, inputElement.geometry().center());
- m_inputFieldsTestView = &view;
- view.installEventFilter( this );
- QTest::qWait(delay);
- QVERIFY2(m_inputFieldTestPaintCount >= 3,
- "The input field should have a blinking caret");
- qApp->setAutoSipEnabled(autoSipEnabled);
-#endif
-}
-
-void tst_QWebEnginePage::hitTestContent()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QString html("<html><body><p>A paragraph</p><br/><br/><br/><a href=\"about:blank\" target=\"_foo\" id=\"link\">link text</a></body></html>");
-
- QWebEnginePage page;
- page.setHtml(html);
- page.setViewportSize(QSize(200, 0)); //no height so link is not visible
- const QWebEngineElement linkElement = page.documentElement().findFirst(QLatin1String("a#link"));
- QWebEngineHitTestResult result = page.hitTestContent(linkElement.geometry().center());
- QCOMPARE(result.linkText(), QString("link text"));
- QWebEngineElement link = result.linkElement();
- QCOMPARE(link.attribute("target"), QString("_foo"));
-#endif
-}
-
void tst_QWebEnginePage::baseUrl_data()
{
QTest::addColumn<QString>("html");
@@ -3391,32 +2214,6 @@ void tst_QWebEnginePage::scrollbarsOff()
QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool());
}
-void tst_QWebEnginePage::horizontalScrollAfterBack()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- QWebEngineView view;
- QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
-
- view.page()->settings()->setMaximumPagesInCache(2);
- view.page()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
- view.page()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
-
- view.load(QUrl("qrc:/resources/testiframe2.html"));
- view.resize(200, 200);
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
-
- view.load(QUrl("qrc:/resources/testiframe.html"));
- QTRY_COMPARE(loadSpy.count(), 2);
-
- view.page()->triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
-#endif
-}
-
class WebView : public QWebEngineView
{
Q_OBJECT
@@ -3511,35 +2308,6 @@ private:
QNetworkRequest::CacheLoadControl m_lastCacheLoad;
};
-void tst_QWebEnginePage::setCacheLoadControlAttribute()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- QWebEnginePage page;
- CacheNetworkAccessManager* manager = new CacheNetworkAccessManager(&page);
- page.setNetworkAccessManager(manager);
-
- QNetworkRequest request(QUrl("http://abcdef.abcdef/"));
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysCache);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferCache);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysNetwork);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork);
-#endif
-}
-
void tst_QWebEnginePage::setUrlWithPendingLoads()
{
QWebEnginePage page;
@@ -4503,6 +3271,133 @@ void tst_QWebEnginePage::dynamicFrame()
QCOMPARE(toPlainTextSync(&page).trimmed(), QStringLiteral("foo"));
}
+struct NotificationPage : ConsolePage {
+ Q_OBJECT
+ const QWebEnginePage::PermissionPolicy policy;
+
+public:
+ NotificationPage(QWebEnginePage::PermissionPolicy ppolicy) : policy(ppolicy) {
+ connect(this, &QWebEnginePage::loadFinished, [load = spyLoad.ref()] (bool result) mutable { load(result); });
+
+ connect(this, &QWebEnginePage::featurePermissionRequested,
+ [this] (const QUrl &origin, QWebEnginePage::Feature feature) {
+ if (feature != QWebEnginePage::Notifications)
+ return;
+ if (spyRequest.wasCalled())
+ QFAIL("request executed twise!");
+ setFeaturePermission(origin, feature, policy);
+ spyRequest.ref()(origin);
+ });
+
+ load(QStringLiteral("qrc:///shared/notification.html"));
+ }
+
+ CallbackSpy<bool> spyLoad;
+ CallbackSpy<QUrl> spyRequest;
+
+ QString getPermission() { return evaluateJavaScriptSync(this, "getPermission()").toString(); }
+ void requestPermission() { runJavaScript("requestPermission()"); }
+ void resetPermission() { runJavaScript("resetPermission()"); }
+ void sendNotification(const QString &title, const QString &body) {
+ runJavaScript("sendNotification('" + title + "', '" + body + "')");
+ }
+};
+
+void tst_QWebEnginePage::notificationRequest_data()
+{
+ QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
+ QTest::addColumn<QString>("permission");
+ QTest::newRow("deny") << QWebEnginePage::PermissionDeniedByUser << "denied";
+ QTest::newRow("grant") << QWebEnginePage::PermissionGrantedByUser << "granted";
+}
+
+void tst_QWebEnginePage::notificationRequest()
+{
+ QFETCH(QWebEnginePage::PermissionPolicy, policy);
+ QFETCH(QString, permission);
+
+ NotificationPage page(policy);
+ QVERIFY(page.spyLoad.waitForResult());
+
+ page.resetPermission();
+ QCOMPARE(page.getPermission(), "default");
+
+ page.requestPermission();
+ page.spyRequest.waitForResult();
+ QVERIFY(page.spyRequest.wasCalled());
+
+ QCOMPARE(page.getPermission(), permission);
+}
+
+void tst_QWebEnginePage::sendNotification()
+{
+ NotificationPage page(QWebEnginePage::PermissionGrantedByUser);
+ QVERIFY(page.spyLoad.waitForResult());
+
+ page.resetPermission();
+ page.requestPermission();
+ auto origin = page.spyRequest.waitForResult();
+ QVERIFY(page.spyRequest.wasCalled());
+ QCOMPARE(page.getPermission(), "granted");
+
+ std::unique_ptr<QWebEngineNotification> activeNotification;
+ CallbackSpy<bool> presenter;
+ page.profile()->setNotificationPresenter(
+ [&] (std::unique_ptr<QWebEngineNotification> notification)
+ {
+ activeNotification = std::move(notification);
+ presenter(true);
+ });
+
+ QString title("Title"), message("Message");
+ page.sendNotification(title, message);
+
+ presenter.waitForResult();
+ QVERIFY(presenter.wasCalled());
+ QVERIFY(activeNotification);
+ QCOMPARE(activeNotification->title(), title);
+ QCOMPARE(activeNotification->message(), message);
+ QCOMPARE(activeNotification->origin(), origin);
+ QCOMPARE(activeNotification->direction(), Qt::RightToLeft);
+ QCOMPARE(activeNotification->language(), "de");
+ QCOMPARE(activeNotification->tag(), "tst");
+
+ activeNotification->show();
+ QTRY_VERIFY2(page.messages.contains("onshow"), page.messages.join("\n").toLatin1().constData());
+ activeNotification->click();
+ QTRY_VERIFY2(page.messages.contains("onclick"), page.messages.join("\n").toLatin1().constData());
+ activeNotification->close();
+ QTRY_VERIFY2(page.messages.contains("onclose"), page.messages.join("\n").toLatin1().constData());
+}
+
+void tst_QWebEnginePage::contentsSize()
+{
+ m_view->resize(800, 600);
+ m_view->show();
+
+ QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+ QSignalSpy contentsSizeChangedSpy(m_page, &QWebEnginePage::contentsSizeChanged);
+
+ m_view->setHtml(QString("<html><body style=\"width: 1600px; height: 1200px;\"><p>hi</p></body></html>"));
+
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(contentsSizeChangedSpy.count(), 1);
+
+ // Verify the page's contents size is not limited by the view's size.
+ QCOMPARE(m_page->contentsSize().width(), 1608);
+ QCOMPARE(m_page->contentsSize().height(), 1216);
+
+ // Verify resizing the view does not affect the contents size.
+ m_view->resize(2400, 1800);
+ QCOMPARE(m_page->contentsSize().width(), 1608);
+ QCOMPARE(m_page->contentsSize().height(), 1216);
+
+ // Verify resizing the view does not affect the contents size.
+ m_view->resize(1600, 1200);
+ QCOMPARE(m_page->contentsSize().width(), 1608);
+ QCOMPARE(m_page->contentsSize().height(), 1216);
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index f2bf8c6ff..cf32486e7 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -24,4 +24,7 @@
<file>resources/bar.txt</file>
<file>resources/path with spaces.txt</file>
</qresource>
+<qresource prefix='/shared'>
+ <file alias='notification.html'>../../shared/data/notification.html</file>
+</qresource>
</RCC>
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 3fc8fb45a..8b75067ee 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -29,6 +29,7 @@
#include "../util.h"
#include <QtCore/qbuffer.h>
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineCore/qwebengineurlrequestjob.h>
#include <QtWebEngineCore/qwebenginecookiestore.h>
#include <QtWebEngineCore/qwebengineurlscheme.h>
@@ -55,6 +56,7 @@ private Q_SLOTS:
void urlSchemeHandlerFailRequest();
void urlSchemeHandlerFailOnRead();
void urlSchemeHandlerStreaming();
+ void urlSchemeHandlerRequestHeaders();
void urlSchemeHandlerInstallation();
void customUserAgent();
void httpAcceptLanguage();
@@ -62,7 +64,7 @@ private Q_SLOTS:
void changePersistentPath();
void initiator();
void badDeleteOrder();
- void qtbug_72299(); // this should be the last test
+ void qtbug_71895(); // this should be the last test
};
void tst_QWebEngineProfile::initTestCase()
@@ -393,17 +395,17 @@ public:
{
}
- qint64 readData(char *, qint64) Q_DECL_OVERRIDE
+ qint64 readData(char *, qint64) override
{
m_job->fail(QWebEngineUrlRequestJob::RequestFailed);
return -1;
}
- qint64 writeData(const char *, qint64) Q_DECL_OVERRIDE
+ qint64 writeData(const char *, qint64) override
{
m_job->fail(QWebEngineUrlRequestJob::RequestFailed);
return -1;
}
- void close() Q_DECL_OVERRIDE
+ void close() override
{
QIODevice::close();
deleteLater();
@@ -467,6 +469,64 @@ void tst_QWebEngineProfile::urlSchemeHandlerStreaming()
QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result));
}
+class ExtraHeaderInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ ExtraHeaderInterceptor() { }
+
+ void setExtraHeader(const QByteArray &key, const QByteArray &value)
+ {
+ m_extraKey = key;
+ m_extraValue = value;
+ }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ if (info.requestUrl().scheme() == QLatin1String("myscheme"))
+ info.setHttpHeader(m_extraKey, m_extraValue);
+ }
+
+ QByteArray m_extraKey;
+ QByteArray m_extraValue;
+};
+
+class RequestHeadersUrlSchemeHandler : public ReplyingUrlSchemeHandler
+{
+public:
+ void setExpectedHeader(const QByteArray &key, const QByteArray &value)
+ {
+ m_expectedKey = key;
+ m_expectedValue = value;
+ }
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ const auto requestHeaders = job->requestHeaders();
+ QVERIFY(requestHeaders.contains(m_expectedKey));
+ QCOMPARE(requestHeaders.value(m_expectedKey), m_expectedValue);
+ ReplyingUrlSchemeHandler::requestStarted(job);
+ }
+ QByteArray m_expectedKey;
+ QByteArray m_expectedValue;
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders()
+{
+ RequestHeadersUrlSchemeHandler handler;
+ ExtraHeaderInterceptor interceptor;
+
+ handler.setExpectedHeader("Hello", "World");
+ interceptor.setExtraHeader("Hello", "World");
+
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("myscheme", &handler);
+ profile.setRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl(QStringLiteral("myscheme://whatever")));
+ QVERIFY(loadFinishedSpy.wait());
+}
+
void tst_QWebEngineProfile::urlSchemeHandlerInstallation()
{
FailingUrlSchemeHandler handler;
@@ -478,8 +538,9 @@ void tst_QWebEngineProfile::urlSchemeHandlerInstallation()
QTest::ignoreMessage(
QtWarningMsg,
QRegularExpression("Cannot install a URL scheme handler overriding internal scheme.*"));
+ auto prevHandler = profile.urlSchemeHandler(scheme);
profile.installUrlSchemeHandler(scheme, &handler);
- QCOMPARE(profile.urlSchemeHandler(scheme), nullptr);
+ QCOMPARE(profile.urlSchemeHandler(scheme), prevHandler);
}
// Builtin schemes that *can* be overridden.
@@ -649,7 +710,7 @@ void tst_QWebEngineProfile::badDeleteOrder()
delete view;
}
-void tst_QWebEngineProfile::qtbug_72299()
+void tst_QWebEngineProfile::qtbug_71895()
{
QWebEngineView view;
QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
@@ -659,8 +720,9 @@ void tst_QWebEngineProfile::qtbug_72299()
view.page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache);
view.page()->profile()->cookieStore()->deleteAllCookies();
view.page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
- QVERIFY(loadSpy.front().front().toBool());
+ bool gotSignal = loadSpy.count() || loadSpy.wait(20000);
+ if (!gotSignal)
+ QSKIP("Couldn't load page from network, skipping test.");
}
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index be9e59b8c..9a2ee9311 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -546,7 +546,9 @@ void tst_QWebEngineScript::webChannelWithBadString()
page.setWebChannel(&channel);
page.setUrl(QStringLiteral("qrc:/resources/webChannelWithBadString.html"));
QVERIFY(hostSpy.wait(20000));
- QCOMPARE(host.text(), QString(QChar(QChar::ReplacementCharacter)));
+ // expect 0xD800 see https://chromium-review.googlesource.com/c/1282993
+ QChar data(0xd800);
+ QCOMPARE(host.text(), data);
}
#endif
QTEST_MAIN(tst_QWebEngineScript)
diff --git a/tests/auto/widgets/qwebengineview/resources/image2.png b/tests/auto/widgets/qwebengineview/resources/image2.png
new file mode 100644
index 000000000..8d703640c
--- /dev/null
+++ b/tests/auto/widgets/qwebengineview/resources/image2.png
Binary files differ
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index b9337cbee..d3ea27fc2 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -47,6 +47,7 @@
#include <QStyle>
#include <QtWidgets/qaction.h>
#include <QWebEngineProfile>
+#include <QtCore/qregularexpression.h>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == (expect | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu));
@@ -274,7 +275,7 @@ void tst_QWebEngineView::getWebKitVersion()
void tst_QWebEngineView::changePage_data()
{
QString html = "<html><head><title>%1</title>"
- "<link rel='icon' href='file://" TESTS_SOURCE_DIR "/resources/image2.png'></head></html>";
+ "<link rel='icon' href='qrc:///resources/image2.png'></head></html>";
QUrl urlFrom("data:text/html," + html.arg("TitleFrom"));
QUrl urlTo("data:text/html," + html.arg("TitleTo"));
QUrl nullPage("data:text/html,<html/>");
@@ -592,8 +593,8 @@ class KeyEventRecordingWidget : public QWidget {
public:
QList<QKeyEvent> pressEvents;
QList<QKeyEvent> releaseEvents;
- void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE { pressEvents << *e; }
- void keyReleaseEvent(QKeyEvent *e) Q_DECL_OVERRIDE { releaseEvents << *e; }
+ void keyPressEvent(QKeyEvent *e) override { pressEvents << *e; }
+ void keyReleaseEvent(QKeyEvent *e) override { releaseEvents << *e; }
};
void tst_QWebEngineView::unhandledKeyEventPropagation()
@@ -883,7 +884,7 @@ public:
explicit KeyboardAndMouseEventRecordingWidget(QWidget *parent = 0) :
QWidget(parent), m_eventCounter(0) {}
- bool event(QEvent *event) Q_DECL_OVERRIDE
+ bool event(QEvent *event) override
{
QString eventString;
switch (event->type()) {
@@ -1187,7 +1188,7 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
- errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
QLocale::setDefault(QLocale("en"));
@@ -1197,7 +1198,7 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty());
- errorLines = toPlainTextSync(viewEN.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
// Reset error page
@@ -1210,7 +1211,7 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
- errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
@@ -2641,7 +2642,7 @@ void tst_QWebEngineView::imeJSInputEvents()
view.show();
auto logLines = [&view]() -> QStringList {
- return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegExp(".+"));
+ return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegularExpression(".+"));
};
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
index 53b11bca8..a09be0399 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/keyboardEvents.html</file>
+ <file>resources/image2.png</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index eec8bb389..92159bf83 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -8,7 +8,10 @@ SUBDIRS += \
devtools \
faviconmanager \
loadsignals \
+ offscreen \
origins \
+ proxy \
+ proxypac \
schemes \
shutdown \
qwebenginedownloaditem \
@@ -27,9 +30,6 @@ qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printing
}
-# QTBUG-71229
-linux:!boot2qt: SUBDIRS += proxypac
-
qtConfig(webengine-spellchecker):!cross_compile {
!qtConfig(webengine-native-spellchecker) {
SUBDIRS += spellchecking
@@ -40,7 +40,8 @@ qtConfig(webengine-spellchecker):!cross_compile {
# QTBUG-60268
boot2qt: SUBDIRS -= accessibility defaultsurfaceformat devtools \
- faviconmanager qwebenginepage qwebenginehistory \
- qwebengineprofile qwebenginescript \
- qwebengineview qwebenginedownloaditem qwebenginesettings \
- schemes origins loadsignals
+ qwebenginepage \
+ qwebengineprofile \
+ qwebengineview
+
+win32: SUBDIRS -= offscreen
diff --git a/tests/manual/widgets/inputmethods/testview.cpp b/tests/manual/widgets/inputmethods/testview.cpp
index d41734c2d..14e355caf 100644
--- a/tests/manual/widgets/inputmethods/testview.cpp
+++ b/tests/manual/widgets/inputmethods/testview.cpp
@@ -31,7 +31,7 @@
#include <QDebug>
#include <QFile>
#include <QPushButton>
-#include <QRegExp>
+#include <QRegularExpression>
#include <QStandardItemModel>
#include <QTableView>
#include <QTest>
@@ -77,15 +77,16 @@ void TestView::loadTestData(const QString &testDataPath)
QTextStream testDataStream(&testDataFile);
while (!testDataStream.atEnd()) {
QString line = testDataStream.readLine();
- QRegExp data("^\"(.*)\"\\s*,\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*,\\s*(\\d+)\\s*,\\s*\"(.*)\"\\s*,\\s*\"(.*)\"\\s*$");
- if (!data.exactMatch(line))
+ QRegularExpression data(QRegularExpression::anchoredPattern("^\"(.*)\"\\s*,\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*,\\s*(\\d+)\\s*,\\s*\"(.*)\"\\s*,\\s*\"(.*)\"\\s*$"));
+ QRegularExpressionMatch match = data.match(line);
+ if (!match.hasMatch())
continue;
QStandardItemModel *model = qobject_cast<QStandardItemModel *>(m_tableView->model());
QList<QStandardItem *> row;
- for (int i = 1; i <= data.captureCount(); ++i)
- row.append(new QStandardItem(data.cap(i)));
+ for (int i = 1; i <= match.lastCapturedIndex(); ++i)
+ row.append(new QStandardItem(match.captured(i)));
model->appendRow(row);
}
diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp
new file mode 100644
index 000000000..364eda8b9
--- /dev/null
+++ b/tests/manual/widgets/webgl/main.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+#include <QtCore/QDebug>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QOperatingSystemVersion>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QSurfaceFormat>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QDesktopWidget>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWebEngineWidgets/QWebEngineView>
+
+// Manual test for checking if WebGL (1 or 2) works.
+// Set environment variable QTWEBENGINE_GL_TYPE to one of the following to try and switch
+// the underlying GL implementation (mostly Windows): "desktop", "gles", "gles3", "software".
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit MainWindow(QWidget *parent = nullptr);
+ QSize sizeHint() const;
+
+private:
+ QWebEngineView *view = nullptr;
+};
+
+MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
+{
+ QWidget *centralWidget = new QWidget;
+
+ QGroupBox *horizontalGroupBox = new QGroupBox;
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ QPushButton *exButton1 = new QPushButton(QStringLiteral("Aquarium (WebGL 1)"));
+ QPushButton *exButton2 = new QPushButton(QStringLiteral("Lots of objects (WebGL 1)"));
+ QPushButton *exButton3 = new QPushButton(QStringLiteral("Instanced triangles (WebGL 2)"));
+
+ buttonLayout->addWidget(exButton1);
+ buttonLayout->addWidget(exButton2);
+ buttonLayout->addWidget(exButton3);
+ horizontalGroupBox->setLayout(buttonLayout);
+
+ const QUrl exUrl1 =
+ QUrl(QStringLiteral(
+ "http://webglsamples.org/aquarium/aquarium.html"));
+ const QUrl exUrl2 =
+ QUrl(QStringLiteral(
+ "http://webglsamples.org/lots-o-objects/lots-o-objects-draw-elements.html"));
+ const QUrl exUrl3 =
+ QUrl(QStringLiteral(
+ "http://webglsamples.org/WebGL2Samples/#transform_feedback_instanced"));
+
+ view = new QWebEngineView;
+ connect(exButton1, &QPushButton::clicked, view, [=](){
+ view->setUrl(exUrl1);
+ });
+ connect(exButton2, &QPushButton::clicked, view, [=](){
+ view->setUrl(exUrl2);
+ });
+ connect(exButton3, &QPushButton::clicked, view, [=](){
+ view->setUrl(exUrl3);
+ });
+
+ QVBoxLayout *centralLayout = new QVBoxLayout;
+ centralLayout->addWidget(horizontalGroupBox);
+ centralLayout->addWidget(view, 1);
+
+ centralWidget->setLayout(centralLayout);
+ setCentralWidget(centralWidget);
+
+ view->setUrl(QUrl(QStringLiteral("http://webglsamples.org/aquarium/aquarium.html")));
+ setWindowTitle(tr("WebGL 1 and 2 examples"));
+}
+
+QSize MainWindow::sizeHint() const
+{
+ const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ const QSize size = desktopRect.size() * qreal(0.9);
+ return size;
+}
+
+bool isWindows()
+{
+ return QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows;
+}
+
+// Easy snippets to copy to command line for testing for UNIX only.
+// QTWEBENGINE_GL_TYPE=desktop ./webgl
+// QTWEBENGINE_GL_TYPE=gles ./webgl
+// QTWEBENGINE_GL_TYPE=gles3 ./webgl
+// QTWEBENGINE_GL_TYPE=software ./webgl
+int main(int argc, char *argv[])
+{
+ // Not all options are relevant for all platforms.
+ const QString desktopGL = QStringLiteral("desktop");
+ const QString angle = QStringLiteral("angle"); // Same as gles really, just an alias.
+ const QString gles = QStringLiteral("gles"); // ANGLE on Windows.
+ const QString gles3 = QStringLiteral("gles3"); // ANGLE on Windows.
+ const QString softwareGL = QStringLiteral("software");
+
+ QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+
+ QString glType = qEnvironmentVariable("QTWEBENGINE_GL_TYPE");
+ if (glType.isEmpty()) {
+ if (isWindows())
+ glType = gles3;
+ else
+ glType = desktopGL;
+ }
+
+ if (glType == desktopGL) {
+ QApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
+ qInfo() << QStringLiteral("Trying to use Desktop OpenGL.\n");
+ } else if (glType == gles || glType == gles3 || glType == angle) {
+ QApplication::setAttribute(Qt::AA_UseOpenGLES);
+ if (glType == gles || glType == angle)
+ qInfo() << QStringLiteral("Trying to use OpenGL ES 2.\n");
+ if (glType == gles3)
+ qInfo() << QStringLiteral("Trying to use OpenGL ES 3.\n");
+ } else if (glType == softwareGL) {
+ QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
+ qInfo() << QStringLiteral("Trying to use software OpenGL.\n");
+ }
+
+ if (glType == gles3) {
+ // Set OpenGL ES version 3.
+ QSurfaceFormat format;
+ format.setSamples(4);
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+ format.setVersion(3, 0);
+ QSurfaceFormat::setDefaultFormat(format);
+ }
+
+ QApplication a(argc, argv);
+
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.general=true"));
+ QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext();
+ qInfo() << "Global OpenGL context format: " << globalSharedContext->format() << "\n";
+
+ MainWindow w;
+
+ // Move middle-ish.
+ const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ const QSize pos = desktopRect.size() * qreal(0.1);
+ w.move(pos.width(), pos.height());
+
+ w.show();
+
+ return a.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/webgl/webgl.pro b/tests/manual/widgets/webgl/webgl.pro
new file mode 100644
index 000000000..9141d0221
--- /dev/null
+++ b/tests/manual/widgets/webgl/webgl.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+TARGET = webgl
+QT += core gui widgets webenginewidgets
+CONFIG += c++11
+SOURCES += main.cpp
+
diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro
index f06d3e1c3..34e88f0e3 100644
--- a/tests/manual/widgets/widgets.pro
+++ b/tests/manual/widgets/widgets.pro
@@ -1,4 +1,5 @@
TEMPLATE= subdirs
SUBDIRS += \
- inputmethods
+ inputmethods \
+ webgl
diff --git a/tests/quicktestbrowser/ApplicationRoot.qml b/tests/quicktestbrowser/ApplicationRoot.qml
index 980016535..a2e83e1e6 100644
--- a/tests/quicktestbrowser/ApplicationRoot.qml
+++ b/tests/quicktestbrowser/ApplicationRoot.qml
@@ -53,6 +53,7 @@ QtObject {
var newWindow = browserWindowComponent.createObject(root)
newWindow.currentWebView.profile = profile
profile.downloadRequested.connect(newWindow.onDownloadRequested)
+ profile.presentNotification.connect(newWindow.onPresentNotification)
return newWindow
}
function createDialog(profile) {
diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml
index 22f98e1c5..6c3c160ac 100644
--- a/tests/quicktestbrowser/BrowserWindow.qml
+++ b/tests/quicktestbrowser/BrowserWindow.qml
@@ -505,6 +505,18 @@ ApplicationWindow {
download.accept()
}
+ MessageDialog {
+ id: notificationDialog
+ width: 200
+ standardButtons: StandardButton.Ok
+ }
+
+ function onPresentNotification(notification) {
+ notificationDialog.title = notification.title
+ notificationDialog.text = notification.origin.toString() + '\n' + notification.message
+ notificationDialog.open()
+ }
+
ZoomController {
id: zoomController
y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
diff --git a/tests/quicktestbrowser/FeaturePermissionBar.qml b/tests/quicktestbrowser/FeaturePermissionBar.qml
index 9c0b25966..500d13206 100644
--- a/tests/quicktestbrowser/FeaturePermissionBar.qml
+++ b/tests/quicktestbrowser/FeaturePermissionBar.qml
@@ -40,10 +40,24 @@ Rectangle {
visible: false
height: acceptButton.height + 4
- onRequestedFeatureChanged: {
- message.text = securityOrigin + " wants to access " + message.textForFeature(requestedFeature);
+
+ function textForFeature(feature) {
+ switch (feature) {
+ case WebEngineView.Geolocation: return 'Allow %1 to access your location information?'
+ case WebEngineView.MediaAudioCapture: return 'Allow %1 to access your microphone?'
+ case WebEngineView.MediaVideoCapture: return 'Allow %1 to access your webcam?'
+ case WebEngineView.MediaAudioVideoCapture: return 'Allow %1 to access your microphone and webcam?'
+ case WebEngineView.DesktopVideoCapture: return 'Allow %1 to capture video of your desktop?'
+ case WebEngineView.DesktopAudioVideoCapture: return 'Allow %1 to capture audio and video of your desktop?'
+ case WebEngineView.Notifications: return 'Allow %1 to show notification on your desktop?'
+ default: break
+ }
+ return 'Grant permission for %1 to unknown or unsupported feature [' + feature + ']?'
}
+ onRequestedFeatureChanged: {
+ message.text = textForFeature(requestedFeature).arg(securityOrigin);
+ }
RowLayout {
anchors {
@@ -54,17 +68,6 @@ Rectangle {
Label {
id: message
Layout.fillWidth: true
-
- function textForFeature(feature) {
- if (feature === WebEngineView.MediaAudioCapture)
- return "your microphone"
- if (feature === WebEngineView.MediaVideoCapture)
- return "your camera"
- if (feature === WebEngineView.MediaAudioVideoCapture)
- return "your camera and microphone"
- if (feature === WebEngineView.Geolocation)
- return "your position"
- }
}
Button {