summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-05-10 14:39:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-05-12 12:46:13 +0200
commit4629185e555e6c891d6308ae7cafa584ce6d731f (patch)
tree1ed9f01ec7fdb6f52a607cab0a31b60bb60179d2
parentf8527fa9427984082cd425d304d29fd030ff5b1a (diff)
parent5d41d39b82acb3e2da597df0588fb906e212d608 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: examples/webenginewidgets/printme/printhandler.cpp src/3rdparty src/core/api/qwebenginepage_p.h src/core/content_browser_client_qt.h src/core/web_contents_adapter_client.h src/core/web_contents_delegate_qt.cpp src/core/web_contents_delegate_qt.h src/webenginequick/api/qquickwebengineview_p_p.h tests/auto/quick/qmltests/data/tst_download.qml tests/auto/quick/qmltests/data/tst_viewSoure.qml tests/auto/widgets/loadsignals/tst_loadsignals.cpp tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp Change-Id: I9c1819ec15e13d4f8e244defe860e26274b5d4be
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml12
-rw-r--r--examples/webenginewidgets/printme/printhandler.cpp1
m---------src/3rdparty0
-rw-r--r--src/core/api/qwebenginepage.cpp22
-rw-r--r--src/core/api/qwebenginepage_p.h3
-rw-r--r--src/core/content_browser_client_qt.cpp23
-rw-r--r--src/core/content_browser_client_qt.h2
-rw-r--r--src/core/content_main_delegate_qt.cpp4
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp2
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp2
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp2
-rw-r--r--src/core/permission_manager_qt.cpp7
-rw-r--r--src/core/permission_manager_qt.h8
-rw-r--r--src/core/profile_adapter.cpp31
-rw-r--r--src/core/profile_adapter.h1
-rw-r--r--src/core/profile_io_data_qt.cpp3
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp3
-rw-r--r--src/core/resource_bundle_qt.cpp2
-rw-r--r--src/core/web_contents_adapter.cpp6
-rw-r--r--src/core/web_contents_adapter_client.h3
-rw-r--r--src/core/web_contents_delegate_qt.cpp121
-rw-r--r--src/core/web_contents_delegate_qt.h22
-rw-r--r--src/core/web_engine_library_info.cpp10
-rw-r--r--src/core/web_engine_library_info.h1
-rw-r--r--src/webenginequick/api/qquickwebengineview.cpp4
-rw-r--r--src/webenginequick/api/qquickwebengineview_p_p.h3
-rw-r--r--src/webenginequick/doc/src/qtwebengine-platform-notes.qdoc4
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc6
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp42
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp2
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST5
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml1
-rw-r--r--tests/auto/quick/qmltests/data/test4.html1
-rw-r--r--tests/auto/quick/qmltests/data/tst_action.qml10
-rw-r--r--tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_audioMuted.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_certificateError.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_contextMenu.qml4
-rw-r--r--tests/auto/quick/qmltests/data/tst_favicon.qml14
-rw-r--r--tests/auto/quick/qmltests/data/tst_faviconDownload.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_filePicker.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml4
-rw-r--r--tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_inputMethod.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardEvents.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadFail.qml7
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadHtml.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml18
-rw-r--r--tests/auto/quick/qmltests/data/tst_mouseClick.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationRequested.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml6
-rw-r--r--tests/auto/quick/qmltests/data/tst_settings.qml3
-rw-r--r--tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_viewSoure.qml16
-rw-r--r--tests/auto/shared/data/loadprogress/page1.html2
-rw-r--r--tests/auto/shared/data/loadprogress/page2.html1
-rw-r--r--tests/auto/shared/data/loadprogress/page5.html20
-rw-r--r--tests/auto/shared/data/loadprogress/page6.html13
-rw-r--r--tests/auto/shared/data/loadprogress/page7.html13
-rw-r--r--tests/auto/shared/data/loadprogress/page8.html20
-rw-r--r--tests/auto/shared/httpserver.h2
-rw-r--r--tests/auto/widgets/certificateerror/tst_certificateerror.cpp2
-rw-r--r--tests/auto/widgets/loadsignals/BLACKLIST17
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.cpp343
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.qrc4
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/redirect.html8
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp42
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc1
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST3
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp49
70 files changed, 642 insertions, 354 deletions
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index c595c3bc5..1b8915df2 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -624,6 +624,18 @@ ApplicationWindow {
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
}
+
+ Timer {
+ id: hideTimer
+ interval: 0
+ running: false
+ repeat: false
+ onTriggered: devToolsEnabled.checked = false
+ }
+ onWindowCloseRequested: function(request) {
+ // Delay hiding for keep the inspectedView set to receive the ACK message of close.
+ hideTimer.running = true;
+ }
}
MessageDialog {
id: sslDialog
diff --git a/examples/webenginewidgets/printme/printhandler.cpp b/examples/webenginewidgets/printme/printhandler.cpp
index 9d23c5b1f..3534c155b 100644
--- a/examples/webenginewidgets/printme/printhandler.cpp
+++ b/examples/webenginewidgets/printme/printhandler.cpp
@@ -107,6 +107,7 @@ void PrintHandler::printPreview()
return;
m_inPrintPreview = true;
QPrinter printer;
+ printer.setResolution(300);
QPrintPreviewDialog preview(&printer, m_view);
connect(&preview, &QPrintPreviewDialog::paintRequested,
this, &PrintHandler::printDocument);
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 6011d6c03dd7111441384033ff56120894e5b54
+Subproject 07af1bb4559d63ffe80a15603622dc2b75792da
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index c168ca93e..367688c88 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -305,28 +305,20 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError
QTimer::singleShot(0, q, &QWebEnginePage::loadStarted);
}
-void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode,
- const QString &errorDescription, bool triggersErrorPage)
+void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
{
Q_Q(QWebEnginePage);
Q_UNUSED(url);
Q_UNUSED(errorCode);
Q_UNUSED(errorDescription);
- if (isErrorPage) {
- QTimer::singleShot(0, q, [q](){
- emit q->loadFinished(false);
- });
+ if (isErrorPage)
return;
- }
isLoading = false;
- Q_ASSERT((success && !triggersErrorPage) || !success);
- if (!triggersErrorPage) {
- QTimer::singleShot(0, q, [q, success](){
- emit q->loadFinished(success);
- });
- }
+ QTimer::singleShot(0, q, [q, success](){
+ emit q->loadFinished(success);
+ });
}
void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success)
@@ -2293,6 +2285,10 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+ \note This function rasterizes the result when rendering onto \a printer. Please consider raising
+ the default resolution of \a printer to at least 300 DPI or using printToPdf() to produce
+ PDF file output more effectively.
+
\since 5.8
*/
void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 1f8087c59..081287889 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -134,8 +134,7 @@ public:
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override { }
void didFirstVisuallyNonEmptyPaint() override { }
- void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode,
- const QString &errorDescription, bool triggersErrorPage) override;
+ void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) override;
void focusContainer() override;
void unhandledKeyEvent(QKeyEvent *event) override;
QSharedPointer<QtWebEngineCore::WebContentsAdapter>
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 1b8ba26e8..d68cad2b0 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -39,6 +39,7 @@
#include "content_browser_client_qt.h"
+#include "base/files/file_util.h"
#include "base/optional.h"
#include "base/task/post_task.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
@@ -348,12 +349,7 @@ std::unique_ptr<net::ClientCertStore> ContentBrowserClientQt::CreateClientCertSt
std::string ContentBrowserClientQt::GetApplicationLocale()
{
- std::string bcp47Name = QLocale().bcp47Name().toStdString();
- if (m_cachedQtLocale != bcp47Name) {
- m_cachedQtLocale = bcp47Name;
- m_appLocale = WebEngineLibraryInfo::getApplicationLocale();
- }
- return m_appLocale;
+ return WebEngineLibraryInfo::getApplicationLocale();
}
std::string ContentBrowserClientQt::GetAcceptLangs(content::BrowserContext *context)
@@ -369,7 +365,7 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c
std::string processType = command_line->GetSwitchValueASCII(switches::kProcessType);
if (processType == switches::kZygoteProcess)
- command_line->AppendSwitchASCII(switches::kLang, GetApplicationLocale());
+ command_line->AppendSwitchASCII(switches::kLang, WebEngineLibraryInfo::getApplicationLocale());
}
void ContentBrowserClientQt::GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes)
@@ -397,9 +393,8 @@ void ContentBrowserClientQt::GetAdditionalAllowedSchemesForFileSystem(std::vecto
#if defined(Q_OS_LINUX)
void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings)
{
- const std::string &locale = GetApplicationLocale();
- const base::FilePath &locale_file_path = ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale);
- if (locale_file_path.empty())
+ const base::FilePath &locale_file_path = ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(WebEngineLibraryInfo::getResolvedLocale());
+ if (locale_file_path.empty() || !base::PathExists(locale_file_path))
return;
// Open pak file of the current locale in the Browser process and pass its file descriptor to the sandboxed
@@ -852,7 +847,13 @@ static bool navigationThrottleCallback(content::WebContents *source,
WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(source)->GetView())->client();
if (!client)
return false;
- client->navigationRequested(pageTransitionToNavigationType(params.transition_type()),
+
+ // Redirects might not be reflected in transition_type at this point (see also chrome/.../web_navigation_api_helpers.cc)
+ auto transition_type = params.transition_type();
+ if (params.is_redirect())
+ transition_type = ui::PageTransitionFromInt(transition_type | ui::PAGE_TRANSITION_SERVER_REDIRECT);
+
+ client->navigationRequested(pageTransitionToNavigationType(transition_type),
toQt(params.url()),
navigationRequestAction,
params.is_main_frame());
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index a5fcc64ef..bac155c8c 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -263,8 +263,6 @@ public:
private:
scoped_refptr<ShareGroupQt> m_shareGroupQt;
- std::string m_appLocale;
- std::string m_cachedQtLocale;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index a8e8b7c8a..62d033f00 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -179,7 +179,9 @@ void ContentMainDelegateQt::PreSandboxStartup()
#endif
net::NetModule::SetResourceProvider(PlatformResourceProvider);
- ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getApplicationLocale(), nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
+
+ base::i18n::SetICUDefaultLocale(WebEngineLibraryInfo::getApplicationLocale());
+ ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getResolvedLocale(), nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
logging::LoggingSettings settings;
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index 792d34373..6d72a622b 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -80,7 +80,7 @@ public:
void AllowedAccess(const GURL &url, const net::SiteForCookies &site_for_cookies, AllowedAccessCallback callback) override
{
- bool allow = m_delegate->canGetCookies(toQt(site_for_cookies.RepresentativeUrl()), toQt(url));
+ bool allow = m_delegate->canGetCookies(toQt(site_for_cookies.first_party_url()), toQt(url));
std::move(callback).Run(allow);
}
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index b0d3787de..f86c0e997 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.cpp
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -197,7 +197,7 @@ bool ProxyingRestrictedCookieManagerQt::allowCookies(const GURL &url, const net:
{
if (!m_profileIoData)
return false;
- return m_profileIoData->canGetCookies(toQt(site_for_cookies.RepresentativeUrl()), toQt(url));
+ return m_profileIoData->canGetCookies(toQt(site_for_cookies.first_party_url()), toQt(url));
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index bc70928ab..c945ee4d5 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -267,7 +267,7 @@ void InterceptedRequest::Restart()
if (!top_document_url.is_empty())
firstPartyUrl = toQt(top_document_url);
else
- firstPartyUrl = toQt(request_.site_for_cookies.RepresentativeUrl()); // m_topDocumentUrl can be empty for the main-frame.
+ firstPartyUrl = toQt(request_.site_for_cookies.first_party_url()); // m_topDocumentUrl can be empty for the main-frame.
auto info = new QWebEngineUrlRequestInfoPrivate(resourceType, navigationType, originalUrl, firstPartyUrl,
initiator, QByteArray::fromStdString(request_.method));
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index f476a5aa1..e0a26e012 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -122,7 +122,6 @@ static blink::mojom::PermissionStatus toBlink(ProfileAdapter::PermissionState re
PermissionManagerQt::PermissionManagerQt()
: m_requestIdCount(0)
- , m_subscriberIdCount(0)
{
}
@@ -341,19 +340,19 @@ void PermissionManagerQt::ResetPermission(
m_permissions.remove(key);
}
-int PermissionManagerQt::SubscribePermissionStatusChange(
+content::PermissionControllerDelegate::SubscriptionId PermissionManagerQt::SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost * /* render_frame_host */,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
{
- int subscriber_id = ++m_subscriberIdCount;
+ auto subscriber_id = subscription_id_generator_.GenerateNextId();
m_subscribers.insert( { subscriber_id,
Subscription { toQt(permission), toQt(requesting_origin), std::move(callback) } });
return subscriber_id;
}
-void PermissionManagerQt::UnsubscribePermissionStatusChange(int subscription_id)
+void PermissionManagerQt::UnsubscribePermissionStatusChange(content::PermissionControllerDelegate::SubscriptionId subscription_id)
{
if (!m_subscribers.erase(subscription_id))
LOG(WARNING) << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index e046174df..f8d7e0ee3 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -89,13 +89,13 @@ public:
base::OnceCallback<void(
const std::vector<blink::mojom::PermissionStatus>&)> callback) override;
- int SubscribePermissionStatusChange(
+ content::PermissionControllerDelegate::SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
const base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(content::PermissionControllerDelegate::SubscriptionId subscription_id) override;
private:
QHash<QPair<QUrl, ProfileAdapter::PermissionType>, bool> m_permissions;
@@ -118,9 +118,9 @@ private:
};
std::vector<Request> m_requests;
std::vector<MultiRequest> m_multiRequests;
- std::map<int, Subscription> m_subscribers;
+ std::map<content::PermissionControllerDelegate::SubscriptionId, Subscription> m_subscribers;
+ content::PermissionControllerDelegate::SubscriptionId::Generator subscription_id_generator_;
int m_requestIdCount;
- int m_subscriberIdCount;
};
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index bc138b7d0..9a6275a84 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -87,6 +87,9 @@ inline QString buildLocationFromStandardPath(const QString &standardPath, const
namespace QtWebEngineCore {
+// static
+QPointer<ProfileAdapter> ProfileAdapter::s_profileForGlobalCertificateVerification;
+
ProfileAdapter::ProfileAdapter(const QString &storageName):
m_name(storageName)
, m_offTheRecord(storageName.isEmpty())
@@ -654,26 +657,26 @@ void ProfileAdapter::setUseForGlobalCertificateVerification(bool enable)
if (m_usedForGlobalCertificateVerification == enable)
return;
- static QPointer<ProfileAdapter> profileForglobalCertificateVerification;
-
m_usedForGlobalCertificateVerification = enable;
if (enable) {
- if (profileForglobalCertificateVerification) {
- profileForglobalCertificateVerification->m_usedForGlobalCertificateVerification = false;
- if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
- profileForglobalCertificateVerification->m_profile->m_profileIOData->resetNetworkContext();
- for (auto *client : qAsConst(profileForglobalCertificateVerification->m_clients))
+ if (s_profileForGlobalCertificateVerification) {
+ s_profileForGlobalCertificateVerification->m_usedForGlobalCertificateVerification = false;
+ for (auto *client : qAsConst(s_profileForGlobalCertificateVerification->m_clients))
client->useForGlobalCertificateVerificationChanged();
+ } else {
+ // OCSP enabled
+ for (auto adapter : qAsConst(WebEngineContext::current()->m_profileAdapters))
+ adapter->m_profile->m_profileIOData->resetNetworkContext();
}
- profileForglobalCertificateVerification = this;
+ s_profileForGlobalCertificateVerification = this;
} else {
- Q_ASSERT(profileForglobalCertificateVerification);
- Q_ASSERT(profileForglobalCertificateVerification == this);
- profileForglobalCertificateVerification = nullptr;
+ Q_ASSERT(s_profileForGlobalCertificateVerification);
+ Q_ASSERT(s_profileForGlobalCertificateVerification == this);
+ s_profileForGlobalCertificateVerification = nullptr;
+ // OCSP disabled
+ for (auto adapter : qAsConst(WebEngineContext::current()->m_profileAdapters))
+ adapter->m_profile->m_profileIOData->resetNetworkContext();
}
-
- if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
- m_profile->m_profileIOData->resetNetworkContext();
}
bool ProfileAdapter::isUsedForGlobalCertificateVerification() const
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index f59768004..e6e9ab7cb 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -215,6 +215,7 @@ public:
QString determineDownloadPath(const QString &downloadDirectory, const QString &suggestedFilename, const time_t &startTime);
+ static QPointer<ProfileAdapter> s_profileForGlobalCertificateVerification;
private:
void updateCustomUrlSchemeHandlers();
void resetVisitedLinksManager();
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 68e674f01..8e6c8fed3 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -224,6 +224,9 @@ void ProfileIODataQt::ConfigureNetworkContextParams(bool in_memory,
SystemNetworkContextManager::GetInstance()->ConfigureDefaultNetworkContextParams(network_context_params);
+ // FIXME: Faking old behavior to allow not enabling OCSP
+ network_context_params->initial_ssl_config->rev_checking_enabled = !ProfileAdapter::s_profileForGlobalCertificateVerification.isNull();
+
network_context_params->context_name = m_storageName.toStdString();
network_context_params->user_agent = m_httpUserAgent.toStdString();
network_context_params->accept_language = m_httpAcceptLanguage.toStdString();
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index de3a76d78..99e98985b 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -117,6 +117,8 @@
#include "chrome/renderer/media/webrtc_logging_agent_impl.h"
#endif
+#include "web_engine_library_info.h"
+
namespace QtWebEngineCore {
static const char kHttpErrorDomain[] = "http";
@@ -133,6 +135,7 @@ ContentRendererClientQt::~ContentRendererClientQt() {}
void ContentRendererClientQt::RenderThreadStarted()
{
+ base::i18n::SetICUDefaultLocale(WebEngineLibraryInfo::getApplicationLocale());
content::RenderThread *renderThread = content::RenderThread::Get();
m_renderConfiguration.reset(new RenderConfiguration());
m_userResourceController.reset(new UserResourceController());
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp
index 22622f216..4e814a806 100644
--- a/src/core/resource_bundle_qt.cpp
+++ b/src/core/resource_bundle_qt.cpp
@@ -98,7 +98,7 @@ std::string ResourceBundle::LoadLocaleResources(const std::string &pref_locale,
{
DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded";
- std::string app_locale = l10n_util::GetApplicationLocale(pref_locale);
+ std::string app_locale = l10n_util::GetApplicationLocale(pref_locale, false /* set_icu_locale */);
#if defined(OS_LINUX)
int locale_fd = base::GlobalDescriptors::GetInstance()->MaybeGet(kWebEngineLocale);
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 695ef24c1..f5656f571 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -717,8 +717,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
m_adapterClient->loadFinished(false, request.url(), false,
net::ERR_DISALLOWED_URL_SCHEME,
QCoreApplication::translate("WebContentsAdapter",
- "HTTP-POST data can only be sent over HTTP(S) protocol"),
- false);
+ "HTTP-POST data can only be sent over HTTP(S) protocol"));
return;
}
params.post_data = network::ResourceRequestBody::CreateFromBytes(
@@ -773,7 +772,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
GURL dataUrlToLoad(urlString);
if (dataUrlToLoad.spec().size() > url::kMaxURLChars) {
- m_adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED, QString(), false);
+ m_adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED, QString());
return;
}
content::NavigationController::LoadURLParams params((dataUrlToLoad));
@@ -1994,6 +1993,7 @@ void WebContentsAdapter::discard()
if (m_webContents->IsLoading()) {
m_webContentsDelegate->didFailLoad(m_webContentsDelegate->url(webContents()), net::Error::ERR_ABORTED,
QStringLiteral("Discarded"));
+ m_webContentsDelegate->DidStopLoading();
}
content::WebContents::CreateParams createParams(m_profileAdapter->profile());
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 497b94720..1e2c7bbec 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -195,8 +195,7 @@ public:
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0;
virtual void loadCommitted() = 0;
virtual void didFirstVisuallyNonEmptyPaint() = 0;
- virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode,
- const QString &errorDescription, bool triggersErrorPage) = 0;
+ virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) = 0;
virtual void focusContainer() = 0;
virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
virtual QSharedPointer<WebContentsAdapter>
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index e71e78d3c..5d11f43c3 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -258,14 +258,12 @@ void WebContentsDelegateQt::CloseContents(content::WebContents *source)
void WebContentsDelegateQt::LoadProgressChanged(double progress)
{
- QUrl current_url(m_viewClient->webContentsAdapter()->getNavigationEntryOriginalUrl(m_viewClient->webContentsAdapter()->currentNavigationEntryIndex()));
- int p = qMin(qRound(progress * 100), 100);
-
- if (!m_loadingErrorFrameList.isEmpty() || !m_loadProgressMap.contains(current_url) || m_loadProgressMap[current_url] == 100 || p == 100)
+ if (!m_loadingInfo.isLoading()) // suppress signals that aren't between loadStarted and loadFinished
return;
- if (p > m_loadProgressMap[current_url]) { // ensure strict monotonic increase
- m_loadProgressMap[current_url] = p;
+ int p = qMin(qRound(progress * 100), 100);
+ if (p > m_loadingInfo.progress) { // ensure strict monotonic increase
+ m_loadingInfo.progress = p;
m_viewClient->loadProgressChanged(p);
}
}
@@ -285,11 +283,6 @@ void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_
m_frameFocusedObserver.addNode(node);
}
-void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
-{
- m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
-}
-
void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
{
// RenderProcessHost::FastShutdownIfPossible results in TERMINATION_STATUS_STILL_RUNNING
@@ -339,40 +332,26 @@ void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, con
}
}
-void WebContentsDelegateQt::EmitLoadStarted(const QUrl &url, bool isErrorPage)
+void WebContentsDelegateQt::emitLoadStarted(bool isErrorPage)
{
for (auto &&wc : m_certificateErrorControllers)
if (auto controller = wc.lock())
controller->deactivate();
m_certificateErrorControllers.clear();
- m_isDocumentEmpty = true;
- m_viewClient->loadStarted(url, isErrorPage);
- m_viewClient->updateNavigationActions();
-
- if ((url.hasFragment() || m_lastLoadedUrl.hasFragment())
- && url.adjusted(QUrl::RemoveFragment) == m_lastLoadedUrl.adjusted(QUrl::RemoveFragment)
- && !m_isNavigationCommitted) {
- m_loadProgressMap.insert(url, 100);
- m_lastLoadedUrl = url;
- m_viewClient->loadProgressChanged(100);
+ // only report first ever load start or separate one for error page only
+ if (!isErrorPage && m_loadingInfo.isLoading()) // already running
return;
- }
- if (!m_loadProgressMap.isEmpty()) {
- QMap<QUrl, int>::iterator it = m_loadProgressMap.begin();
- while (it != m_loadProgressMap.end()) {
- if (it.value() == 100) {
- it = m_loadProgressMap.erase(it);
- continue;
- }
- ++it;
- }
+ m_isDocumentEmpty = true; // reset to default which may only be overridden on actual resource load complete
+ if (!isErrorPage) {
+ m_loadingInfo.progress = 0;
+ m_viewClient->loadStarted(m_loadingInfo.url, false);
+ m_viewClient->updateNavigationActions();
+ m_viewClient->loadProgressChanged(0);
+ } else {
+ m_viewClient->loadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true);
}
-
- m_lastLoadedUrl = url;
- m_loadProgressMap.insert(url, 0);
- m_viewClient->loadProgressChanged(0);
}
void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *navigation_handle)
@@ -380,34 +359,39 @@ void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *naviga
if (!webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled))
navigation_handle->SetSilentlyIgnoreErrors();
- if (!navigation_handle->IsInMainFrame())
+ if (!navigation_handle->IsInMainFrame() || !web_contents()->IsLoadingToDifferentDocument())
return;
-
- m_loadingErrorFrameList.clear();
m_faviconManager->resetCandidates();
- EmitLoadStarted(toQt(navigation_handle->GetURL()));
+
+ m_loadingInfo.url = toQt(navigation_handle->GetURL());
+ // IsErrorPage is only set after navigation commit, so check it otherwise: error page shouldn't have navigation entry
+ bool isErrorPage = m_loadingInfo.triggersErrorPage && !navigation_handle->GetNavigationEntry();
+ emitLoadStarted(isErrorPage);
}
-void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription, bool triggersErrorPage)
+void WebContentsDelegateQt::emitLoadFinished(bool isErrorPage)
{
- Q_ASSERT(!isErrorPage || webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled));
- Q_ASSERT((triggersErrorPage && webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled)) || !triggersErrorPage);
-
- // When error page enabled we don't need to send the error page load finished signal
- if (m_loadProgressMap[url] == 100)
+ if (!m_loadingInfo.isLoading()) // not currently running
return;
- m_lastLoadedUrl = url;
- m_loadProgressMap[url] = 100;
- m_isNavigationCommitted = false;
- m_viewClient->loadProgressChanged(100);
+ Q_ASSERT(!isErrorPage || webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled));
+ Q_ASSERT((m_loadingInfo.triggersErrorPage && webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled)) || !m_loadingInfo.triggersErrorPage);
- m_viewClient->loadFinished(success, url, isErrorPage, errorCode, errorDescription, triggersErrorPage);
- m_viewClient->updateNavigationActions();
+ if (!isErrorPage) {
+ if (m_loadingInfo.progress < 100) {
+ m_loadingInfo.progress = 100;
+ m_viewClient->loadProgressChanged(100);
+ }
+
+ m_viewClient->loadFinished(m_loadingInfo.success, m_loadingInfo.url, false, m_loadingInfo.errorCode, m_loadingInfo.errorDescription);
+ m_viewClient->updateNavigationActions();
+ } else {
+ m_viewClient->loadFinished(false, toQt(GURL(content::kUnreachableWebDataURL)), true, 0, QString());
+ }
}
-void WebContentsDelegateQt::EmitLoadCommitted()
+void WebContentsDelegateQt::emitLoadCommitted()
{
m_findTextHelper->handleLoadCommitted();
m_viewClient->loadCommitted();
@@ -427,8 +411,7 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
profileAdapter->visitedLinksManager()->addUrl(url);
}
- m_isNavigationCommitted = true;
- EmitLoadCommitted();
+ emitLoadCommitted();
}
// Success is reported by DidFinishLoad, but DidFailLoad is now dead code and needs to be handled below
@@ -443,13 +426,12 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
// The load will succede as an error-page load later, and we reported the original error above
if (navigation_handle->IsErrorPage()) {
// Now report we are starting to load an error-page.
- m_loadingErrorFrameList.append(navigation_handle->GetRenderFrameHost()->GetRoutingID());
m_faviconManager->resetCandidates();
- EmitLoadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true);
+ emitLoadStarted(true);
// If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call.
if (navigation_handle->HasCommitted())
- EmitLoadCommitted();
+ emitLoadCommitted();
}
}
@@ -491,6 +473,9 @@ void WebContentsDelegateQt::DidStopLoading()
if (m_loadingState == LoadingState::Loading)
setLoadingState(LoadingState::Loaded);
+
+ emitLoadFinished();
+ m_loadingInfo.clear();
}
void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription)
@@ -500,7 +485,11 @@ void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QS
// Delay notifying failure until the error-page is done loading.
// Error-pages are not loaded on failures due to abort.
bool aborted = (errorCode == -3 /* ERR_ABORTED*/ );
- EmitLoadFinished(false /* success */ , url, false /* isErrorPage */, errorCode, errorDescription, errorPageEnabled && !aborted);
+ m_loadingInfo.success = false;
+ m_loadingInfo.url = url;
+ m_loadingInfo.errorCode = errorCode;
+ m_loadingInfo.errorDescription = errorDescription;
+ m_loadingInfo.triggersErrorPage = errorPageEnabled && !aborted;
}
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code)
@@ -514,10 +503,8 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
if (validated_url.spec() == content::kUnreachableWebDataURL) {
// error-pages should only ever fail due to abort:
Q_ASSERT(error_code == -3 /* ERR_ABORTED */);
- m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
m_viewClient->iconChanged(QUrl());
-
- EmitLoadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */);
+ emitLoadFinished(/* isErrorPage = */true);
return;
}
// Qt6: Consider getting rid of the error_description (Chromium already has)
@@ -532,12 +519,10 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
{
Q_ASSERT(validated_url.is_valid());
if (validated_url.spec() == content::kUnreachableWebDataURL) {
- m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
-
// Trigger LoadFinished signal for main frame's error page only.
if (!render_frame_host->GetParent()) {
m_viewClient->iconChanged(QUrl());
- EmitLoadFinished(true /* success */, toQt(validated_url), true /* isErrorPage */);
+ emitLoadFinished(/* isErrorPage = */true);
}
return;
@@ -555,7 +540,11 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
int http_statuscode = entry ? entry->GetHttpStatusCode() : 0;
bool errorPageEnabled = webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled);
bool triggersErrorPage = errorPageEnabled && (http_statuscode >= 400) && m_isDocumentEmpty;
- EmitLoadFinished(http_statuscode < 400, toQt(validated_url), false /* isErrorPage */, http_statuscode, QString(), triggersErrorPage);
+
+ m_loadingInfo.success = http_statuscode < 400;
+ m_loadingInfo.url = toQt(validated_url);
+ m_loadingInfo.errorCode = http_statuscode;
+ m_loadingInfo.triggersErrorPage = triggersErrorPage;
}
void WebContentsDelegateQt::DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index ca2cf2e0e..c3676d996 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -155,7 +155,6 @@ public:
// WebContentsObserver overrides
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
- void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
void RenderProcessGone(base::TerminationStatus status) override;
void RenderFrameHostChanged(content::RenderFrameHost *old_host, content::RenderFrameHost *new_host) override;
void RenderViewHostChanged(content::RenderViewHost *old_host, content::RenderViewHost *new_host) override;
@@ -212,9 +211,9 @@ private:
WindowOpenDisposition disposition, const gfx::Rect &initial_pos,
const QUrl &url,
bool user_gesture);
- void EmitLoadStarted(const QUrl &url, bool isErrorPage = false);
- void EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString(), bool triggersErrorPage = false);
- void EmitLoadCommitted();
+ void emitLoadStarted(bool isErrorPage = false);
+ void emitLoadFinished(bool isErrorPage = false);
+ void emitLoadCommitted();
LoadingState determineLoadingState(content::WebContents *contents);
void setLoadingState(LoadingState state);
@@ -222,7 +221,6 @@ private:
int &streamCount(blink::mojom::MediaStreamType type);
WebContentsAdapterClient *m_viewClient;
- QList<int64_t> m_loadingErrorFrameList;
QScopedPointer<FaviconManager> m_faviconManager;
QScopedPointer<FindTextHelper> m_findTextHelper;
SavePageInfo m_savePageInfo;
@@ -238,9 +236,17 @@ private:
int m_desktopStreamCount = 0;
mutable bool m_pendingUrlUpdate = false;
- QMap<QUrl, int> m_loadProgressMap;
- QUrl m_lastLoadedUrl;
- bool m_isNavigationCommitted = false;
+ struct LoadingInfo {
+ bool success = false;
+ int progress = -1;
+ bool isLoading() const { return progress >= 0; }
+ QUrl url;
+ int errorCode = 0;
+ QString errorDescription;
+ bool triggersErrorPage = false;
+ void clear() { *this = LoadingInfo(); }
+ } m_loadingInfo;
+
bool m_isDocumentEmpty = true;
base::WeakPtrFactory<WebContentsDelegateQt> m_weakPtrFactory { this };
QList<QWeakPointer<CertificateErrorController>> m_certificateErrorControllers;
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 47c4634b3..407bd50bc 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -351,7 +351,7 @@ base::string16 WebEngineLibraryInfo::getApplicationName()
return toString16(qApp->applicationName());
}
-std::string WebEngineLibraryInfo::getApplicationLocale()
+std::string WebEngineLibraryInfo::getResolvedLocale()
{
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
if (parsedCommandLine->HasSwitch(switches::kLang)) {
@@ -365,6 +365,14 @@ std::string WebEngineLibraryInfo::getApplicationLocale()
return "en-US";
}
+std::string WebEngineLibraryInfo::getApplicationLocale()
+{
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ return parsedCommandLine->HasSwitch(switches::kLang)
+ ? parsedCommandLine->GetSwitchValueASCII(switches::kLang)
+ : QLocale().bcp47Name().toStdString();
+}
+
#if defined(OS_WIN)
bool WebEngineLibraryInfo::isRemoteDrivePath(const QString &path)
{
diff --git a/src/core/web_engine_library_info.h b/src/core/web_engine_library_info.h
index 4d23d8921..e7dc195f6 100644
--- a/src/core/web_engine_library_info.h
+++ b/src/core/web_engine_library_info.h
@@ -57,6 +57,7 @@ public:
static base::FilePath getPath(int key);
// Called by localized_error in our custom chrome layer
static base::string16 getApplicationName();
+ static std::string getResolvedLocale();
static std::string getApplicationLocale();
#if defined(OS_WIN)
static bool isRemoteDrivePath(const QString &path);
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 494e26090..710e593c5 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -517,11 +517,9 @@ void QQuickWebEngineViewPrivate::didCompositorFrameSwap()
#endif
}
-void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode,
- const QString &errorDescription, bool triggersErrorPage)
+void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
{
Q_Q(QQuickWebEngineView);
- Q_UNUSED(triggersErrorPage);
if (isErrorPage) {
#if QT_CONFIG(webenginequick_testsupport)
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index d472d6975..115c13e06 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -117,8 +117,7 @@ public:
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override;
void didFirstVisuallyNonEmptyPaint() override;
- void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode,
- const QString &errorDescription, bool triggersErrorPage) override;
+ void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) override;
void focusContainer() override;
void unhandledKeyEvent(QKeyEvent *event) override;
QSharedPointer<QtWebEngineCore::WebContentsAdapter>
diff --git a/src/webenginequick/doc/src/qtwebengine-platform-notes.qdoc b/src/webenginequick/doc/src/qtwebengine-platform-notes.qdoc
index 6356b97af..e32424eea 100644
--- a/src/webenginequick/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webenginequick/doc/src/qtwebengine-platform-notes.qdoc
@@ -65,7 +65,7 @@
\li \l Python 2.7.5 or later. Python 3 is not supported.
\li Bison, Flex
\li GPerf
- \li Node.js for a full featured Dev Tools.
+ \li Node.js version 8 or later (version 12 or later is recommended)
\endlist
\section2 Windows
@@ -73,7 +73,7 @@
On Windows, the following additional tools are required:
\list
- \li Visual Studio 2017 version 15.8 or later
+ \li Visual Studio 2017 version 15.8 or later, or clang-cl version 8 or later
\li Active Template Library (ATL), usually included in the Visual Studio
installation
\li Windows 10 SDK version 10.0.19041 or later
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 5def0d65c..087c171cb 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -381,6 +381,12 @@
used as part of the user interface, and not to display external data, for example, when
displaying a list of results.
+ \note This function is not called for fragment navigation on the same page. Such navigation,
+ for example, happens by clicking a link to a '#fragment' within the page. It does not trigger
+ a load to a different document, even though it changes page's url and adds history entry.
+ It only serves as a shortcut to scroll within the page. Hence, no delegation of this navigation
+ type is expected to happen.
+
\note The loading process is started and the loadStarted() signal is emitted
\e before the request is accepted or rejected. Therefore, a loadFinished()
signal that returns \c false is to be expected even after delegating the
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index 8416abfdb..dbd645a83 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -249,22 +249,27 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QWebEngineCookieStore *client = m_profile->cookieStore();
QAtomicInt accessTested = 0;
- client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return true; });
+ QList<QPair<QUrl, QUrl>> resourceFirstParty;
+ client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) {
+ resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl));
+ ++accessTested;
+ return true;
+ });
HttpServer httpServer;
-
- if (!httpServer.start())
- QSKIP("Failed to start http server");
+ httpServer.setHostDomain(QString("sub.test.localhost"));
+ QVERIFY(httpServer.start());
QByteArray cookieRequestHeader;
connect(&httpServer, &HttpServer::newRequest, [&cookieRequestHeader](HttpReqRep *rr) {
- if (rr->requestPath().size() <= 1) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/test.html") {
cookieRequestHeader = rr->requestHeader(QByteArrayLiteral("Cookie"));
if (cookieRequestHeader.isEmpty())
rr->setResponseHeader(QByteArrayLiteral("Set-Cookie"), QByteArrayLiteral("Test=test"));
+ rr->setResponseBody("<head><link rel='icon' type='image/png' href='resources/Fav.png'/>"
+ "<title>Page with a favicon and an icon</title></head>"
+ "<body><img src='resources/Img.ico'></body>");
rr->sendResponse();
- } else {
- rr->sendResponse(404);
}
});
@@ -273,12 +278,13 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
QSignalSpy serverSpy(&httpServer, SIGNAL(newRequest(HttpReqRep *)));
- page.load(httpServer.url());
+ QUrl firstPartyUrl = httpServer.url("/test.html");
+ page.load(firstPartyUrl);
QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 3);
+ QTRY_COMPARE(accessTested.loadAcquire(), 4);
QVERIFY(cookieRequestHeader.isEmpty());
page.triggerAction(QWebEnginePage::Reload);
@@ -286,12 +292,16 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QVERIFY(!cookieRequestHeader.isEmpty());
QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 5);
+ QTRY_COMPARE(accessTested.loadAcquire(), 7);
client->deleteAllCookies();
QTRY_COMPARE(cookieRemovedSpy.count(), 1);
- client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return false; });
+ client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) {
+ resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl));
+ ++accessTested;
+ return false;
+ });
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
@@ -299,8 +309,7 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
// Test cookies are NOT added:
QTest::qWait(100);
QCOMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 8);
-
+ QTRY_COMPARE(accessTested.loadAcquire(), 11);
page.triggerAction(QWebEnginePage::Reload);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
@@ -308,8 +317,13 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QCOMPARE(cookieAddedSpy.count(), 1);
// Wait for last GET /favicon.ico
- QTRY_COMPARE(serverSpy.count(), 8);
+ QTRY_COMPARE(serverSpy.count(), 12);
(void) httpServer.stop();
+
+ QCOMPARE(resourceFirstParty.size(), accessTested.loadAcquire());
+ for (auto &&p : qAsConst(resourceFirstParty))
+ QVERIFY2(p.second == firstPartyUrl,
+ qPrintable(QString("Resource [%1] has wrong firstPartyUrl: %2").arg(p.first.toString(), p.second.toString())));
}
void tst_QWebEngineCookieStore::html5featureFilter()
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 090da3d6a..0d4e172ee 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -726,7 +726,7 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
QTRY_COMPARE(page->messages.count(), 1);
QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel);
- QUrl firstPartyUrl = QUrl(server.url().toString(QUrl::RemovePort));
+ QUrl firstPartyUrl = QUrl(server.url().toString() + "sw.js");
QList<RequestInfo> infos;
// Service Worker
QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker));
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
new file mode 100644
index 000000000..e5a575f06
--- /dev/null
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -0,0 +1,5 @@
+[CertificateError::test_error]
+macos
+
+[NewViewRequest::test_loadNewViewRequest]
+macos
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index 4840f474d..f82589f7d 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -104,7 +104,6 @@ WebEngineView {
}
TestResult { id: testResult }
- TestCase { id: testCase }
onLoadingChanged: function(load) {
loadStatus = load.status
diff --git a/tests/auto/quick/qmltests/data/test4.html b/tests/auto/quick/qmltests/data/test4.html
index c9b395ee5..cf5708994 100644
--- a/tests/auto/quick/qmltests/data/test4.html
+++ b/tests/auto/quick/qmltests/data/test4.html
@@ -24,6 +24,7 @@
}
</script>
<div id="content">
+ <p><a id='anchor' href='#anchor'>anchor</a>
<p>bla00
<p>bla01
<p>bla02
diff --git a/tests/auto/quick/qmltests/data/tst_action.qml b/tests/auto/quick/qmltests/data/tst_action.qml
index 852d4145a..91f260e0e 100644
--- a/tests/auto/quick/qmltests/data/tst_action.qml
+++ b/tests/auto/quick/qmltests/data/tst_action.qml
@@ -41,7 +41,7 @@ TestWebEngineView {
}
TestCase {
- id: actionTests
+ id: testCase
name: "WebEngineAction"
when: windowShown
@@ -116,8 +116,8 @@ TestWebEngineView {
var stopAction = webEngineView.action(WebEngineView.Stop);
verify(stopAction);
- var triggerSpy = createTemporaryObject(signalSpy, actionTests, {target: selectAction, signalName: "triggered"});
- var stopTriggerSpy = createTemporaryObject(signalSpy, actionTests, {target: stopAction, signalName: "triggered"});
+ var triggerSpy = createTemporaryObject(signalSpy, testCase, {target: selectAction, signalName: "triggered"});
+ var stopTriggerSpy = createTemporaryObject(signalSpy, testCase, {target: stopAction, signalName: "triggered"});
verify(selectAction.enabled);
selectAction.trigger();
@@ -148,7 +148,7 @@ TestWebEngineView {
compare(enabledSpy.count, 0);
selectAllAction.trigger();
compare(triggerSpy.count, 0);
- compare(getTextSelection(), "");
+ compare(webEngineView.getTextSelection(), "");
// Focus content by focusing window from JavaScript. Edit actions should be enabled and functional.
webView.runJavaScript("window.focus();");
@@ -157,6 +157,7 @@ TestWebEngineView {
selectAllAction.trigger();
compare(triggerSpy.count, 1);
tryVerify(function() { return webView.getTextSelection() === "foo bar" });
+ webView.destroy();
}
function test_editActionsWithInitialFocus() {
@@ -180,6 +181,7 @@ TestWebEngineView {
selectAllAction.trigger();
compare(triggerSpy.count, 1);
tryVerify(function() { return webView.getTextSelection() === "foo bar" });
+ webView.destroy();
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
index c360a1da2..83a2dc8c9 100644
--- a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
+++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
@@ -55,6 +55,7 @@ Item {
}
TestCase {
+ id: testCase
name: "ActiveFocusOnPress"
when:windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_audioMuted.qml b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
index c626d07a0..d0d9e35c3 100644
--- a/tests/auto/quick/qmltests/data/tst_audioMuted.qml
+++ b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
@@ -42,7 +42,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineViewAudioMuted"
function test_audioMuted() {
diff --git a/tests/auto/quick/qmltests/data/tst_certificateError.qml b/tests/auto/quick/qmltests/data/tst_certificateError.qml
index 976de88a9..d6c7edfd8 100644
--- a/tests/auto/quick/qmltests/data/tst_certificateError.qml
+++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml
@@ -45,6 +45,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: 'CertificateError'
when: windowShown
@@ -55,6 +56,7 @@ TestWebEngineView {
request.sendResponse()
})
view.settings.errorPageEnabled = false
+ view.profile.useForGlobalCertificateVerification = true
}
function init() {
diff --git a/tests/auto/quick/qmltests/data/tst_contextMenu.qml b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
index 99450a159..8493ba1c7 100644
--- a/tests/auto/quick/qmltests/data/tst_contextMenu.qml
+++ b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
@@ -65,12 +65,12 @@ TestWebEngineView {
}
function destroyContextMenu() {
- contextMenuTest.keyPress(Qt.Key_Escape);
+ testCase.keyPress(Qt.Key_Escape);
return getContextMenus().length == 0;
}
TestCase {
- id: contextMenuTest
+ id: testCase
name: "WebEngineViewContextMenu"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index 92c50876c..fc8b90542 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -59,16 +59,16 @@ TestWebEngineView {
function getFaviconPixel(faviconImage) {
var grabImage = Qt.createQmlObject("
import QtQuick 2.5\n
- Image { }", test)
+ Image { }", testCase)
var faviconCanvas = Qt.createQmlObject("
import QtQuick 2.5\n
- Canvas { }", test)
+ Canvas { }", testCase)
- test.tryVerify(function() { return faviconImage.status == Image.Ready });
+ testCase.tryVerify(function() { return faviconImage.status == Image.Ready });
faviconImage.grabToImage(function(result) {
grabImage.source = result.url
});
- test.tryVerify(function() { return grabImage.status == Image.Ready });
+ testCase.tryVerify(function() { return grabImage.status == Image.Ready });
faviconCanvas.width = faviconImage.width;
faviconCanvas.height = faviconImage.height;
@@ -97,7 +97,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineFavicon"
when: windowShown
@@ -315,7 +315,7 @@ TestWebEngineView {
function test_faviconProvider(row) {
var faviconImage = Qt.createQmlObject("
import QtQuick 2.5\n
- Image { sourceSize: Qt.size(width, height) }", test)
+ Image { sourceSize: Qt.size(width, height) }", testCase)
compare(iconChangedSpy.count, 0)
@@ -338,7 +338,7 @@ TestWebEngineView {
function test_dynamicFavicon() {
var faviconImage = Qt.createQmlObject("
import QtQuick 2.5\n
- Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", test)
+ Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", testCase)
faviconImage.source = Qt.binding(function() { return webEngineView.icon; });
var colors = [
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml
index 9aa32279c..7d9c39814 100644
--- a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml
+++ b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml
@@ -47,7 +47,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineFaviconDownload"
function init() {
diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml
index ab30d9e82..4313c8d9e 100644
--- a/tests/auto/quick/qmltests/data/tst_filePicker.qml
+++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml
@@ -58,6 +58,7 @@ TestWebEngineView {
onTitleChanged: { titleChanges.push(webEngineView.title) }
TestCase {
+ id: testCase
name: "WebEngineViewSingleFileUpload"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index c02a1348e..0b4a8d459 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -56,7 +56,7 @@ TestWebEngineView {
// If this starts to fail then either clear was not called before findText
// or unexpected callback was triggered from some search.
// On c++ side callback id can be checked to verify
- testcase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!')
+ testCase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!')
webEngineView.matchCount = matchCount
findFailed = matchCount == 0
@@ -64,7 +64,7 @@ TestWebEngineView {
TestCase {
- id: testcase
+ id: testCase
name: "WebViewFindText"
function getBodyInnerHTML() {
diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
index 93410a727..b2b7374f6 100644
--- a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
+++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
@@ -65,6 +65,7 @@ Item {
}
TestCase {
+ id: testCase
name: "WebEngineViewFocusOnNavigation"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_inputMethod.qml b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
index 0bf9f7eb0..00f85cb71 100644
--- a/tests/auto/quick/qmltests/data/tst_inputMethod.qml
+++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
@@ -40,6 +40,7 @@ TestWebEngineView {
testSupport: WebEngineTestSupport { }
TestCase {
+ id: testCase
name: "WebEngineViewInputMethod"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
index 2536f319b..136863c4c 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
@@ -36,6 +36,7 @@ TestWebEngineView {
height: 480
TestCase {
+ id: testCase
name: "WebEngineViewKeyboardEvents"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml
index 8a46afbad..c27ae8b0f 100644
--- a/tests/auto/quick/qmltests/data/tst_loadFail.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml
@@ -119,21 +119,22 @@ TestWebEngineView {
verify(!loadRequest.isErrorPage)
// Loading of the unavailableUrl must fail
- loadRequest = loadRequestArray[1]
+ loadRequest = loadRequestArray[3]
compare(loadRequest.status, WebEngineView.LoadFailedStatus)
compare(loadRequest.errorDomain, WebEngineView.InternalErrorDomain)
compare(loadRequest.url, unavailableUrl)
verify(!loadRequest.isErrorPage)
+ // error page load is done inside main load through test support
// Start to load error page
- loadRequest = loadRequestArray[2]
+ loadRequest = loadRequestArray[1]
compare(loadRequest.status, WebEngineView.LoadStartedStatus)
compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain)
compare(loadRequest.url, "chrome-error://chromewebdata/")
verify(loadRequest.isErrorPage)
// Loading of the error page must be successful
- loadRequest = loadRequestArray[3]
+ loadRequest = loadRequestArray[2]
compare(loadRequest.status, WebEngineView.LoadSucceededStatus)
compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain)
compare(loadRequest.url, "chrome-error://chromewebdata/")
diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
index ed1de41fd..6ed9a4317 100644
--- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
@@ -42,6 +42,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: "WebEngineViewLoadHtml"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 817a28637..b60a00faf 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -52,6 +52,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: "WebEngineViewLoadUrl"
when: windowShown
@@ -298,20 +299,19 @@ TestWebEngineView {
compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus);
compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
- // In-page navigation.
- webEngineView.url = Qt.resolvedUrl("test4.html#content");
- // In-page navigation doesn't trigger load succeeded, wait for load progress instead.
- tryCompare(loadRequestArray, "length", 3);
- tryCompare(webEngineView, "loadProgress", 100);
- compare(loadRequestArray[2].status, WebEngineView.LoadStartedStatus);
+ // In-page navigation shouldn't trigger load
+ let anchorUrl = Qt.resolvedUrl("test4.html#anchor");
+ let c = webEngineView.getElementCenter('anchor')
+ mouseClick(webEngineView, c.x, c.y)
+ tryCompare(webEngineView, 'url', anchorUrl)
// Load after in-page navigation.
webEngineView.url = Qt.resolvedUrl("test4.html");
verify(webEngineView.waitForLoadSucceeded());
compare(webEngineView.loadProgress, 100);
- compare(loadRequestArray.length, 5);
- compare(loadRequestArray[3].status, WebEngineView.LoadStartedStatus);
- compare(loadRequestArray[4].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray.length, 4);
+ compare(loadRequestArray[2].status, WebEngineView.LoadStartedStatus);
+ compare(loadRequestArray[3].status, WebEngineView.LoadSucceededStatus);
webEngineView.clear();
}
diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
index eaa012f86..6c314d44c 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
@@ -65,6 +65,7 @@ TestWebEngineView {
TestCase {
+ id: testCase
name: "WebEngineViewMouseClick"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
index 96128574e..a24b8f0d4 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
@@ -79,6 +79,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: "WebEngineViewNavigationRequested"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index cce657f81..fd720befe 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -77,7 +77,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "NewViewRequest"
when: windowShown
@@ -158,7 +158,7 @@ TestWebEngineView {
" <button id='popupButton' onclick='popup()'>Pop Up!</button>" +
"</body></html>");
verify(webEngineView.waitForLoadSucceeded());
- verifyElementHasFocus("popupButton");
+ webEngineView.verifyElementHasFocus("popupButton");
keyPress(Qt.Key_Enter);
tryCompare(newViewRequestedSpy, "count", 1);
compare(newViewRequest.requestedUrl, url);
@@ -176,7 +176,7 @@ TestWebEngineView {
compare(loadRequestArray.length, 0);
webEngineView.url = Qt.resolvedUrl("test2.html");
verify(webEngineView.waitForLoadSucceeded());
- var center = getElementCenter("link");
+ var center = webEngineView.getElementCenter("link");
mouseClick(webEngineView, center.x, center.y, Qt.LeftButton, Qt.ControlModifier);
tryCompare(newViewRequestedSpy, "count", 1);
compare(newViewRequest.requestedUrl, Qt.resolvedUrl("test1.html"));
diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml
index 2ff4f9c3c..b286a1dae 100644
--- a/tests/auto/quick/qmltests/data/tst_settings.qml
+++ b/tests/auto/quick/qmltests/data/tst_settings.qml
@@ -36,6 +36,7 @@ TestWebEngineView {
height: 300
TestCase {
+ id: testCase
name: "WebEngineViewSettings"
function test_javascriptEnabled() {
@@ -75,7 +76,7 @@ TestWebEngineView {
}
function test_settingsAffectCurrentViewOnly() {
- var webEngineView2 = Qt.createQmlObject('TestWebEngineView {width: 400; height: 300;}', webEngineView);
+ var webEngineView2 = Qt.createQmlObject('TestWebEngineView {width: 400; height: 300;}', testCase);
webEngineView.settings.javascriptEnabled = true;
webEngineView2.settings.javascriptEnabled = true;
diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
index 69aa76b77..5e163fc64 100644
--- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
+++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
@@ -46,6 +46,7 @@ Item {
focus: true
}
TestCase {
+ id: testCase
name: "WebEngineViewUnhandledKeyEventPropagation"
when: false
diff --git a/tests/auto/quick/qmltests/data/tst_viewSoure.qml b/tests/auto/quick/qmltests/data/tst_viewSoure.qml
index 870f6ee7b..1ee687f34 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSoure.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSoure.qml
@@ -44,6 +44,7 @@ TestWebEngineView {
errorPage.onLoadingChanged: function(load) {
loadRequestArray.push({
"status": load.status,
+ "url": load.url
})
}
}
@@ -51,6 +52,7 @@ TestWebEngineView {
onLoadingChanged: function(load) {
loadRequestArray.push({
"status": load.status,
+ "url": load.url
});
}
@@ -76,7 +78,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineViewSource"
function init() {
@@ -109,14 +111,16 @@ TestWebEngineView {
WebEngine.settings.errorPageEnabled = true
webEngineView.url = row.userInputUrl;
+
if (row.loadSucceed) {
- tryVerify(function() { return loadRequestArray.length >= 2 });
+ tryVerify(function() { return loadRequestArray.length == 2 });
compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
} else {
- tryVerify(function() { return loadRequestArray.length >= 2 });
- compare(loadRequestArray[1].status, WebEngineView.LoadFailedStatus);
- tryVerify(function() { return loadRequestArray.length == 4 });
- compare(loadRequestArray[3].status, WebEngineView.LoadSucceededStatus);
+ tryVerify(function() { return loadRequestArray.length == 4 }, 90000);
+ // error page load is done inside main load through test support
+ compare(loadRequestArray[2].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray[2].url, "chrome-error://chromewebdata/")
+ compare(loadRequestArray[3].status, WebEngineView.LoadFailedStatus);
}
tryVerify(function() { return titleChangedSpy.count == 1; });
diff --git a/tests/auto/shared/data/loadprogress/page1.html b/tests/auto/shared/data/loadprogress/page1.html
index 5cd479ab6..9b11ce887 100644
--- a/tests/auto/shared/data/loadprogress/page1.html
+++ b/tests/auto/shared/data/loadprogress/page1.html
@@ -3,6 +3,6 @@
<title>page1</title>
</head>
<body>
- <h1>page1</h1>
+ <div><a href="page2.html#anchor">page2</a></div>
</body>
</html>
diff --git a/tests/auto/shared/data/loadprogress/page2.html b/tests/auto/shared/data/loadprogress/page2.html
index e3031f56a..223817c8c 100644
--- a/tests/auto/shared/data/loadprogress/page2.html
+++ b/tests/auto/shared/data/loadprogress/page2.html
@@ -9,6 +9,7 @@
}
</style>
<body>
+ <div><a href="#anchor">page2</a></div>
<div class="fardown" id="anchor">page2 anchor</div>
</body>
</html>
diff --git a/tests/auto/shared/data/loadprogress/page5.html b/tests/auto/shared/data/loadprogress/page5.html
new file mode 100644
index 000000000..47709ff08
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page5.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>page5</title>
+ </head>
+ <script>
+ addEventListener('DOMContentLoaded', (event) => {
+ document.getElementById('anchorLink').click();
+ });
+ </script>
+ <style>
+ .fardown {
+ position: absolute;
+ top: 2500px;
+ }
+ </style>
+ <body>
+ <div><a id="anchorLink" href="#anchor">go to the anchor</a></div>
+ <div class="fardown" id="anchor">here is the anchor</div>
+ </body>
+</html>
diff --git a/tests/auto/shared/data/loadprogress/page6.html b/tests/auto/shared/data/loadprogress/page6.html
new file mode 100644
index 000000000..98042701a
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page6.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>page6</title>
+ </head>
+ <script>
+ addEventListener('DOMContentLoaded', (event) => {
+ document.getElementById('anchorLink').click();
+ });
+ </script>
+ <body>
+ <div><a id="anchorLink" href="page2.html#anchor">go to another page</a></div>
+ </body>
+</html>
diff --git a/tests/auto/shared/data/loadprogress/page7.html b/tests/auto/shared/data/loadprogress/page7.html
new file mode 100644
index 000000000..42538c5de
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page7.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>page6</title>
+ </head>
+ <script>
+ setTimeout(function(){
+ document.getElementById('anchorLink').click();
+ },500);
+ </script>
+ <body>
+ <div><a id="anchorLink" href="page2.html#anchor">go to another page</a></div>
+ </body>
+</html>
diff --git a/tests/auto/shared/data/loadprogress/page8.html b/tests/auto/shared/data/loadprogress/page8.html
new file mode 100644
index 000000000..8ebdddf97
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page8.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>Page with js navigation in the end of document to anchor within the page</title>
+ </head>
+ <style>
+ .fardown {
+ position: absolute;
+ top: 2500px;
+ }
+ </style>
+ <body>
+ <div><a id="anchorLink" href="#anchor">go to the anchor</a></div>
+ <div class="fardown" id="anchor">here is the anchor</div>
+ <script>
+ addEventListener('load', (event) => {
+ window.location.replace(document.getElementById('anchorLink').href)
+ })
+ </script>
+ </body>
+</html>
diff --git a/tests/auto/shared/httpserver.h b/tests/auto/shared/httpserver.h
index 952ead220..3ec69f8ed 100644
--- a/tests/auto/shared/httpserver.h
+++ b/tests/auto/shared/httpserver.h
@@ -78,6 +78,8 @@ public:
Q_INVOKABLE void setResourceDirs(const QStringList &dirs) { m_dirs = dirs; }
+ Q_INVOKABLE void setHostDomain(const QString &host) { m_url.setHost(host); }
+
Q_SIGNALS:
// Emitted after a HTTP request has been successfully parsed.
void newRequest(HttpReqRep *reqRep);
diff --git a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
index 063a53ae2..9865162cb 100644
--- a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
+++ b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
@@ -30,6 +30,7 @@
#include <QWebEngineCertificateError>
#include <QWebEnginePage>
+#include <QWebEngineProfile>
#include <QWebEngineSettings>
#include <QtTest/QtTest>
@@ -128,6 +129,7 @@ void tst_CertificateError::handleError()
void tst_CertificateError::fatalError()
{
PageWithCertificateErrorHandler page(false, false);
+ page.profile()->setUseForGlobalCertificateVerification();
page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
diff --git a/tests/auto/widgets/loadsignals/BLACKLIST b/tests/auto/widgets/loadsignals/BLACKLIST
deleted file mode 100644
index e5c625bd6..000000000
--- a/tests/auto/widgets/loadsignals/BLACKLIST
+++ /dev/null
@@ -1,17 +0,0 @@
-[secondLoadForError_WhenErrorPageEnabled:ErrorPageEnabled]
-*
-
-# QTBUG-65223
-[loadStartedAndFinishedCount:WithAnchorClickedFromJS]
-*
-
-# QTBUG-66869 (https://codereview.qt-project.org/#/c/222112/ is only a workaround)
-[loadAfterInPageNavigation_qtbug66869]
-*
-
-# QTBUG-66661
-[fileDownloadDoesNotTriggerLoadSignals_qtbug66661]
-*
-
-[numberOfStartedAndFinishedSignalsIsSame]
-b2qt
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
index b5140ec89..a0fa97e02 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
@@ -36,6 +36,43 @@
#include "qwebenginesettings.h"
#include "qwebengineview.h"
+enum { LoadStarted, LoadSucceeded, LoadFailed };
+static const QList<int> SignalsOrderOnce({ LoadStarted, LoadSucceeded});
+static const QList<int> SignalsOrderTwice({ LoadStarted, LoadSucceeded, LoadStarted, LoadSucceeded });
+static const QList<int> SignalsOrderOnceFailure({ LoadStarted, LoadFailed });
+static const QList<int> SignalsOrderTwiceWithFailure({ LoadStarted, LoadSucceeded, LoadStarted, LoadFailed });
+
+class TestPage : public QWebEnginePage
+{
+public:
+ QSet<QUrl> blacklist;
+ int navigationRequestCount = 0;
+ QList<int> signalsOrder;
+ QList<int> loadProgress;
+
+ explicit TestPage(QObject *parent = nullptr) : TestPage(nullptr, parent) { }
+ TestPage(QWebEngineProfile *profile, QObject *parent = nullptr) : QWebEnginePage(profile, parent) {
+ connect(this, &QWebEnginePage::loadStarted, [this] () { signalsOrder.append(LoadStarted); });
+ connect(this, &QWebEnginePage::loadProgress, [this] (int p) { loadProgress.append(p); });
+ connect(this, &QWebEnginePage::loadFinished, [this] (bool r) { signalsOrder.append(r ? LoadSucceeded : LoadFailed); });
+ }
+
+ void reset()
+ {
+ blacklist.clear();
+ navigationRequestCount = 0;
+ signalsOrder.clear();
+ loadProgress.clear();
+ }
+
+protected:
+ bool acceptNavigationRequest(const QUrl &url, NavigationType, bool) override
+ {
+ ++navigationRequestCount;
+ return !blacklist.contains(url);
+ }
+};
+
class tst_LoadSignals : public QObject
{
Q_OBJECT
@@ -48,10 +85,13 @@ private Q_SLOTS:
void monotonicity();
void loadStartedAndFinishedCount_data();
void loadStartedAndFinishedCount();
- void secondLoadForError_WhenErrorPageEnabled_data();
- void secondLoadForError_WhenErrorPageEnabled();
+ void loadStartedAndFinishedCountClick_data();
+ void loadStartedAndFinishedCountClick();
+ void rejectNavigationRequest_data();
+ void rejectNavigationRequest();
void loadAfterInPageNavigation_qtbug66869();
- void fileDownloadDoesNotTriggerLoadSignals_qtbug66661();
+ void fileDownload();
+ void numberOfStartedAndFinishedSignalsIsSame_data();
void numberOfStartedAndFinishedSignalsIsSame();
void loadFinishedAfterNotFoundError_data();
void loadFinishedAfterNotFoundError();
@@ -59,31 +99,45 @@ private Q_SLOTS:
void errorPageTriggered();
private:
+ void clickLink(QPoint linkPos);
+
QWebEngineProfile profile;
- QWebEnginePage page{&profile};
+ TestPage page{&profile};
QWebEngineView view;
QSignalSpy loadStartedSpy{&page, &QWebEnginePage::loadStarted};
- QSignalSpy loadProgressSpy{&page, &QWebEnginePage::loadProgress};
QSignalSpy loadFinishedSpy{&page, &QWebEnginePage::loadFinished};
+ void resetSpies() {
+ loadStartedSpy.clear();
+ loadFinishedSpy.clear();
+ }
};
void tst_LoadSignals::initTestCase()
{
view.setPage(&page);
- view.resize(1024,768);
+ view.resize(640, 480);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
}
void tst_LoadSignals::init()
{
// Reset content
- loadFinishedSpy.clear();
- view.load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ if (!view.url().isEmpty()) {
+ loadFinishedSpy.clear();
+ view.load(QUrl("about:blank"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ }
+ resetSpies();
+ page.reset();
+}
- loadStartedSpy.clear();
- loadProgressSpy.clear();
- loadFinishedSpy.clear();
+void tst_LoadSignals::clickLink(QPoint linkPos)
+{
+ // Simulate left-clicking on link.
+ QTRY_VERIFY(view.focusWidget());
+ QWidget *renderWidget = view.focusWidget();
+ QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos);
}
/**
@@ -92,27 +146,124 @@ void tst_LoadSignals::init()
void tst_LoadSignals::loadStartedAndFinishedCount_data()
{
QTest::addColumn<QUrl>("url");
- QTest::addColumn<int>("expectedLoadCount");
- QTest::newRow("Normal") << QUrl("qrc:///resources/page1.html") << 1;
- QTest::newRow("WithAnchor") << QUrl("qrc:///resources/page2.html#anchor") << 1;
-
- // In this case, we get an unexpected additional loadStarted, but no corresponding
- // loadFinished, so expectedLoadCount=2 would also not work. See also QTBUG-65223
- QTest::newRow("WithAnchorClickedFromJS") << QUrl("qrc:///resources/page3.html") << 1;
+ QTest::addColumn<QList<int>>("expectedSignals");
+ QTest::newRow("Simple") << QUrl("qrc:///resources/page1.html") << SignalsOrderOnce;
+ QTest::newRow("SimpleWithAnchor") << QUrl("qrc:///resources/page2.html#anchor") << SignalsOrderOnce;
+ QTest::newRow("SamePageImmediate") << QUrl("qrc:///resources/page5.html") << SignalsOrderOnce;
+ QTest::newRow("SamePageDeferred") << QUrl("qrc:///resources/page3.html") << SignalsOrderOnce;
+ QTest::newRow("OtherPageImmediate") << QUrl("qrc:///resources/page6.html") << SignalsOrderOnce;
+ QTest::newRow("OtherPageDeferred") << QUrl("qrc:///resources/page7.html") << SignalsOrderTwice;
+ QTest::newRow("SamePageImmediateJS") << QUrl("qrc:///resources/page8.html") << SignalsOrderOnce;
}
void tst_LoadSignals::loadStartedAndFinishedCount()
{
QFETCH(QUrl, url);
- QFETCH(int, expectedLoadCount);
+ QFETCH(QList<int>, expectedSignals);
view.load(url);
+
+ int expectedLoadCount = expectedSignals.size() / 2;
+ QTRY_COMPARE(loadStartedSpy.size(), expectedLoadCount);
QTRY_COMPARE(loadFinishedSpy.size(), expectedLoadCount);
+
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != expectedLoadCount || loadFinishedSpy.size() != expectedLoadCount, 1000, 100);
+
+ // No further signals should have occurred within this time and expected number of signals is preserved
+ QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
+ QCOMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.signalsOrder, expectedSignals);
+}
+
+/**
+ * Load a URL, then simulate a click to load a different URL.
+ */
+void tst_LoadSignals::loadStartedAndFinishedCountClick_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<int>("numberOfSignals");
+ QTest::newRow("SamePage") << QUrl("qrc:///resources/page2.html") << 0; // in-page navigation to anchor shouldn't emit anything
+ QTest::newRow("OtherPage") << QUrl("qrc:///resources/page1.html") << 1;
+}
+
+void tst_LoadSignals::loadStartedAndFinishedCountClick()
+{
+ QFETCH(QUrl, url);
+ QFETCH(int, numberOfSignals);
+
+ view.load(url);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(loadFinishedSpy[0][0].toBool());
+ resetSpies();
+
+ clickLink(QPoint(10, 10));
+ if (numberOfSignals > 0) {
+ QTRY_COMPARE(loadStartedSpy.size(), numberOfSignals);
+ QTRY_COMPARE(loadFinishedSpy.size(), numberOfSignals);
+ QVERIFY(loadFinishedSpy[0][0].toBool());
+ }
+
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != numberOfSignals || loadFinishedSpy.size() != numberOfSignals, 1000, 100);
+
+ // No further loadStarted should have occurred within this time
+ QCOMPARE(loadStartedSpy.size(), numberOfSignals);
+ QCOMPARE(loadFinishedSpy.size(), numberOfSignals);
+ QCOMPARE(page.signalsOrder, numberOfSignals > 0 ? SignalsOrderTwice : SignalsOrderOnce);
+}
+
+void tst_LoadSignals::rejectNavigationRequest_data()
+{
+ QTest::addColumn<QUrl>("initialUrl");
+ QTest::addColumn<QUrl>("rejectedUrl");
+ QTest::addColumn<int>("expectedNavigations");
+ QTest::addColumn<QList<int>>("expectedSignals");
+ QTest::newRow("Simple")
+ << QUrl("qrc:///resources/page1.html")
+ << QUrl("qrc:///resources/page1.html")
+ << 1 << SignalsOrderOnceFailure;
+ QTest::newRow("SamePageImmediate")
+ << QUrl("qrc:///resources/page5.html")
+ << QUrl("qrc:///resources/page5.html#anchor")
+ << 1 << SignalsOrderOnce;
+ QTest::newRow("SamePageDeferred")
+ << QUrl("qrc:///resources/page3.html")
+ << QUrl("qrc:///resources/page3.html#anchor")
+ << 1 << SignalsOrderOnce;
+ QTest::newRow("OtherPageImmediate")
+ << QUrl("qrc:///resources/page6.html")
+ << QUrl("qrc:///resources/page2.html#anchor")
+ << 2 << SignalsOrderOnceFailure;
+ QTest::newRow("OtherPageDeferred")
+ << QUrl("qrc:///resources/page7.html")
+ << QUrl("qrc:///resources/page2.html#anchor")
+ << 2 << SignalsOrderTwiceWithFailure;
+}
- // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs)
- QTRY_LOOP_IMPL((loadStartedSpy.size() != expectedLoadCount)
- || (loadFinishedSpy.size() != expectedLoadCount), 10000, 100);
+/**
+ * Returning false from acceptNavigationRequest means that the load
+ * fails, not that the load never starts.
+ *
+ * See QTBUG-75185.
+ */
+void tst_LoadSignals::rejectNavigationRequest()
+{
+ QFETCH(QUrl, initialUrl);
+ QFETCH(QUrl, rejectedUrl);
+ QFETCH(int, expectedNavigations);
+ QFETCH(QList<int>, expectedSignals);
+
+ page.blacklist.insert(rejectedUrl);
+ page.load(initialUrl);
+ QTRY_COMPARE(page.navigationRequestCount, expectedNavigations);
+ int expectedLoadCount = expectedSignals.size() / 2;
+ QTRY_COMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.signalsOrder, expectedSignals);
+
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != expectedLoadCount || loadFinishedSpy.size() != expectedLoadCount, 1000, 100);
// No further loadStarted should have occurred within this time
QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
@@ -135,53 +286,19 @@ void tst_LoadSignals::monotonicity()
QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(loadFinishedSpy[0][0].toBool());
+ QVERIFY(page.loadProgress.size() >= 3);
// first loadProgress should have 0% progress
- QCOMPARE(loadProgressSpy.takeFirst()[0].toInt(), 0);
+ QCOMPARE(page.loadProgress.first(), 0);
// every loadProgress should have more progress than the one before
- int progress = 0;
- for (const auto &item : loadProgressSpy) {
- QVERIFY(progress < item[0].toInt());
- progress = item[0].toInt();
+ int progress = -1;
+ for (int p : page.loadProgress) {
+ QVERIFY(progress < p);
+ progress = p;
}
// last loadProgress should have 100% progress
- QCOMPARE(loadProgressSpy.last()[0].toInt(), 100);
-}
-
-/**
- * Test that we get a second loadStarted and loadFinished signal
- * for error-pages (unless error-pages are disabled)
- */
-void tst_LoadSignals::secondLoadForError_WhenErrorPageEnabled_data()
-{
- QTest::addColumn<bool>("enabled");
- // in this case, we get no second loadStarted and loadFinished, although we had
- // agreed on making the navigation to an error page an individual load
- QTest::newRow("ErrorPageEnabled") << true;
- QTest::newRow("ErrorPageDisabled") << false;
-}
-
-void tst_LoadSignals::secondLoadForError_WhenErrorPageEnabled()
-{
- QFETCH(bool, enabled);
- view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enabled);
- int expectedLoadCount = (enabled ? 2 : 1);
-
- // RFC 2606 guarantees that this will never become a valid domain
- view.load(QUrl("http://nonexistent.invalid"));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), expectedLoadCount, 10000);
- QVERIFY(!loadFinishedSpy[0][0].toBool());
- if (enabled)
- QVERIFY(loadFinishedSpy[1][0].toBool());
-
- // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs)
- QTRY_LOOP_IMPL((loadStartedSpy.size() != expectedLoadCount)
- || (loadFinishedSpy.size() != expectedLoadCount), 10000, 100);
-
- // No further loadStarted should have occurred within this time
- QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
- QCOMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.loadProgress.last(), 100);
}
/**
@@ -195,27 +312,17 @@ void tst_LoadSignals::loadAfterInPageNavigation_qtbug66869()
QVERIFY(loadFinishedSpy[0][0].toBool());
// page3 does an in-page navigation after 500ms
- QTest::qWait(2000);
- loadFinishedSpy.clear();
- loadProgressSpy.clear();
- loadStartedSpy.clear();
+ QTRY_COMPARE(view.url(), QUrl("qrc:///resources/page3.html#anchor"));
// second load
view.load(QUrl("qrc:///resources/page1.html"));
- QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 2);
QVERIFY(loadFinishedSpy[0][0].toBool());
// loadStarted and loadFinished should have been signalled
- QCOMPARE(loadStartedSpy.size(), 1);
-
- // reminder that we still need to solve the core issue
- QFAIL("https://codereview.qt-project.org/#/c/222112/ only hides the symptom, the core issue still needs to be solved");
+ QCOMPARE(loadStartedSpy.size(), 2);
}
-/**
- * Test that file-downloads don't trigger loadStarted or loadFinished signals.
- * See QTBUG-66661
- */
-void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661()
+void tst_LoadSignals::fileDownload()
{
view.load(QUrl("qrc:///resources/page4.html"));
QTRY_COMPARE(loadFinishedSpy.size(), 1);
@@ -237,59 +344,55 @@ void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661()
});
// trigger the download link that becomes focused on page4
- QTest::qWait(1000);
QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
- // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs)
- QTRY_LOOP_IMPL((loadStartedSpy.size() != 1)
- || (loadFinishedSpy.size() != 1), 10000, 100);
-
// Download must have occurred
QTRY_COMPARE(downloadState, QWebEngineDownloadRequest::DownloadCompleted);
+ QTRY_COMPARE(loadFinishedSpy.size() + loadStartedSpy.size(), 4);
- // No further loadStarted should have occurred within this time
- QCOMPARE(loadStartedSpy.size(), 1);
- QCOMPARE(loadFinishedSpy.size(), 1);
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != 2 || loadFinishedSpy.size() != 2, 1000, 100);
+
+ QCOMPARE(page.signalsOrder, SignalsOrderTwiceWithFailure);
}
-void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame() {
+void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame_data()
+{
+ QTest::addColumn<bool>("imageFromServer");
+ QTest::addColumn<QString>("imageResourceUrl");
+ // triggers these calls in delegate internally:
+ // just two ordered triples DidStartNavigation/DidFinishNavigation/DidFinishLoad
+ QTest::newRow("no_image_resource") << false << "";
+ // out of order: DidStartNavigation/DidFinishNavigation/DidStartNavigation/DidFailLoad/DidFinishNavigation/DidFinishLoad
+ QTest::newRow("with_invalid_image") << false << "https://non.existent.locahost/image.png";
+ // out of order: DidStartNavigation/DidFinishNavigation/DidStartNavigation/DidFinishLoad/DidFinishNavigation/DidFinishLoad
+ QTest::newRow("with_server_image") << true << "";
+}
+
+void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame()
+{
+ QFETCH(bool, imageFromServer);
+ QFETCH(QString, imageResourceUrl);
HttpServer server;
server.setResourceDirs({ TESTS_SOURCE_DIR "/qwebengineprofile/resources" });
- connect(&server, &HttpServer::newRequest, [] (HttpReqRep *) {
- QTest::qWait(250); // just add delay to trigger some progress for every sub resource
- });
QVERIFY(server.start());
- view.load(server.url("/hedgehog.png"));
- QTRY_COMPARE(loadFinishedSpy.size(), 1);
- QVERIFY(loadFinishedSpy[0][0].toBool());
-
- loadStartedSpy.clear();
- loadFinishedSpy.clear();
- loadProgressSpy.clear();
-
- view.page()->setHtml("<html><body>"
- "<img src=\"" + server.url("/hedgehog.png").toEncoded() + "\">"
- "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />"
- "<script language='javascript'>document.forms[0].submit();</script>"
- "</body></html>");
+ QUrl serverImage = server.url("/hedgehog.png");
+ QString imageUrl(!imageFromServer && imageResourceUrl.isEmpty()
+ ? "" : (imageFromServer ? serverImage.toEncoded() : imageResourceUrl));
- QTRY_COMPARE(loadStartedSpy.size(), 2);
- QTRY_COMPARE(loadFinishedSpy.size(), 2);
+ auto html = "<html><head><link rel='icon' href='data:,'></head><body>"
+ "%1" "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />"
+ "<script language='javascript'>document.forms[0].submit();</script>"
+ "</body></html>";
+ view.page()->setHtml(QString(html).arg(imageUrl.isEmpty() ? "" : "<img src='" + imageUrl + "'>"));
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
- QTRY_VERIFY(!loadFinishedSpy[0][0].toBool());
- QTRY_VERIFY(loadFinishedSpy[1][0].toBool());
-
- view.page()->setHtml("<html><body>"
- "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />"
- "<script language='javascript'>document.forms[0].submit();</script>"
- "</body></html>");
- QTRY_COMPARE(loadStartedSpy.size(), 4);
- QTRY_COMPARE(loadFinishedSpy.size(), 4);
- QVERIFY(loadFinishedSpy[2][0].toBool());
- QVERIFY(loadFinishedSpy[3][0].toBool());
+ resetSpies();
+ QTRY_LOOP_IMPL(loadStartedSpy.size() || loadFinishedSpy.size(), 1000, 100);
+ QCOMPARE(page.signalsOrder, SignalsOrderOnce);
}
void tst_LoadSignals::loadFinishedAfterNotFoundError_data()
@@ -311,7 +414,6 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError()
server.reset(new HttpServer);
QVERIFY(server->start());
}
-
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
auto url = server
? server->url("/not-found-page.html")
@@ -321,6 +423,9 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError()
QVERIFY(!loadFinishedSpy.at(0).at(0).toBool());
QCOMPARE(toPlainTextSync(view.page()), QString());
QCOMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadStartedSpy.count(), 1);
+ QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
+ page.loadProgress.clear();
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
url = server
@@ -329,9 +434,12 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError()
view.load(url);
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 2, 20000);
QVERIFY(!loadFinishedSpy.at(1).at(0).toBool());
+ QCOMPARE(loadStartedSpy.count(), 2);
QEXPECT_FAIL("", "No more loads (like separate load for error pages) are expected", Continue);
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 1000);
+ QCOMPARE(loadStartedSpy.count(), 2);
+ QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
}
void tst_LoadSignals::errorPageTriggered_data()
@@ -388,6 +496,5 @@ void tst_LoadSignals::errorPageTriggered()
loadFinishedSpy.clear();
}
-
QTEST_MAIN(tst_LoadSignals)
#include "tst_loadsignals.moc"
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.qrc b/tests/auto/widgets/loadsignals/tst_loadsignals.qrc
index 21c517154..b4ee36676 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.qrc
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.qrc
@@ -4,6 +4,10 @@
<file alias="page2.html">../../shared/data/loadprogress/page2.html</file>
<file alias="page3.html">../../shared/data/loadprogress/page3.html</file>
<file alias="page4.html">../../shared/data/loadprogress/page4.html</file>
+ <file alias="page5.html">../../shared/data/loadprogress/page5.html</file>
+ <file alias="page6.html">../../shared/data/loadprogress/page6.html</file>
+ <file alias="page7.html">../../shared/data/loadprogress/page7.html</file>
+ <file alias="page8.html">../../shared/data/loadprogress/page8.html</file>
<file alias="downloadable.tar.gz">../../shared/data/loadprogress/downloadable.tar.gz</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/qwebenginepage/resources/redirect.html b/tests/auto/widgets/qwebenginepage/resources/redirect.html
new file mode 100644
index 000000000..db06d73a7
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/redirect.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<script>
+function doRedirect() { location.replace('qrc:///resources/content.html') }
+document.addEventListener("DOMContentLoaded", doRedirect)
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 644d0f319..a8d0e1ac8 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -599,6 +599,39 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
<< QWebEnginePage::NavigationTypeReload
<< QWebEnginePage::NavigationTypeTyped
<< QWebEnginePage::NavigationTypeRedirect;
+
+ // client side redirect
+ page.load(QUrl("qrc:///resources/redirect.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 7, 20000);
+ QTRY_COMPARE(page.navigations.count(), 8);
+ expectedList += { QWebEnginePage::NavigationTypeTyped, QWebEnginePage::NavigationTypeRedirect };
+
+ // server side redirect
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ connect(&server, &HttpServer::newRequest, &server, [&] (HttpReqRep *r) {
+ if (r->requestMethod() == "GET") {
+ if (r->requestPath() == "/redirect1.html") {
+ r->setResponseHeader("Location", server.url("/redirect2.html").toEncoded());
+ r->setResponseBody("<html><body>Redirect1</body></html>");
+ r->sendResponse(307); // Internal server redirect
+ } else if (r->requestPath() == "/redirect2.html") {
+ r->setResponseHeader("Location", server.url("/content.html").toEncoded());
+ r->setResponseBody("<html><body>Redirect2</body></html>");
+ r->sendResponse(301); // Moved permanently
+ }
+ }
+ });
+ QVERIFY(server.start());
+ page.load(QUrl(server.url("/redirect1.html")));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 8, 20000);
+ QTRY_COMPARE(page.navigations.count(), 11);
+ expectedList += {
+ QWebEnginePage::NavigationTypeTyped,
+ QWebEnginePage::NavigationTypeRedirect,
+ QWebEnginePage::NavigationTypeRedirect
+ };
+
QVERIFY(expectedList.count() == page.navigations.count());
for (int i = 0; i < expectedList.count(); ++i) {
QCOMPARE(page.navigations[i].type, expectedList[i]);
@@ -2913,11 +2946,7 @@ void tst_QWebEnginePage::loadInSignalHandlers()
URLSetter setter(m_page, signal, type, urlForSetter);
QSignalSpy spy(&setter, &URLSetter::finished);
m_page->load(url);
- // every loadStarted() call should have also loadFinished()
- if (signal == URLSetter::LoadStarted)
- QTRY_COMPARE(spy.count(), 2);
- else
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.count(), 1);
QCOMPARE(m_page->url(), urlForSetter);
}
@@ -4068,8 +4097,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 2, 90000);
- QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(false));
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// keep DevTools open
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index 013a307de..3480341e8 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -14,6 +14,7 @@
<file>resources/user.css</file>
<file>resources/image.png</file>
<file>resources/pasteimage.html</file>
+ <file>resources/redirect.html</file>
<file>resources/reload.html</file>
<file>resources/style.css</file>
<file>resources/test1.html</file>
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index 05ebee4ce..c1a46e16d 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -6,3 +6,6 @@ windows
[horizontalScrollbarTest]
osx
+
+[mixLangLocale:eu_ES]
+*
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 7af08dbde..284f84d9f 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -124,6 +124,7 @@ private Q_SLOTS:
void doNotBreakLayout();
void changeLocale();
+ void mixLangLocale_data();
void mixLangLocale();
void inputMethodsTextFormat_data();
void inputMethodsTextFormat();
@@ -1213,26 +1214,46 @@ void tst_QWebEngineView::changeLocale()
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
+void tst_QWebEngineView::mixLangLocale_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QByteArray>("formattedNumber");
+ QTest::newRow("en_DK") << "en-DK" << QByteArray("1.234.567.890");
+ QTest::newRow("de") << "de" << QByteArray("1.234.567.890");
+ QTest::newRow("de_CH") << "de-CH" << QByteArray("1’234’567’890");
+ QTest::newRow("eu_ES") << "eu-ES" << QByteArray("1.234.567.890");
+ QTest::newRow("hu_HU") << "hu-HU" << QByteArray("1\xC2\xA0""234\xC2\xA0""567\xC2\xA0""890"); // no-break spaces
+}
+
void tst_QWebEngineView::mixLangLocale()
{
- for (QString locale : { "en_DK", "de_CH", "eu_ES" }) {
- QLocale::setDefault(QLocale(locale));
- QWebEngineView view;
- QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ QFETCH(QString, locale);
+ QFETCH(QByteArray, formattedNumber);
- bool terminated = false;
- auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; });
+ QLocale::setDefault(QLocale(locale));
- view.load(QUrl("qrc:///resources/dummy.html"));
- QTRY_VERIFY(terminated || loadSpy.count() == 1);
+ QWebEngineView view;
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
- QVERIFY2(!terminated,
- qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count())));
- QVERIFY(loadSpy.first().first().toBool());
+ bool terminated = false;
+ auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; });
+
+ view.load(QUrl("qrc:///resources/dummy.html"));
+ QTRY_VERIFY(terminated || loadSpy.count() == 1);
+
+ QVERIFY2(!terminated,
+ qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count())));
+ QVERIFY(loadSpy.first().first().toBool());
+
+ QString content = toPlainTextSync(view.page());
+ QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content));
+
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "navigator.language").toString(), QLocale().bcp47Name());
+
+ if (locale == "eu-ES")
+ QEXPECT_FAIL("", "Basque number formatting is somehow dependent on environment", Continue);
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "Number(1234567890).toLocaleString()").toByteArray(), formattedNumber);
- QString content = toPlainTextSync(view.page());
- QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content));
- }
QLocale::setDefault(QLocale("en"));
}