Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package qt6-webview for openSUSE:Factory checked in at 2026-08-21 16:52:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qt6-webview (Old) and /work/SRC/openSUSE:Factory/.qt6-webview.new.1258 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qt6-webview" Fri Aug 21 16:52:10 2026 rev:31 rq:1372273 version:6.11.2 Changes: -------- --- /work/SRC/openSUSE:Factory/qt6-webview/qt6-webview.changes 2026-05-28 17:26:42.283136697 +0200 +++ /work/SRC/openSUSE:Factory/.qt6-webview.new.1258/qt6-webview.changes 2026-08-21 16:52:55.544127067 +0200 @@ -1,0 +2,6 @@ +Tue Aug 18 11:49:50 UTC 2026 - Christophe Marin <[email protected]> + +- Update to 6.11.2 + https://www.qt.io/blog/qt-6.11.2-released + +------------------------------------------------------------------- Old: ---- qtwebview-everywhere-src-6.11.1.tar.xz New: ---- qtwebview-everywhere-src-6.11.2.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qt6-webview.spec ++++++ --- /var/tmp/diff_new_pack.ZHXI43/_old 2026-08-21 16:52:56.643166161 +0200 +++ /var/tmp/diff_new_pack.ZHXI43/_new 2026-08-21 16:52:56.649166374 +0200 @@ -16,7 +16,7 @@ # -%define real_version 6.11.1 +%define real_version 6.11.2 %define short_version 6.11 %define tar_name qtwebview-everywhere-src %define tar_suffix %{nil} @@ -27,7 +27,7 @@ %endif # Name: qt6-webview%{?pkg_suffix} -Version: 6.11.1 +Version: 6.11.2 Release: 0 Summary: Qt 6 WebView library License: GPL-2.0-only OR GPL-3.0-or-later OR LGPL-3.0-only ++++++ qtwebview-everywhere-src-6.11.1.tar.xz -> qtwebview-everywhere-src-6.11.2.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/.cmake.conf new/qtwebview-everywhere-src-6.11.2/.cmake.conf --- old/qtwebview-everywhere-src-6.11.1/.cmake.conf 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/.cmake.conf 2026-08-12 21:46:00.000000000 +0200 @@ -1,5 +1,7 @@ -set(QT_REPO_MODULE_VERSION "6.11.1") +set(QT_REPO_MODULE_VERSION "6.11.2") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_ENABLE_STRICT_MODE_UP_TO=QT_VERSION_CHECK(6,11,0)" + # not yet in strict mode: + "QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD=1" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/.tag new/qtwebview-everywhere-src-6.11.2/.tag --- old/qtwebview-everywhere-src-6.11.1/.tag 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/.tag 2026-08-12 21:46:00.000000000 +0200 @@ -1 +1 @@ -acf7547689bd4b14c1401063b4418cac1221c7e5 +5e6561080be8de2099381fa3a729682d1b652340 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/REUSE.toml new/qtwebview-everywhere-src-6.11.2/REUSE.toml --- old/qtwebview-everywhere-src-6.11.1/REUSE.toml 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/REUSE.toml 2026-08-12 21:46:00.000000000 +0200 @@ -1,9 +1,7 @@ version = 1 [[annotations]] -path = ["tests/auto/qml/qquickwebview/dummy.qml", - "tests/auto/qml/qquickwebview/html/*.html", - "tests/auto/qml/qquickwebview/html/resources/simple_image.png"] +path = ["tests/auto/qml/qquickwebview/html/*.html"] precedence = "closest" SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/dependencies.yaml new/qtwebview-everywhere-src-6.11.2/dependencies.yaml --- old/qtwebview-everywhere-src-6.11.1/dependencies.yaml 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/dependencies.yaml 2026-08-12 21:46:00.000000000 +0200 @@ -1,7 +1,7 @@ dependencies: ../qtdeclarative: - ref: a02bed441965ee1f18f856352c7d5ee5ba35d795 + ref: 4e3399c26ec57246c08de019cfcbda8d23604cfa required: true ../qtwebengine: - ref: eb0793cc4b76e93cf669f586fd68c76019f40ec9 + ref: a33fa2a897e5ee58e385b3f88dc247d99fca56db required: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java new/qtwebview-everywhere-src-6.11.2/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java --- old/qtwebview-everywhere-src-6.11.1/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/src/jar/src/org/qtproject/qt/android/view/QtAndroidWebViewController.java 2026-08-12 21:46:00.000000000 +0200 @@ -12,6 +12,9 @@ import android.webkit.WebViewClient; import android.webkit.WebChromeClient; import android.webkit.CookieManager; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebResourceError; import java.lang.Runnable; import android.app.Activity; import android.content.Intent; @@ -22,6 +25,7 @@ import android.webkit.WebSettings.PluginState; import android.graphics.Bitmap; import java.util.concurrent.Semaphore; +import java.util.OptionalInt; import java.lang.reflect.Method; import android.os.Build; import java.util.concurrent.TimeUnit; @@ -33,6 +37,8 @@ private final long m_id; private boolean m_hasLocationPermission; private WebView m_webView = null; + private StringBuffer m_errorString = new StringBuffer(); + private OptionalInt m_errorCode; private static final String TAG = "QtAndroidWebViewController"; private final int INIT_STATE = 0; private final int STARTED_STATE = 1; @@ -80,15 +86,15 @@ QtAndroidWebViewClient() { super(); } @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { // handle http: and http:, etc., as usual - if (URLUtil.isValidUrl(url)) + if (URLUtil.isValidUrl(request.getUrl().toString())) return false; // try to handle geo:, tel:, mailto: and other schemes try { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); view.getContext().startActivity(intent); return true; } catch (Exception e) { @@ -109,11 +115,13 @@ { super.onPageFinished(view, url); m_frameCount = 0; - if (m_loadingState == INIT_STATE) { - // we got an error do not call pageFinished - m_loadingState = FINISHED_STATE; + m_loadingState = FINISHED_STATE; + if (m_errorString.length() != 0 && m_errorCode.isPresent()) { + // We got an error, call onReceivedError() instead of onPageFinished() + c_onReceivedError(m_id, m_errorCode.getAsInt(), m_errorString.toString(), url); + m_errorString.setLength(0); + m_errorCode = OptionalInt.empty(); } else { - m_loadingState = FINISHED_STATE; c_onPageFinished(m_id, url); } } @@ -130,13 +138,31 @@ @Override public void onReceivedError(WebView view, - int errorCode, - String description, - String url) + WebResourceRequest request, + WebResourceError error) { - super.onReceivedError(view, errorCode, description, url); - resetLoadingState(INIT_STATE); - c_onReceivedError(m_id, errorCode, description, url); + if (!request.isForMainFrame()) + return; + m_errorString.setLength(0); + m_errorString.append(error.getDescription()); + m_errorCode = OptionalInt.of(error.getErrorCode()); + super.onReceivedError(view, request, error); + } + + @Override + public void onReceivedHttpError(WebView view, + WebResourceRequest request, + WebResourceResponse errorResponse) + { + // We receive this signal first, before loading the actual 4XX error page has begun. + // However, we want to make sure the user is notified of a failed load when the 404 page is fully loaded. + // So, cache the response and URL, and handle the rest in onPageFinished() + if (!request.isForMainFrame()) + return; + m_errorString.setLength(0); + m_errorString.append(errorResponse.getReasonPhrase()); + m_errorCode = OptionalInt.of(errorResponse.getStatusCode()); + super.onReceivedHttpError(view, request, errorResponse); } } @@ -186,7 +212,6 @@ // The local storage options are not user changeable in QtWebView and disabled by default on Android. // In QtWebEngine and on iOS local storage is enabled by default, so we follow that. - webSettings.setDatabaseEnabled(true); webSettings.setDomStorageEnabled(true); if (Build.VERSION.SDK_INT > 10) { @@ -210,7 +235,6 @@ try { m_webSettingsSetDisplayZoomControls.invoke(webSettings, false); } catch (Exception e) { e.printStackTrace(); } } webSettings.setBuiltInZoomControls(true); - webSettings.setPluginState(PluginState.ON); m_webView.setWebViewClient((WebViewClient)new QtAndroidWebViewClient()); m_webView.setWebChromeClient((WebChromeClient)new QtAndroidWebChromeClient()); sem.release(); @@ -231,7 +255,6 @@ @Override public void run() { WebSettings webSettings = m_webView.getSettings(); - webSettings.setDatabaseEnabled(enabled); webSettings.setDomStorageEnabled(enabled); } }); @@ -245,7 +268,7 @@ @Override public void run() { WebSettings webSettings = m_webView.getSettings(); - enabled[0] = webSettings.getDatabaseEnabled() && webSettings.getDomStorageEnabled(); + enabled[0] = webSettings.getDomStorageEnabled(); sem.release(); } }); @@ -655,7 +678,6 @@ private static boolean hasValidCookie(final String url, final String cookieString) { CookieManager cookieManager = CookieManager.getInstance(); - cookieManager.removeExpiredCookie(); boolean cookieFound = false; final String domainCookie = cookieManager.getCookie(url); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/src/plugins/darwin/qdarwinwebview.mm new/qtwebview-everywhere-src-6.11.2/src/plugins/darwin/qdarwinwebview.mm --- old/qtwebview-everywhere-src-6.11.1/src/plugins/darwin/qdarwinwebview.mm 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/src/plugins/darwin/qdarwinwebview.mm 2026-08-12 21:46:00.000000000 +0200 @@ -350,7 +350,16 @@ if (url.isLocalFile()) { // NOTE: Check if the file exists before attempting to load it, we follow the same // asynchronous pattern as expected to not break the tests (Started + Failed). - if (!QFile::exists(url.toLocalFile())) { + bool exists = QFile::exists(url.toLocalFile()); + + // We need to pass local files via loadFileURL and the read access should cover + // the directory that the file is in, to facilitate loading referenced images etc + if (exists && m_settings->allowFileAccess()) { + if (m_settings->localContentCanAccessFileUrls()) + [wkWebView loadFileURL:url.toNSURL() allowingReadAccessToURL:QUrl(url.toString(QUrl::RemoveFilename)).toNSURL()]; + else + [wkWebView loadRequest:[NSURLRequest requestWithURL:url.toNSURL()]]; + } else { QMetaObject::invokeMethod( q_ptr, &QWebView::loadingChanged, Qt::QueuedConnection, QWebViewFactory::LoadingInfo::create(url, QWebViewLoadingInfo::LoadStatus::Started, @@ -358,17 +367,11 @@ QMetaObject::invokeMethod( q_ptr, &QWebView::loadingChanged, Qt::QueuedConnection, QWebViewFactory::LoadingInfo::create(url, QWebViewLoadingInfo::LoadStatus::Failed, - QStringLiteral("File does not exist"))); + exists + ? QStringLiteral("Permission denied") + : QStringLiteral("File does not exist"))); return; } - // We need to pass local files via loadFileURL and the read access should cover - // the directory that the file is in, to facilitate loading referenced images etc - if (m_settings->allowFileAccess()) { - if (m_settings->localContentCanAccessFileUrls()) - [wkWebView loadFileURL:url.toNSURL() allowingReadAccessToURL:QUrl(url.toString(QUrl::RemoveFilename)).toNSURL()]; - else - [wkWebView loadRequest:[NSURLRequest requestWithURL:url.toNSURL()]]; - } } else { [wkWebView loadRequest:[NSURLRequest requestWithURL:url.toNSURL()]]; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/src/webview/qwebviewsettings.cpp new/qtwebview-everywhere-src-6.11.2/src/webview/qwebviewsettings.cpp --- old/qtwebview-everywhere-src-6.11.1/src/webview/qwebviewsettings.cpp 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/src/webview/qwebviewsettings.cpp 2026-08-12 21:46:00.000000000 +0200 @@ -16,9 +16,9 @@ \value JavaScriptEnabled Enables the running of JavaScript programs. \value AllowFileAccess - Allows locally loaded documents to access other local URLs. - \value LocalContentCanAccessFileUrls Enables the WebView to load file URLs. + \value LocalContentCanAccessFileUrls + Allows locally loaded documents to access other local URLs. */ /*! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/CMakeLists.txt new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/CMakeLists.txt --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/CMakeLists.txt 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/CMakeLists.txt 2026-08-12 21:46:00.000000000 +0200 @@ -5,23 +5,36 @@ ## tst_qquickwebview Binary: ##################################################################### +find_package(Qt6 ${PROJECT_VERSION} CONFIG + REQUIRED COMPONENTS Qml QuickTest) + +include(../../util/util.cmake) + qt_internal_add_test(tst_qquickwebview + QMLTEST SOURCES - util.h testwindow.h + qmltestutil.cpp + qmltestutil.h tst_qquickwebview.cpp LIBRARIES - Qt::Quick + Qt::WebView + Qt::WebViewQuick Qt::WebViewPrivate - Qt::WebViewQuickPrivate + Qt::Qml + WebViewTest::Util +) + +qt_add_qml_module(tst_qquickwebview + URI QuickWebViewTest + VERSION 1.0 + QML_FILES + tst_qquickwebview.qml + WebViewTestCase.qml ) set(testdata_resource_files "html/basic_page.html" "html/basic_page2.html" - "html/direct-image-compositing.html" - "html/inputmethod.html" - "html/scroll.html" - "html/cookies.html" "html/javascript.html" ) @@ -33,16 +46,3 @@ FILES ${testdata_resource_files} ) -set(testdata1_resource_files - "html/resources/simple_image.png" -) - -qt_internal_add_resource(tst_qquickwebview "testdata1" - PREFIX - "/resources" - BASE - "html" - FILES - ${testdata1_resource_files} -) - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/WebViewTestCase.qml new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/WebViewTestCase.qml --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/WebViewTestCase.qml 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/WebViewTestCase.qml 2026-08-12 21:46:00.000000000 +0200 @@ -0,0 +1,106 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtWebView +import QtTest + +TestCase { + id: testCase + when: windowShown + + // Dynamically load a new WebView for every test case + property var webView: undefined + property var webViewComponent: webViewComponent + + // WebView Component: + Component { + id: webViewComponent + + WebView { + id: webView + settings.allowFileAccess: true + property bool completed: false + property var loadingStatuses: [] + property var urls: [] + + // Signal spies + property SignalSpy loadProgressSpy: SignalSpy { + target: webView + signalName: "loadProgressChanged" + } + + property SignalSpy titleSpy: SignalSpy { + target: webView + signalName: "titleChanged" + } + + property SignalSpy cookieAddedSpy: SignalSpy { + target: webView + signalName: "cookieAdded" + } + + property SignalSpy cookieRemovedSpy: SignalSpy { + target: webView + signalName: "cookieRemoved" + } + + // Signal handlers + onLoadingChanged: (loadRequest) => { + // We can't use a signal spy because the signal passes a stack-allocated object by reference. + // Instead, we cache the loading status and URL to separate arrays. TODO fix this + loadingStatuses.push(loadRequest.status); + urls.push(loadRequest.url); + } + + // Helpers + function expectedUrl(expectedUrl) { + return webView.url == expectedUrl + && urls[urls.length - 1] == expectedUrl; + } + + TestResult { id: testResult } + + function _waitFor(predicate, timeout) { + if (timeout === undefined) + timeout = 30000; + var i = 0; + while (i < timeout && !predicate()) { + testResult.wait(50); + i += 50; + } + return predicate(); + } + + function waitForLoad(loadStatus, timeout) { + var numArgs = loadingStatuses.length; + var success = _waitFor(function() { + if (loadingStatuses.length) + return loadingStatuses.length >= numArgs + 2 + && loadingStatuses[loadingStatuses.length - 1] == loadStatus; + }, timeout); + return success; + } + + function pluginIs(pluginName) { + return WebViewTestUtils.loadedPluginHasKey(pluginName); + } + } + } + + // Test init/cleanup: + function initTestCase() { + let completed = false; + tryVerify(function () { return webViewComponent.status == Component.Ready; }); + } + + function init() { + webView = webViewComponent.createObject(root); + } + + function cleanup() { + webView.deleteAllCookies(); + webView.destroy(); + webView = undefined; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/dummy.qml new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/dummy.qml --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/dummy.qml 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/dummy.qml 1970-01-01 01:00:00.000000000 +0100 @@ -1,8 +0,0 @@ -import QtQuick 2.0 -import QtWebView 1.1 - - WebView { - width: 100 - height: 62 -} - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/cookies.html new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/cookies.html --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/cookies.html 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/cookies.html 1970-01-01 01:00:00.000000000 +0100 @@ -1,9 +0,0 @@ -<html> - <head> - <script> - document.cookie = "TestCookie1=testValue1"; - document.cookie = "TestCookie2=testValue2"; -</script> - </head> - </body> -</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/direct-image-compositing.html new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/direct-image-compositing.html --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/direct-image-compositing.html 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/direct-image-compositing.html 1970-01-01 01:00:00.000000000 +0100 @@ -1,66 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> - -<html lang="en"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title>Testing direct image layer optimization</title> - <style type="text/css" media="screen"> - img { - float: left; - width: 150px; - height: 150px; - } - img { - -webkit-transform: rotate3d(0, 0, 1, 0); - } - .test { - float: left; - height: 200px; - width: 260px; - } - </style> -</head> -<body> - - <h1>Image optimization in layers</h1> - - <p> - This test exercises direct compositing of images with hardware acceleration. The visual results - using ACCELERATED_COMPOSITING and regular TOT should be identical. Running this test manually with - the correct debug options will show which elements are directly composited. See - <a href="https://bugs.webkit.org/show_bug.cgi?id=23361">https://bugs.webkit.org/show_bug.cgi?id=23361</a> - </p> - - <div class="test"> - <img src="resources/simple_image.png"> - Basic image - no style - can be directly composited - </div> - - <div class="test"> - <img src="resources/simple_image.png" style="border: 5px solid blue;"> - 5px blue border - can NOT be directly composited - </div> - - <div class="test"> - <img src="resources/simple_image.png" style="margin: 5px 5px;"> - margin - can NOT be directly composited - </div> - - <div class="test"> - <img src="resources/simple_image.png" style="background-color: grey;"> - solid background - can be directly composited - </div> - - <div class="test"> - <img src="resources/simple_image.png" style="background: orange url(resources/simple_image.png) -50px -50px;"> - background image - can NOT be directly composited - </div> - - <div class="test"> - <img src="resources/simple_image.png" style="-webkit-transform: rotate3d(0, 0, 1, 10deg);"> - rotated but otherwise no style - can be directly composited - </div> - -</body> -</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/inputmethod.html new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/inputmethod.html --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/inputmethod.html 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/inputmethod.html 1970-01-01 01:00:00.000000000 +0100 @@ -1,11 +0,0 @@ -<html> -<head> -<title>Basic Page For Input Method Testing</title> -</head> -<body> -<h1>Basic page</h1> -<input id="inputField" /> -<input id="emailInputField" type="email" /> -<div id="editableDiv" contenteditable></div> -</body> -</html> Binary files old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/resources/simple_image.png and new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/resources/simple_image.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/scroll.html new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/scroll.html --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/html/scroll.html 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/html/scroll.html 1970-01-01 01:00:00.000000000 +0100 @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> -<meta name="viewport" content="width=200, height=500, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1"/> -<script type="text/javascript"> -function pageScroll() { - window.scrollBy(0,50); // horizontal and vertical scroll increments -} -</script> -<style> - body { - background-color: blue; - margin: 50 50 50 50; - } - div { - font-color: white; - background-color: green; - width: 300px; - height: 1000px; - } -</style> - -<head> -<title>Scroll test </title> -</head> -<body onload="pageScroll()"> -<div> -</div> -</body> -</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/qmltestutil.cpp new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/qmltestutil.cpp --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/qmltestutil.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/qmltestutil.cpp 2026-08-12 21:46:00.000000000 +0200 @@ -0,0 +1,17 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qmltestutil.h" + +#include <testutil.h> +#include <QtWebView/private/qwebviewfactory_p.h> + +bool QQuickWebViewTestUtilsSingleton::loadedPluginHasKey(const QString &key) const +{ + return QWebViewFactory::loadedPluginHasKey(key); +} + +QUrl QQuickWebViewTestUtilsSingleton::makeTestFileUrl(const QString &testFile) const +{ + return ::makeTestFileUrl(testFile); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/qmltestutil.h new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/qmltestutil.h --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/qmltestutil.h 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/qmltestutil.h 2026-08-12 21:46:00.000000000 +0200 @@ -0,0 +1,26 @@ +// Copyright (C) 2026 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMLTESTUTIL_H +#define QMLTESTUTIL_H + +#include <QtCore/qobject.h> +#include <QtCore/qstring.h> +#include <QtCore/qtemporaryfile.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickWebViewTestUtilsSingleton : public QObject { + Q_OBJECT + QML_SINGLETON + QML_NAMED_ELEMENT(WebViewTestUtils) + +public: + Q_INVOKABLE bool loadedPluginHasKey(const QString &key) const; + Q_INVOKABLE QUrl makeTestFileUrl(const QString &testFile) const; +}; + +QT_END_NAMESPACE + +#endif /* QMLTESTUTIL_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/testwindow.h new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/testwindow.h --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/testwindow.h 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/testwindow.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,43 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#ifndef TESTWINDOW_H -#define TESTWINDOW_H - -#if 0 -#pragma qt_no_master_include -#endif - -#include <QResizeEvent> -#include <QScopedPointer> -#include <QtQuick/qquickitem.h> -#include <QtQuick/qquickview.h> - -// TestWindow: Utility class to ignore QQuickView details. -class TestWindow : public QQuickView { -public: - inline TestWindow(QQuickItem *webView); - QScopedPointer<QQuickItem> webView; - -protected: - inline void resizeEvent(QResizeEvent*) override; -}; - -inline TestWindow::TestWindow(QQuickItem *webView) - : webView(webView) -{ - Q_ASSERT(webView); - webView->setParentItem(contentItem()); - resize(300, 400); -} - -inline void TestWindow::resizeEvent(QResizeEvent *event) -{ - QQuickView::resizeEvent(event); - webView->setX(0); - webView->setY(0); - webView->setWidth(event->size().width()); - webView->setHeight(event->size().height()); -} - -#endif /* TESTWINDOW_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp 2026-08-12 21:46:00.000000000 +0200 @@ -1,440 +1,6 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -#include "testwindow.h" -#include "util.h" +#include <QtQuickTest/quicktest.h> -#include <QScopedPointer> -#include <QtQml/QQmlEngine> -#include <QtTest/QtTest> -#include <QtWebViewQuick/private/qquickwebview_p.h> -#include <QtCore/qfile.h> -#include <QtCore/qstandardpaths.h> -#include <QtWebView/qtwebviewfunctions.h> -#include <QtWebView/private/qwebviewfactory_p.h> -#include <QtWebViewQuick/private/qquickwebviewsettings_p.h> - -QUrl getTestFilePath(const QString &testFile) -{ - const QString tempTestFile = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + testFile; - const bool exists = QFile::exists(tempTestFile); - if (exists) - return QUrl::fromLocalFile(tempTestFile); - - QFile tf(QString(":/") + testFile); - const bool copied = tf.copy(tempTestFile); - - return QUrl::fromLocalFile(copied ? tempTestFile : testFile); -} - -class tst_QQuickWebView : public QObject { - Q_OBJECT -public: - tst_QQuickWebView(); - -private Q_SLOTS: - void initTestCase(); - - void init(); - void cleanup(); - - void navigationStatusAtStartup(); - void stopEnabledAfterLoadStarted(); - void baseUrl(); - void loadEmptyUrl(); - void loadEmptyPageViewVisible(); - void loadEmptyPageViewHidden(); - void loadNonexistentFileUrl(); - void backAndForward(); - void reload(); - void stop(); - void loadProgress(); - - void show(); - void showWebView(); - void removeFromCanvas(); - void multipleWebViewWindows(); - void multipleWebViews(); - void titleUpdate(); - void changeUserAgent(); - void setAndDeleteCookies(); - - void settings_JS_data(); - void settings_JS(); - -private: - inline QQuickWebView *newWebView(); - inline QQuickWebView *webView() const; - void runJavaScript(const QString &script); - QScopedPointer<TestWindow> m_window; - QScopedPointer<QQmlComponent> m_component; - QQmlEngine *engine = nullptr; -}; - -tst_QQuickWebView::tst_QQuickWebView() -{ - engine = new QQmlEngine(this); - m_component.reset(new QQmlComponent(engine, this)); - m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n" - "import QtWebView 1.1\n" - "WebView {}") - , QUrl()); -} - -QQuickWebView *tst_QQuickWebView::newWebView() -{ - QObject *viewInstance = m_component->create(); - QQuickWebView *webView = qobject_cast<QQuickWebView*>(viewInstance); - webView->settings()->setAllowFileAccess(true); - webView->settings()->setLocalContentCanAccessFileUrls(true); - return webView; -} - -void tst_QQuickWebView::initTestCase() -{ - if (!qEnvironmentVariableIsEmpty("QEMU_LD_PREFIX")) - QSKIP("This test is unstable on QEMU, so it will be skipped."); -} - -void tst_QQuickWebView::init() -{ - QtWebView::initialize(); - m_window.reset(new TestWindow(newWebView())); -} - -void tst_QQuickWebView::cleanup() -{ - m_window.reset(); -} - -inline QQuickWebView *tst_QQuickWebView::webView() const -{ - return static_cast<QQuickWebView*>(m_window->webView.data()); -} - -void tst_QQuickWebView::runJavaScript(const QString &script) -{ - webView()->runJavaScript(script); -} - -void tst_QQuickWebView::navigationStatusAtStartup() -{ - QCOMPARE(webView()->canGoBack(), false); - - QCOMPARE(webView()->canGoForward(), false); - - QCOMPARE(webView()->isLoading(), false); -} - -void tst_QQuickWebView::stopEnabledAfterLoadStarted() -{ - QCOMPARE(webView()->isLoading(), false); - - LoadStartedCatcher loadStartedCatcher(webView()); - LoadSpy loadSpy(webView()); - webView()->setUrl(getTestFilePath("basic_page.html")); - - waitForSignal(&loadStartedCatcher, SIGNAL(finished())); - waitForSignal(&loadSpy, SIGNAL(loadSucceeded())); -} - -void tst_QQuickWebView::baseUrl() -{ - // Test the url is in a well defined state when instanciating the view, but before loading anything. - QVERIFY(webView()->url().isEmpty()); -} - -void tst_QQuickWebView::loadEmptyUrl() -{ - webView()->setUrl(QUrl()); - webView()->setUrl(QUrl(QLatin1String(""))); -} - -void tst_QQuickWebView::loadEmptyPageViewVisible() -{ - m_window->show(); - loadEmptyPageViewHidden(); -} - -void tst_QQuickWebView::loadEmptyPageViewHidden() -{ - QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QQuickWebViewLoadRequest*))); - - webView()->setUrl(getTestFilePath("basic_page.html")); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(loadSpy.size(), 2); -} - -void tst_QQuickWebView::loadNonexistentFileUrl() -{ - QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QQuickWebViewLoadRequest*))); - - webView()->setUrl(getTestFilePath("file_that_does_not_exist.html")); - QVERIFY(waitForLoadFailed(webView())); - - QCOMPARE(loadSpy.size(), 2); -} - -void tst_QQuickWebView::backAndForward() -{ - const QUrl basicPage = getTestFilePath("basic_page.html"); - const QUrl basicPage2 = getTestFilePath("basic_page2.html"); - webView()->setUrl(basicPage); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), basicPage); - - webView()->setUrl(basicPage2); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), basicPage2); - - webView()->goBack(); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), basicPage); - - webView()->goForward(); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), basicPage2); -} - -void tst_QQuickWebView::reload() -{ - webView()->setUrl(getTestFilePath("basic_page.html")); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), getTestFilePath("basic_page.html")); - - webView()->reload(); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), getTestFilePath("basic_page.html")); -} - -void tst_QQuickWebView::stop() -{ - webView()->setUrl(QUrl(getTestFilePath("basic_page.html"))); - QVERIFY(waitForLoadSucceeded(webView())); - - QCOMPARE(webView()->url(), getTestFilePath("basic_page.html")); - - webView()->stop(); -} - -void tst_QQuickWebView::loadProgress() -{ - QCOMPARE(webView()->loadProgress(), 0); - - webView()->setUrl(getTestFilePath("basic_page.html")); - QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged())); - QVERIFY(waitForLoadSucceeded(webView())); - - QVERIFY(loadProgressChangedSpy.size() >= 1); - - QCOMPARE(webView()->loadProgress(), 100); -} - -void tst_QQuickWebView::show() -{ - // This should not crash. - m_window->show(); - QTest::qWait(200); - m_window->hide(); -} - -void tst_QQuickWebView::showWebView() -{ - webView()->setUrl(getTestFilePath("direct-image-compositing.html")); - QVERIFY(waitForLoadSucceeded(webView())); - m_window->show(); - // This should not crash. - webView()->setVisible(true); - QTest::qWait(200); - webView()->setVisible(false); - QTest::qWait(200); -} - -void tst_QQuickWebView::removeFromCanvas() -{ - showWebView(); - - // This should not crash. - QQuickItem *parent = webView()->parentItem(); - QQuickItem noCanvasItem; - webView()->setParentItem(&noCanvasItem); - QTest::qWait(200); - webView()->setParentItem(parent); - webView()->setVisible(true); - QTest::qWait(200); -} - -void tst_QQuickWebView::multipleWebViewWindows() -{ - showWebView(); - - // This should not crash. - QQuickWebView *webView1 = newWebView(); - QScopedPointer<TestWindow> window1(new TestWindow(webView1)); - QQuickWebView *webView2 = newWebView(); - QScopedPointer<TestWindow> window2(new TestWindow(webView2)); - - webView1->setUrl(getTestFilePath("scroll.html")); - QVERIFY(waitForLoadSucceeded(webView1)); - window1->show(); - webView1->setVisible(true); - - webView2->setUrl(getTestFilePath("basic_page.html")); - QVERIFY(waitForLoadSucceeded(webView2)); - window2->show(); - webView2->setVisible(true); - QTest::qWait(200); -} - -void tst_QQuickWebView::multipleWebViews() -{ - showWebView(); - - // This should not crash. - QScopedPointer<QQuickWebView> webView1(newWebView()); - webView1->setParentItem(m_window->contentItem()); - QScopedPointer<QQuickWebView> webView2(newWebView()); - webView2->setParentItem(m_window->contentItem()); - - webView1->setSize(QSizeF(300, 400)); - webView1->setUrl(getTestFilePath("scroll.html")); - QVERIFY(waitForLoadSucceeded(webView1.data())); - webView1->setVisible(true); - - webView2->setSize(QSizeF(300, 400)); - webView2->setUrl(getTestFilePath("basic_page.html")); - QVERIFY(waitForLoadSucceeded(webView2.data())); - webView2->setVisible(true); - QTest::qWait(200); -} - -void tst_QQuickWebView::titleUpdate() -{ - QSignalSpy titleSpy(webView(), SIGNAL(titleChanged())); - - // Load page with no title - webView()->setUrl(getTestFilePath("basic_page2.html")); - QVERIFY(waitForLoadSucceeded(webView())); - if (QWebViewFactory::loadedPluginHasKey("webengine") - || QWebViewFactory::loadedPluginHasKey("android_view") - || QWebViewFactory::loadedPluginHasKey("webview2")) { - // on some platforms if the page has no <title> element, then the URL is used instead - QCOMPARE(titleSpy.size(), 1); - } else { - QCOMPARE(titleSpy.size(), 0); - } - titleSpy.clear(); - - // No titleChanged signal for failed load - webView()->setUrl(getTestFilePath("file_that_does_not_exist.html")); - QVERIFY(waitForLoadFailed(webView())); - if (QWebViewFactory::loadedPluginHasKey("android_view") - || QWebViewFactory::loadedPluginHasKey("webview2")) { - QTRY_COMPARE(titleSpy.size(), 1); - } else { - QCOMPARE(titleSpy.size(), 0); - } -} - -void tst_QQuickWebView::changeUserAgent() -{ - QQmlComponent userAgentWebView(engine, this); - userAgentWebView.setData(QByteArrayLiteral("import QtQuick 2.0\n" - "import QtWebView 1.14\n" - "WebView {\n" - "httpUserAgent: \"dummy\"\n" - "}"), - QUrl()); - QObject *viewInstance = userAgentWebView.create(); - QQuickWebView *webView = qobject_cast<QQuickWebView *>(viewInstance); - QCOMPARE(webView->httpUserAgent(), "dummy"); -} - -void tst_QQuickWebView::setAndDeleteCookies() -{ - QSignalSpy cookieAddedSpy(webView(), SIGNAL(cookieAdded(QString,QString))); - QSignalSpy cookieRemovedSpy(webView(), SIGNAL(cookieRemoved(QString,QString))); - - if (QWebViewFactory::loadedPluginHasKey("webengine")) { - webView()->setUrl(QUrl("qrc:///cookies.html")); - QVERIFY(waitForLoadSucceeded(webView())); - - QTRY_COMPARE(cookieAddedSpy.size(), 2); - - webView()->deleteAllCookies(); - QTRY_COMPARE(cookieRemovedSpy.size(), 2); - - cookieAddedSpy.clear(); - cookieRemovedSpy.clear(); - } - - Cookie::List cookies { {".example.com", "TestCookie", "testValue"}, - {".example2.com", "TestCookie2", "testValue2"}, - {".example3.com", "TestCookie3", "testValue3"} }; - - for (const auto &cookie : cookies) - webView()->setCookie(cookie.domain, cookie.name, cookie.value); - - QTRY_COMPARE(cookieAddedSpy.size(), cookies.size()); - QVERIFY(Cookie::testSignalValues(cookies, cookieAddedSpy)); - - auto removedCookie = cookies.takeLast(); - - webView()->deleteCookie(removedCookie.domain, removedCookie.name); - QTRY_COMPARE(cookieRemovedSpy.size(), 1); - { - const auto &first = cookieRemovedSpy.first(); - Cookie::SigArg sigArg{ first.at(0).toString(), first.at(1).toString() }; - QCOMPARE(removedCookie, sigArg); - } - - // deleting a cookie using a name that has not been set - webView()->deleteCookie(".example.com", "NewCookieName"); - QTRY_COMPARE(cookieRemovedSpy.size(), 1); - - // deleting a cookie using a domain that has not been set - webView()->deleteCookie(".new.domain.com", "TestCookie2"); - QTRY_COMPARE(cookieRemovedSpy.size(), 1); - - webView()->deleteAllCookies(); - if (QWebViewFactory::loadedPluginHasKey("android_view")) - QEXPECT_FAIL("", "Notification for deleteAllCookies() is not implemented on Android, yet!", Continue); - QTRY_COMPARE(cookieRemovedSpy.size(), 3); -} - -void tst_QQuickWebView::settings_JS_data() -{ - QTest::addColumn<bool>("jsEnabled"); - QTest::addColumn<QUrl>("testUrl"); - QTest::addColumn<QString>("expectedTitle"); - - // Title should be updated from "JavaScript" to "JavaScript Test" - QTest::newRow("Test JS enabled") << true << getTestFilePath("javascript.html") << "JavaScript Test"; - // Title should _not_ be updated from "JavaScript" to "JavaScript Test" - QTest::newRow("Test JS disabled") << false << getTestFilePath("javascript.html") << "JavaScript"; -} - -void tst_QQuickWebView::settings_JS() -{ - - QFETCH(bool, jsEnabled); - QFETCH(QUrl, testUrl); - QFETCH(QString, expectedTitle); - - bool wasJsEnabled = webView()->settings()->javaScriptEnabled(); - webView()->settings()->setJavaScriptEnabled(jsEnabled); - webView()->setUrl(testUrl); - QVERIFY(waitForLoadSucceeded(webView())); - QTRY_COMPARE(webView()->title(), expectedTitle); - webView()->settings()->setJavaScriptEnabled(wasJsEnabled); -} - -QTEST_MAIN(tst_QQuickWebView) -#include "tst_qquickwebview.moc" +QUICK_TEST_MAIN(tst_qquickwebview) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/tst_qquickwebview.qml new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/tst_qquickwebview.qml --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/tst_qquickwebview.qml 1970-01-01 01:00:00.000000000 +0100 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/tst_qquickwebview.qml 2026-08-12 21:46:00.000000000 +0200 @@ -0,0 +1,230 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtWebView +import QtTest +import QuickWebViewTest + +RowLayout { + id: root + + WebViewTestCase { + name: "HiddenNavigation" + + function test_loadEmptyPageViewHidden() { + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + } + } + + WebViewTestCase { + name: "Navigation" + when: windowShown + + function test_startupState() { + compare(webView.canGoBack, false); + compare(webView.canGoForward, false); + compare(webView.loading, false); + compare(webView.url, ""); + } + + function test_loadNonexistentFileUrl() { + webView.url = Qt.resolvedUrl("file_that_does_not_exist.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadFailedStatus)); + } + + function test_backAndForward() { + let page1 = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + let page2 = WebViewTestUtils.makeTestFileUrl("basic_page2.html"); + + webView.url = page1; + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(webView.expectedUrl(page1)); + + verify(!webView.canGoBack); + verify(!webView.canGoForward); + + webView.url = page2; + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(webView.expectedUrl(page2)); + + verify(webView.canGoBack); + verify(!webView.canGoForward); + + webView.goBack(); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(!webView.canGoBack); + verify(webView.canGoForward); + + webView.goForward(); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(webView.canGoBack); + verify(!webView.canGoForward); + } + + function test_reload() { + let u = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + webView.url = u; + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(webView.expectedUrl(u)); + + webView.reload(); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(webView.expectedUrl(u)); + } + + function test_loadProgress() { + // TODO check for values less than 100. Is that guaranteed to happen on all platforms? + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + verify(webView.loadProgressSpy.signalArguments.length >= 1); + compare(webView.loadProgress, 100); + } + } + + WebViewTestCase { + name: "PageData" + + function test_title() { + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page2.html"); + + if (webView.pluginIs("webengine") + || webView.pluginIs("android_view") + || webView.pluginIs("webview2") ) { + // Signal does not get emitted on some platforms, because page has no <title> + // TODO maybe fix that? + webView.titleSpy.wait(); + webView.titleSpy.clear(); + } + + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + webView.titleSpy.wait(); + tryCompare(webView, "title", "Basic Page"); + + // No titleChanged signal for failed load + webView.titleSpy.clear(); + webView.loadingStatuses = []; + webView.urls = []; + webView.url = Qt.resolvedUrl("file_that_does_not_exist.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadFailedStatus)); + + if (webView.pluginIs("android_view") + || webView.pluginIs("webview2")) { + webView.titleSpy.wait(); + } else { + wait(200); + compare(webView.titleSpy.signalArguments.length, 0); + } + } + } + + WebViewTestCase { + name: "UserAgent" + + function test_changeUserAgent() { + // Wait for backend to initialize. TODO maybe add signal for that? + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + let waitForBackend = function() { return webView.httpUserAgent.length != 0; }; + tryVerify(waitForBackend, 10000); + + let defaultAgent = webView.httpUserAgent.slice(0); + + // Test setting at object creation + webView.destroy(); + webView = webViewComponent.createObject(root, { httpUserAgent: "TestAgent" }); + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + tryVerify(waitForBackend, 10000); + verify(webView.httpUserAgent == "TestAgent"); + + // Test that the setting is not global + webView.destroy(); + webView = webViewComponent.createObject(root); + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + if (webView.pluginIs("webengine")) { + expectFail("", "The setting is global for the WebEngine backend"); + } + verify(webView.httpUserAgent == defaultAgent); + + // Test setting dynamically + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + webView.httpUserAgent = "TestAgent"; + verify(webView.httpUserAgent == "TestAgent"); + } + } + + WebViewTestCase { + name: "JavaScript" + + function test_javascriptSettings_data() { + return [ + { tag: "Test JS enabled", jsEnabled: true, expectedTitle: "JavaScript Test" }, + { tag: "Test JS disabled", jsEnabled: false, expectedTitle: "JavaScript" }, + ] + } + + function test_javascriptSettings(data) { + webView.settings.javaScriptEnabled = data.jsEnabled; + webView.url = WebViewTestUtils.makeTestFileUrl("javascript.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + tryCompare(webView, "title", data.expectedTitle); + } + + function test_runJavaScript() { + webView.url = WebViewTestUtils.makeTestFileUrl("basic_page.html"); + verify(webView.waitForLoad(WebViewLoadRequest.LoadStatus.LoadSucceededStatus)); + + var title = undefined; + webView.runJavaScript("document.title", function(result) { + title = result; + }); + + tryVerify(function() { return title === "Basic Page" }, 12000); + } + } + + WebViewTestCase { + name: "Cookies" + + function test_setAndDeleteCookies() { + let cookieList = [ + { domain: ".example1.com", name: "TestCookie1", value: "testValue1" }, + { domain: ".example2.com", name: "TestCookie2", value: "testValue2" }, + { domain: ".example3.com", name: "TestCookie3", value: "testValue3" } + ] + let deletedCookie = { domain: ".example3.com", name: "TestCookie3", value: "testValue3" }; + + for (const cookie of cookieList) { + webView.setCookie(cookie.domain, cookie.name, cookie.value); + } + + tryCompare(webView.cookieAddedSpy.signalArguments, "length", cookieList.length, 10000); + + // Delete an existing cookie + webView.deleteCookie(deletedCookie.domain, deletedCookie.name); + webView.cookieRemovedSpy.wait(); + compare(webView.cookieRemovedSpy.signalArguments[0][0], deletedCookie.domain); + compare(webView.cookieRemovedSpy.signalArguments[0][1], deletedCookie.name); + + // Try to delete a cookie using a name that has not been set + webView.deleteCookie(".example.com", "NewCookieName"); + wait(200); // We need to check that no signal has been emitted. Wait time is arbitrary + compare(webView.cookieRemovedSpy.signalArguments.length, 1); + + // Try to delete a cookie using a domain that has not been set + webView.deleteCookie("new.domain.com", "TestCookie2"); + wait(200); + compare(webView.cookieRemovedSpy.signalArguments.length, 1); + + webView.deleteAllCookies(); + if (webView.pluginIs("android_view")) { + expectFail("", "Notification for deleteAllCookies() is not implemented on Android yet!"); + } + tryCompare(webView.cookieRemovedSpy.signalArguments, "length", 3); + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/util.h new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/util.h --- old/qtwebview-everywhere-src-6.11.1/tests/auto/qml/qquickwebview/util.h 2026-05-08 20:36:42.000000000 +0200 +++ new/qtwebview-everywhere-src-6.11.2/tests/auto/qml/qquickwebview/util.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,141 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#ifndef UTIL_H -#define UTIL_H - -#include <QEventLoop> -#include <QSignalSpy> -#include <QTimer> -#include <QtTest/QtTest> -#include <QtWebViewQuick/private/qquickwebview_p.h> -#include <QtWebViewQuick/private/qquickwebviewloadrequest_p.h> - -#if !defined(TESTS_SOURCE_DIR) -#define TESTS_SOURCE_DIR "" -#endif - -class LoadSpy : public QEventLoop { - Q_OBJECT - -public: - LoadSpy(QQuickWebView *webView) - { - connect(webView, SIGNAL(loadingChanged(QQuickWebViewLoadRequest*)), SLOT(onLoadingChanged(QQuickWebViewLoadRequest*))); - } - - ~LoadSpy() { } - -Q_SIGNALS: - void loadSucceeded(); - void loadFailed(); - -private Q_SLOTS: - void onLoadingChanged(QQuickWebViewLoadRequest *loadRequest) - { - if (loadRequest->status() == QQuickWebView::LoadSucceededStatus) - emit loadSucceeded(); - else if (loadRequest->status() == QQuickWebView::LoadFailedStatus) - emit loadFailed(); - } -}; - -class LoadStartedCatcher : public QObject { - Q_OBJECT - -public: - LoadStartedCatcher(QQuickWebView *webView) - : m_webView(webView) - { - connect(m_webView, SIGNAL(loadingChanged(QQuickWebViewLoadRequest*)), this, SLOT(onLoadingChanged(QQuickWebViewLoadRequest*))); - } - - virtual ~LoadStartedCatcher() { } - -public Q_SLOTS: - void onLoadingChanged(QQuickWebViewLoadRequest *loadRequest) - { - if (loadRequest->status() == QQuickWebView::LoadStartedStatus) - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - } - -Q_SIGNALS: - void finished(); - -private: - QQuickWebView *m_webView; -}; - -/** - * Starts an event loop that runs until the given signal is received. - * Optionally the event loop - * can return earlier on a timeout. - * - * \return \p true if the requested signal was received - * \p false on timeout - */ -inline bool waitForSignal(QObject *obj, const char *signal, int timeout = 10000) -{ - QEventLoop loop; - QObject::connect(obj, signal, &loop, SLOT(quit())); - QTimer timer; - QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); - if (timeout > 0) { - QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - timer.setSingleShot(true); - timer.start(timeout); - } - loop.exec(); - return timeoutSpy.isEmpty(); -} - -inline bool waitForLoadSucceeded(QQuickWebView *webView, int timeout = 10000) -{ - LoadSpy loadSpy(webView); - return waitForSignal(&loadSpy, SIGNAL(loadSucceeded()), timeout); -} - -inline bool waitForLoadFailed(QQuickWebView *webView, int timeout = 10000) -{ - LoadSpy loadSpy(webView); - return waitForSignal(&loadSpy, SIGNAL(loadFailed()), timeout); -} - -struct Cookie -{ - struct SigArg - { - QString domain; - QString name; - }; - - using List = QList<Cookie>; - using SignalReturnValues = QList<QList<QVariant>>; - - QString domain; - QString name; - QString value; - friend bool operator==(const Cookie &a, const Cookie::SigArg &b) - { - return (a.domain == b.domain) && (a.name == b.name); - } - - static bool testSignalValues(const Cookie::List &cookies, const SignalReturnValues &sigValues) - { - if (cookies.size() != sigValues.size()) - return false; - - int found = 0; - for (const auto &cookie : cookies) { - auto it = std::find_if(sigValues.constBegin(), sigValues.constEnd(), [cookie](const QVariantList &sigArgs) { - return (cookie == Cookie::SigArg{sigArgs.at(0).toString(), sigArgs.at(1).toString() }); - }); - if (it != sigValues.constEnd()) - ++found; - } - - return (found == cookies.size()); - } -}; - -#endif /* UTIL_H */
