diff options
| author | Michal Klocek <michal.klocek@qt.io> | 2025-06-23 10:08:51 +0200 |
|---|---|---|
| committer | Michal Klocek <michal.klocek@qt.io> | 2025-06-26 11:38:21 +0200 |
| commit | 5dac61ff6fd281f47f60ae419a9b4d4332e6d17d (patch) | |
| tree | c7448a0ee352048f2235ad35a5bc3a59306579bd | |
| parent | e564399f219fe1c7d6c7a4932428c92851063c48 (diff) | |
Make tests based on runtime plugin setting
Do not rely on compile time flags, as we can run the test
with backend selected during runtime.
Introduce WebViewFactory to hide the fact that webview
tests uses quick apis. This should be all clean up when
c++ api are introduced.
Pick-to: 6.10
Change-Id: Ib630e828e6277061b84c1fe528c2d497ba4d0b4e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
| -rw-r--r-- | src/plugins/android/android.json | 5 | ||||
| -rw-r--r-- | src/plugins/darwin/darwin.json | 5 | ||||
| -rw-r--r-- | src/plugins/windows/windows.json | 5 | ||||
| -rw-r--r-- | src/plugins/winrt/winrt.json | 5 | ||||
| -rw-r--r-- | src/webview/qwebviewfactory.cpp | 12 | ||||
| -rw-r--r-- | src/webview/qwebviewfactory_p.h | 1 | ||||
| -rw-r--r-- | tests/auto/qml/qquickwebview/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | tests/auto/qml/qquickwebview/tst_qquickwebview.cpp | 50 | ||||
| -rw-r--r-- | tests/auto/webview/qwebview/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | tests/auto/webview/qwebview/tst_qwebview.cpp | 113 |
10 files changed, 105 insertions, 101 deletions
diff --git a/src/plugins/android/android.json b/src/plugins/android/android.json index 9f65fd4..b95957a 100644 --- a/src/plugins/android/android.json +++ b/src/plugins/android/android.json @@ -1,3 +1,6 @@ { - "Keys": ["native"] + "Keys": [ + "native", + "android_view" + ] } diff --git a/src/plugins/darwin/darwin.json b/src/plugins/darwin/darwin.json index 9f65fd4..d696127 100644 --- a/src/plugins/darwin/darwin.json +++ b/src/plugins/darwin/darwin.json @@ -1,3 +1,6 @@ { - "Keys": ["native"] + "Keys": [ + "native", + "webkit" + ] } diff --git a/src/plugins/windows/windows.json b/src/plugins/windows/windows.json index 9f65fd4..319863f 100644 --- a/src/plugins/windows/windows.json +++ b/src/plugins/windows/windows.json @@ -1,3 +1,6 @@ { - "Keys": ["native"] + "Keys": [ + "native", + "webview2" + ] } diff --git a/src/plugins/winrt/winrt.json b/src/plugins/winrt/winrt.json index 9f65fd4..a2a6e28 100644 --- a/src/plugins/winrt/winrt.json +++ b/src/plugins/winrt/winrt.json @@ -1,3 +1,6 @@ { - "Keys": ["native"] + "Keys": [ + "native", + "winrt" + ] } diff --git a/src/webview/qwebviewfactory.cpp b/src/webview/qwebviewfactory.cpp index b6dad45..22a24b2 100644 --- a/src/webview/qwebviewfactory.cpp +++ b/src/webview/qwebviewfactory.cpp @@ -114,4 +114,16 @@ QWebViewPlugin *QWebViewFactory::getPlugin() return qobject_cast<QWebViewPlugin *>(loader->instance(index)); } +bool QWebViewFactory::loadedPluginHasKey(const QString key) +{ + const QString &pluginName = getPluginName(); + // instead of creating multimap with QFactoryLoader::KeyMap and doing a search + // simply check if loded and key index matches + if (pluginName.isEmpty()) + return false; + const int loadedIndex = qMax<int>(0, loader->indexOf(pluginName)); + const int keyIndex = loader->indexOf(key); + return keyIndex > -1 && loadedIndex == keyIndex; +} + QT_END_NAMESPACE diff --git a/src/webview/qwebviewfactory_p.h b/src/webview/qwebviewfactory_p.h index 80cefcf..f1d999d 100644 --- a/src/webview/qwebviewfactory_p.h +++ b/src/webview/qwebviewfactory_p.h @@ -26,6 +26,7 @@ namespace QWebViewFactory QWebViewPlugin *getPlugin(); QAbstractWebView *createWebView(); bool requiresExtraInitializationSteps(); + Q_WEBVIEW_EXPORT bool loadedPluginHasKey(const QString key); }; QT_END_NAMESPACE diff --git a/tests/auto/qml/qquickwebview/CMakeLists.txt b/tests/auto/qml/qquickwebview/CMakeLists.txt index 06565d7..4d712c2 100644 --- a/tests/auto/qml/qquickwebview/CMakeLists.txt +++ b/tests/auto/qml/qquickwebview/CMakeLists.txt @@ -46,7 +46,3 @@ qt_internal_add_resource(tst_qquickwebview "testdata1" ${testdata1_resource_files} ) -qt_internal_extend_target(tst_qquickwebview CONDITION TARGET Qt::WebEngineQuick AND NOT APPLE - DEFINES - QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED -) diff --git a/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp b/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp index 51dc736..482da0d 100644 --- a/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp +++ b/tests/auto/qml/qquickwebview/tst_qquickwebview.cpp @@ -11,6 +11,7 @@ #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) @@ -321,23 +322,25 @@ void tst_QQuickWebView::titleUpdate() // Load page with no title webView()->setUrl(getTestFilePath("basic_page2.html")); QVERIFY(waitForLoadSucceeded(webView())); -#if defined(QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED) || defined(Q_OS_ANDROID) || defined(Q_OS_WIN) - // 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); -#endif + 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 defined(Q_OS_ANDROID) || (!defined(QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED) && defined(Q_OS_WIN)) - // error page with "Webpage not available" - QTRY_COMPARE(titleSpy.size(), 1); -#else - QCOMPARE(titleSpy.size(), 0); -#endif + if (QWebViewFactory::loadedPluginHasKey("android_view") + || QWebViewFactory::loadedPluginHasKey("webview2")) { + QTRY_COMPARE(titleSpy.size(), 1); + } else { + QCOMPARE(titleSpy.size(), 0); + } } void tst_QQuickWebView::changeUserAgent() @@ -359,18 +362,18 @@ void tst_QQuickWebView::setAndDeleteCookies() QSignalSpy cookieAddedSpy(webView(), SIGNAL(cookieAdded(const QString &, const QString &))); QSignalSpy cookieRemovedSpy(webView(), SIGNAL(cookieRemoved(const QString &, const QString &))); -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - webView()->setUrl(QUrl("qrc:///cookies.html")); - QVERIFY(waitForLoadSucceeded(webView())); + if (QWebViewFactory::loadedPluginHasKey("webengine")) { + webView()->setUrl(QUrl("qrc:///cookies.html")); + QVERIFY(waitForLoadSucceeded(webView())); - QTRY_COMPARE(cookieAddedSpy.size(), 2); + QTRY_COMPARE(cookieAddedSpy.size(), 2); - webView()->deleteAllCookies(); - QTRY_COMPARE(cookieRemovedSpy.size(), 2); + webView()->deleteAllCookies(); + QTRY_COMPARE(cookieRemovedSpy.size(), 2); - cookieAddedSpy.clear(); - cookieRemovedSpy.clear(); -#endif + cookieAddedSpy.clear(); + cookieRemovedSpy.clear(); + } Cookie::List cookies { {".example.com", "TestCookie", "testValue"}, {".example2.com", "TestCookie2", "testValue2"}, @@ -401,9 +404,8 @@ void tst_QQuickWebView::setAndDeleteCookies() QTRY_COMPARE(cookieRemovedSpy.size(), 1); webView()->deleteAllCookies(); -#ifdef Q_OS_ANDROID - QEXPECT_FAIL("", "Notification for deleteAllCookies() is not implemented on Android, yet!", Continue); -#endif + if (QWebViewFactory::loadedPluginHasKey("android_view")) + QEXPECT_FAIL("", "Notification for deleteAllCookies() is not implemented on Android, yet!", Continue); QTRY_COMPARE(cookieRemovedSpy.size(), 3); } diff --git a/tests/auto/webview/qwebview/CMakeLists.txt b/tests/auto/webview/qwebview/CMakeLists.txt index ca5f626..227f313 100644 --- a/tests/auto/webview/qwebview/CMakeLists.txt +++ b/tests/auto/webview/qwebview/CMakeLists.txt @@ -14,16 +14,12 @@ qt_internal_add_test(tst_qwebview ) qt_internal_extend_target(tst_qwebview CONDITION TARGET Qt::WebViewQuick - DEFINES - QT_QQUICKWEBVIEW_TESTS LIBRARIES Qt::WebViewQuickPrivate Qt::Qml ) -qt_internal_extend_target(tst_qwebview CONDITION TARGET Qt::WebEngineQuick AND NOT APPLE - DEFINES - QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED +qt_internal_extend_target(tst_qwebview CONDITION TARGET Qt::WebEngineQuick LIBRARIES Qt::WebEngineQuickPrivate Qt::Qml diff --git a/tests/auto/webview/qwebview/tst_qwebview.cpp b/tests/auto/webview/qwebview/tst_qwebview.cpp index 5db32de..d0c89bc 100644 --- a/tests/auto/webview/qwebview/tst_qwebview.cpp +++ b/tests/auto/webview/qwebview/tst_qwebview.cpp @@ -9,14 +9,12 @@ #include <QtWebView/private/qwebview_p.h> #include <QtQml/qqmlengine.h> #include <QtWebView/private/qwebviewloadrequest_p.h> - -#ifdef QT_QQUICKWEBVIEW_TESTS +#include <QtWebView/private/qwebviewfactory_p.h> #include <QtWebViewQuick/private/qquickwebview_p.h> -#endif // QT_NO_QQUICKWEBVIEW_TESTS -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED -#include <QtWebEngineQuick> -#endif // QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED +#if QT_CONFIG(webview_webengine_plugin) +#include <QtWebEngineQuick/qtwebenginequickglobal.h> +#endif #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) #include <QtCore/private/qjnihelpers_p.h> @@ -27,6 +25,30 @@ #define ANDROID_REQUIRES_API_LEVEL(N) #endif +// TODO: remove when c++ apis come +class WebViewFactory +{ +public: + WebViewFactory() + : m_webengine(QWebViewFactory::loadedPluginHasKey("webengine")), + m_engine(m_webengine ? std::make_unique<QQmlEngine>() : nullptr), + m_quickView(m_webengine ? std::make_unique<QQuickWebView>() : nullptr), + m_view(m_webengine ? nullptr : std::make_unique<QWebView>()) + { + if (m_webengine) { + QQmlContext *rootContext = m_engine->rootContext(); + QQmlEngine::setContextForObject(m_quickView.get(), rootContext); + } + } + QWebView &webViewRef() { return m_webengine ? m_quickView->webView() : *(m_view.get()); } + +private: + bool m_webengine; + std::unique_ptr<QQmlEngine> m_engine; + std::unique_ptr<QQuickWebView> m_quickView; + std::unique_ptr<QWebView> m_view; +}; + class tst_QWebView : public QObject { Q_OBJECT @@ -49,9 +71,10 @@ void tst_QWebView::initTestCase() { if (!qEnvironmentVariableIsEmpty("QEMU_LD_PREFIX")) QSKIP("This test is unstable on QEMU, so it will be skipped."); -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QtWebEngineQuick::initialize(); -#endif // QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED +#if QT_CONFIG(webview_webengine_plugin) + if (QWebViewFactory::loadedPluginHasKey("webengine")) + QtWebEngineQuick::initialize(); +#endif if (!QFileInfo(m_cacheLocation).isDir()) { QDir dir; QVERIFY(dir.mkpath(m_cacheLocation)); @@ -68,15 +91,8 @@ void tst_QWebView::load() const QString fileName = file.fileName(); file.close(); -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QQmlEngine engine; - QQmlContext *rootContext = engine.rootContext(); - QQuickWebView qview; - QQmlEngine::setContextForObject(&qview, rootContext); - QWebView &view = qview.webView(); -#else - QWebView view; -#endif + WebViewFactory factory; + QWebView &view = factory.webViewRef(); view.getSettings()->setAllowFileAccess(true); view.getSettings()->setLocalContentCanAccessFileUrls(true); QCOMPARE(view.loadProgress(), 0); @@ -92,10 +108,7 @@ void tst_QWebView::load() void tst_QWebView::runJavaScript() { -#ifdef QT_QQUICKWEBVIEW_TESTS -#ifndef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED ANDROID_REQUIRES_API_LEVEL(19) -#endif const QString tstProperty = QString(QLatin1String("Qt.tst_data")); const QString title = QString(QLatin1String("WebViewTitle")); @@ -115,25 +128,18 @@ void tst_QWebView::runJavaScript() QVERIFY(callback.isCallable()); view.runJavaScript(QString(QLatin1String("document.title")), callback); QTRY_COMPARE(engine.evaluate(tstProperty).toString(), title); -#endif // QT_QQUICKWEBVIEW_TESTS } void tst_QWebView::loadHtml() { -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QQmlEngine engine; - QQmlContext *rootContext = engine.rootContext(); - QQuickWebView qview; - QQmlEngine::setContextForObject(&qview, rootContext); - QWebView &view = qview.webView(); -#else - QWebView view; -#endif + WebViewFactory factory; + QWebView &view = factory.webViewRef(); QCOMPARE(view.loadProgress(), 0); QSignalSpy loadChangedSingalSpy(&view, SIGNAL(loadingChanged(const QWebViewLoadRequestPrivate &))); const QByteArray content( QByteArrayLiteral("<html><title>WebViewTitle</title>" "<body><span style=\"color:#ff0000\">Hello</span></body></html>")); + view.loadHtml(content); QTRY_COMPARE(view.loadProgress(), 100); QTRY_VERIFY(!view.isLoading()); @@ -164,15 +170,10 @@ void tst_QWebView::loadRequest() file.write("<html><head><title>FooBar</title></head><body/></html>"); const QString fileName = file.fileName(); file.close(); -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QQmlEngine engine; - QQmlContext *rootContext = engine.rootContext(); - QQuickWebView qview; - QQmlEngine::setContextForObject(&qview, rootContext); - QWebView &view = qview.webView(); -#else - QWebView view; -#endif + + WebViewFactory factory; + QWebView &view = factory.webViewRef(); + view.getSettings()->setAllowFileAccess(true); view.getSettings()->setLocalContentCanAccessFileUrls(true); QCOMPARE(view.loadProgress(), 0); @@ -198,15 +199,8 @@ void tst_QWebView::loadRequest() // LoadFailed { -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QQmlEngine engine; - QQmlContext *rootContext = engine.rootContext(); - QQuickWebView qview; - QQmlEngine::setContextForObject(&qview, rootContext); - QWebView &view = qview.webView(); -#else - QWebView view; -#endif + WebViewFactory factory; + QWebView &view = factory.webViewRef(); view.getSettings()->setAllowFileAccess(true); view.getSettings()->setLocalContentCanAccessFileUrls(true); QCOMPARE(view.loadProgress(), 0); @@ -224,23 +218,15 @@ void tst_QWebView::loadRequest() const QWebViewLoadRequestPrivate &lr = loadStartedArgs.at(0).value<QWebViewLoadRequestPrivate>(); QCOMPARE(lr.m_status, QWebView::LoadFailedStatus); } -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QCOMPARE(view.loadProgress(), 0); // darwin plugin returns 100 -#endif + if (QWebViewFactory::loadedPluginHasKey("webengine")) + QCOMPARE(view.loadProgress(), 0); // darwin plugin returns 100 } } void tst_QWebView::setAndDeleteCookie() { -#ifdef QT_WEBVIEW_WEBENGINE_BACKEND_IS_COMPILED - QQmlEngine engine; - QQmlContext * rootContext = engine.rootContext(); - QQuickWebView qview; - QQmlEngine::setContextForObject(&qview, rootContext); - QWebView & view = qview.webView(); -#else - QWebView view; -#endif + WebViewFactory factory; + QWebView &view = factory.webViewRef(); view.getSettings()->setLocalStorageEnabled(true); view.getSettings()->setAllowFileAccess(true); view.getSettings()->setLocalContentCanAccessFileUrls(true); @@ -265,9 +251,8 @@ void tst_QWebView::setAndDeleteCookie() QTRY_COMPARE(cookieRemovedSpy.size(), 1); view.deleteAllCookies(); -#ifdef Q_OS_ANDROID - QEXPECT_FAIL("", "Notification for deleteAllCookies() is not implemented on Android, yet!", Continue); -#endif + if (QWebViewFactory::loadedPluginHasKey("android_view")) + QEXPECT_FAIL("", "Notification for deleteAllCookies() is not implemented on Android, yet!", Continue); QTRY_COMPARE(cookieRemovedSpy.size(), 3); } |
