diff --git a/config.tests/hostcompiler/hostcompiler.pro b/config.tests/hostcompiler/hostcompiler.pro
new file mode 100644
index 0000000000000000000000000000000000000000..5a80246ab0175e72050b00c3fe25f10ec52d7cd4
--- /dev/null
+++ b/config.tests/hostcompiler/hostcompiler.pro
@@ -0,0 +1,9 @@
+option(host_build)
+
+gcc:equals(QT_ARCH, "x86_64"):contains(QT_TARGET_ARCH, "arm"):!contains(QT_TARGET_ARCH, "arm64") {
+    QMAKE_CXXFLAGS += -m32
+    QMAKE_LFLAGS += -m32
+}
+
+SOURCES = main.cpp
+
diff --git a/config.tests/hostcompiler/main.cpp b/config.tests/hostcompiler/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..96444ae8bdd0dc9ecf8cdb41b36fe2caf799867a
--- /dev/null
+++ b/config.tests/hostcompiler/main.cpp
@@ -0,0 +1,6 @@
+#include <stdio.h>
+int main()
+{
+   printf("This works\n");
+   return 0;
+}
diff --git a/configure.json b/configure.json
index 7ef1f5003ec6d1085087b8675ba3a1596b5314bc..c44da9854f29e5bfa62f155a2cb193d349e9a12a 100644
--- a/configure.json
+++ b/configure.json
@@ -21,8 +21,8 @@
             "webengine-spellchecker": "boolean",
             "webengine-native-spellchecker": "boolean",
             "webengine-webrtc": "boolean",
-            "webengine-geolocation" : "boolean",
-
+            "webengine-geolocation": "boolean",
+            "webengine-v8-snapshot": "boolean",
             "alsa": { "type": "boolean", "name": "webengine-alsa" },
             "pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" },
             "ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
@@ -189,6 +189,11 @@
             "test": "alsa",
             "type": "compile"
         },
+        "webengine-host-compiler": {
+            "label": "host compiler",
+            "test": "hostcompiler",
+            "type": "compile"
+        },
         "webengine-khr": {
             "label": "khr",
             "test": "khr",
@@ -223,6 +228,11 @@
             "type": "detectPython2",
             "log": "location"
         },
+        "webengine-host-pkg-config": {
+            "label": "host pkg-config",
+            "type": "detectHostPkgConfig",
+            "log": "path"
+        },
         "webengine-gperf": {
             "label": "gperf",
             "type": "detectGperf"
@@ -355,6 +365,14 @@
                 { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" }
             ]
         },
+        "webengine-host-pkg-config": {
+            "label": "host-pkg-config",
+            "condition": "config.unix && tests.webengine-host-pkg-config",
+            "output": [
+                "privateFeature",
+                { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" }
+            ]
+        },
         "webengine-gperf": {
             "label": "gperf",
             "condition": "tests.webengine-gperf",
@@ -383,6 +401,16 @@
             "condition": "config.unix && tests.alsa",
             "output": [ "privateFeature" ]
         },
+        "webengine-v8-snapshot": {
+            "label" : "Use v8 snapshot",
+            "purpuse": "Enables the v8 snapshot, for fast v8 context creation",
+            "output": [ "privateFeature" ]
+        },
+        "webengine-v8-snapshot-support": {
+            "autoDetect": "features.webengine-v8-snapshot",
+            "condition": "!config.unix || !features.webengine-embedded-build || tests.webengine-host-compiler",
+            "output": [ "privateFeature" ]
+        },
         "webengine-system-khr" : {
             "label": "khr",
             "condition": "config.unix && tests.webengine-khr",
@@ -566,6 +594,11 @@
             "type": "warning",
             "condition": "config.sanitizer && !tests.webengine-sanitizer && !features.webengine-sanitizer",
             "message": "Qt WebEngine cannot be built with the chosen sanitizer configuration. Check config.log for details or use -feature-webengine-sanitizer to force the build."
+        },
+        {
+            "type": "warning",
+            "condition": "config.unix && !features.webengine-host-pkg-config",
+            "message": "host pkg-config not found"
         }
     ],
 
@@ -582,6 +615,7 @@
                 "webengine-webrtc",
                 "webengine-system-ninja",
                 "webengine-geolocation",
+                "webengine-v8-snapshot",
                 {
                     "type": "feature",
                     "args": "webengine-alsa",
diff --git a/configure.pri b/configure.pri
index 497557262ee86f6d587c6bef192b3852a6c010c8..ecf2ce4d36856c90ea81eb0354fe3fffa8a42c18 100644
--- a/configure.pri
+++ b/configure.pri
@@ -157,6 +157,20 @@ defineTest(qtConfTest_detectIcuuc) {
    return(false)
 }
 
+defineTest(qtConfTest_detectHostPkgConfig) {
+   PKG_CONFIG = $$qtConfPkgConfig(true)
+   isEmpty(PKG_CONFIG) {
+       qtLog("Could not find host pkg-config")
+       return(false)
+   }
+   qtLog("Found host pkg-config: $$PKG_CONFIG")
+   $${1}.path = $$PKG_CONFIG
+   export($${1}.path)
+   $${1}.cache += path
+   export($${1}.cache)
+   return(true)
+}
+
 defineTest(qtConfTest_isSanitizerSupported) {
   sanitizer_combo_supported = true
 
diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
index c5506a6234a70045bf05ac9cd38e322d5f0f99e3..f1fdf85d159f8bb9d184f8c6e50f2d6bfbe8c6ce 100644
--- a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
+++ b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
@@ -11,8 +11,8 @@
 ** accordance with the commercial license agreement provided with the
 ** Software or, alternatively, in accordance with the terms contained in
 ** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
 **
 ** GNU Free Documentation License Usage
 ** Alternatively, this file may be used under the terms of the GNU Free
@@ -20,7 +20,7 @@
 ** Foundation and appearing in the file included in the packaging of
 ** this file. Please review the following information to ensure
 ** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index 8b8fd3efe931d37ea2bffcc9e0f58a9e5783a838..f8c15465571fcde0c2d193e2bccd37331af1b2c9 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -30,6 +30,13 @@ defineTest(runConfigure) {
     include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri)
     QT_FOR_CONFIG += webengine-private
 
+    !qtConfig(webengine-v8-snapshot-support):qtConfig(webengine-v8-snapshot) {
+        skipBuild("V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work."\
+                  "Please make sure you have 32-bit devel environment installed, or "\
+                  "configure webengine with '-no-webengine-v8-snapshot'")
+        return(false)
+    }
+
     !qtConfig(webengine-gperf) {
         skipBuild("Required gperf could not be found.")
         return(false)
@@ -53,6 +60,12 @@ defineTest(runConfigure) {
     }
 
     linux {
+
+        !qtConfig(webengine-host-pkg-config) {
+            skipBuild("Host pkg-config is required")
+            return(false)
+        }
+
         !qtConfig(webengine-system-glibc) {
             skipBuild("A suitable version of libc could not be found. See: https://sourceware.org/bugzilla/show_bug.cgi?id=14898")
             return(false)
diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf
index 3b9a400b1204f96dfa40305096dc66f0a6e79f9a..8564bad8adaf7798daa4959e5d8da0fff26f24c1 100644
--- a/mkspecs/features/functions.prf
+++ b/mkspecs/features/functions.prf
@@ -115,3 +115,18 @@ defineTest(skipBuild) {
     skipBuildReason = "$$skipBuildReason $${EOL}$$1"
     export(skipBuildReason)
 }
+
+defineReplace(pkgConfigHostExecutable) {
+    wrapper_name = $$OUT_PWD/pkg-config-host_wrapper.sh
+    wrapper_cmd = $$QMAKE_PKG_CONFIG_HOST
+    isEmpty(wrapper_cmd): wrapper_cmd = pkg-config
+    wrapper_content = \
+        "$$LITERAL_HASH!/bin/sh" \
+        "unset PKG_CONFIG_LIBDIR" \
+        "unset PKG_CONFIG_SYSROOT_DIR" \
+        "exec $$wrapper_cmd \"$@\""
+    !build_pass:!write_file($$wrapper_name, wrapper_content, exe): error()
+    QMAKE_DISTCLEAN += $$wrapper_name
+    export(QMAKE_DISTCLEAN)
+    return($$system_quote($$system_path($$wrapper_name)))
+}
diff --git a/src/core/config/common.pri b/src/core/config/common.pri
index 60aba490c4ed8366a24bd122e49b9bfe252f51b4..ab2a609782d3815425501a0b29d0c5e4649566c1 100644
--- a/src/core/config/common.pri
+++ b/src/core/config/common.pri
@@ -47,7 +47,11 @@ qtConfig(webengine-webrtc) {
 
 qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\"
 
-!precompile_header: gn_args += disable_precompiled_headers=true
+precompile_header {
+    gn_args += enable_precompiled_headers=true
+} else {
+    gn_args += enable_precompiled_headers=false
+}
 
 CONFIG(release, debug|release) {
     force_debug_info {
@@ -80,3 +84,10 @@ optimize_size: gn_args += optimize_for_size=true
     # rtti, linking would fail at build time.
     sanitize_undefined: gn_args += is_ubsan=true use_rtti=true
 }
+
+qtConfig(webengine-v8-snapshot) {
+    gn_args += v8_use_snapshot=true
+} else {
+    gn_args += v8_use_snapshot=false
+}
+
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index cdb723b7962f7bad62a834f9587f366d29714760..f4a95a03c7c63dbaadacad4e3c29f8c9a0cdf3f1 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -110,7 +110,14 @@ host_build {
         PKGCONFIG = $$first($$list($$pkgConfigExecutable()))
         gn_args += pkg_config=\"$$PKGCONFIG\"
         PKG_CONFIG_HOST = $$(GN_PKG_CONFIG_HOST)
-        isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = pkg-config
+        pkgConfigLibDir = $$(PKG_CONFIG_LIBDIR)
+        pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR)
+        isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = $$QMAKE_PKG_CONFIG_HOST
+        cross_compile {
+            !isEmpty(pkgConfigLibDir)|!isEmpty(pkgConfigSysrootDir) {
+                PKG_CONFIG_HOST = $$pkgConfigHostExecutable()
+            }
+        }
         gn_args += host_pkg_config=\"$$PKG_CONFIG_HOST\"
     }
 
diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp
index e9491eabab704b3f20eb019a22702001625f1ed2..941fbd211347f222ae0ff0825b68931116c139c6 100644
--- a/src/core/gl_surface_qt.cpp
+++ b/src/core/gl_surface_qt.cpp
@@ -290,7 +290,7 @@ bool GLSurfaceQtGLX::Initialize(GLSurfaceFormat format)
         GLX_PBUFFER_HEIGHT, m_size.height(),
         GLX_LARGEST_PBUFFER, False,
         GLX_PRESERVED_CONTENTS, False,
-        GLX_NONE
+        0
     };
 
     m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes);
diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp
index 5198985d7ae5148d9af48da1bbfccd03b443f650..fef2cf51afc78d0834d65e808cabc2b2f272cdea 100644
--- a/src/core/print_view_manager_qt.cpp
+++ b/src/core/print_view_manager_qt.cpp
@@ -154,27 +154,37 @@ static base::DictionaryValue *createPrintSettings()
     return printSettings;
 }
 
-static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout)
+static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout, bool printToPdf)
 {
     base::DictionaryValue *printSettings = createPrintSettings();
 
     //Set page size attributes, chromium expects these in micrometers
-    QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter);
+    QRectF pageSizeInMillimeter = pageLayout.pageSize().rect(QPageSize::Millimeter);
+    if (!printToPdf) {
+        // QPrinter will extend this size with its margins
+        QMarginsF margins = pageLayout.margins(QPageLayout::Millimeter);
+        pageSizeInMillimeter = pageSizeInMillimeter.marginsRemoved(margins);
+    }
     std::unique_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue);
-    sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter);
-    sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter);
+    sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMillimeter.width() * kMicronsToMillimeter);
+    sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMillimeter.height() * kMicronsToMillimeter);
     printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict));
 
-    // Apply page margins
-    QMargins pageMarginsInPoints = pageLayout.marginsPoints();
-    std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
-    marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
-    marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
-    marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
-    marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
-
-    printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
-    printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS);
+    if (printToPdf) {
+        // Apply page margins when printing to PDF
+        QMargins pageMarginsInPoints = pageLayout.marginsPoints();
+        std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
+        marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
+        marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
+        marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
+        marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
+
+        printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
+        printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS);
+    } else {
+        // QPrinter will handle margins
+        printSettings->SetInteger(printing::kSettingMarginsType, printing::NO_MARGINS);
+    }
 
     printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
 
@@ -244,7 +254,7 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool
     if (!pageLayout.isValid())
         return false;
 
-    m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout));
+    m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, !m_pdfOutputPath.empty()));
     m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds
         , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds);
     m_printSettings->SetInteger(printing::kSettingColor,
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 8986a34953905b09b1e77d0fe42d2494b4193b2f..4f6d6d0eaa62f61e807bb05de02c3f61ad1b00d0 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -1595,7 +1595,8 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
     if (webEvent.GetType() == blink::WebInputEvent::kMouseDown) {
         if (event->button() != m_clickHelper.lastPressButton
             || (event->timestamp() - m_clickHelper.lastPressTimestamp > static_cast<ulong>(qGuiApp->styleHints()->mouseDoubleClickInterval()))
-            || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance())
+            || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance()
+            || m_clickHelper.clickCounter >= 3)
             m_clickHelper.clickCounter = 0;
 
         m_clickHelper.lastPressTimestamp = event->timestamp();
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index f87cc115b651b8d7d33a1cf189af2a177eca9342..5b7e437bf16ac1723211c2708fe6a1d6d7569634 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -367,8 +367,6 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate()
 
 WebContentsAdapterPrivate::~WebContentsAdapterPrivate()
 {
-    // Destroy the WebContents first
-    webContents.reset();
 }
 
 QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient)
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 5364afa94f2b7d8bbbdb8f7269cfe807d8cfc6cb..09cca943ef3fdb9f2d1d583daeddf58a136ca990 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -110,6 +110,13 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents,
     Observe(webContents);
 }
 
+WebContentsDelegateQt::~WebContentsDelegateQt()
+{
+    // The destruction of this object should take place before
+    // WebContents destruction since WebContentsAdapterClient
+    // might be already deleted.
+}
+
 content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents *source, const content::OpenURLParams &params)
 {
     content::WebContents *target = source;
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 7e21e4b55d8d3edb8de0176517a1150f586a8b0f..8a3331163c87fe28b0bf88c5fb53bd2215e6b6be 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -93,7 +93,7 @@ class WebContentsDelegateQt : public content::WebContentsDelegate
 {
 public:
     WebContentsDelegateQt(content::WebContents*, WebContentsAdapterClient *adapterClient);
-    ~WebContentsDelegateQt() { Q_ASSERT(m_loadingErrorFrameList.isEmpty()); }
+    ~WebContentsDelegateQt();
     QString lastSearchedString() const { return m_lastSearchedString; }
     void setLastSearchedString(const QString &s) { m_lastSearchedString = s; }
     int lastReceivedFindReply() const { return m_lastReceivedFindReply; }
diff --git a/src/webengine/api/qquickwebenginetestsupport.cpp b/src/webengine/api/qquickwebenginetestsupport.cpp
index b3290d3cc2d05063c873181d8c8daf8eeacb438b..b7b86312595bcc07256ca98ad7d119868e30da51 100644
--- a/src/webengine/api/qquickwebenginetestsupport.cpp
+++ b/src/webengine/api/qquickwebenginetestsupport.cpp
@@ -42,6 +42,7 @@
 #include "qquickwebengineloadrequest_p.h"
 #include <QQuickWindow>
 #include <QtTest/qtest.h>
+#include <QtCore/QTimer>
 
 QT_BEGIN_NAMESPACE
 
@@ -56,19 +57,20 @@ QQuickWebEngineErrorPage::QQuickWebEngineErrorPage()
 void QQuickWebEngineErrorPage::loadFinished(bool success, const QUrl &url)
 {
     Q_UNUSED(success);
-
-    QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
-    Q_EMIT loadingChanged(&loadRequest);
-    return;
+    QTimer::singleShot(0, this, [this, url]() {
+       QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
+       emit loadingChanged(&loadRequest);
+    });
 }
 
 void QQuickWebEngineErrorPage::loadStarted(const QUrl &provisionalUrl)
 {
-    QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus);
-    Q_EMIT loadingChanged(&loadRequest);
+    QTimer::singleShot(0, this, [this, provisionalUrl]() {
+        QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus);
+        emit loadingChanged(&loadRequest);
+    });
 }
 
-
 QQuickWebEngineTestInputContext::QQuickWebEngineTestInputContext()
     : m_visible(false)
 {
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 19e85315b7b491287b3b5e857e48916e56f41366..492becaa310f2195d3970948090fc9192636597e 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -331,14 +331,14 @@ void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url)
 
     iconUrl = faviconProvider->attach(q, url);
     m_history->reset();
-    Q_EMIT q->iconChanged();
+    QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged);
 }
 
 void QQuickWebEngineViewPrivate::loadProgressChanged(int progress)
 {
     Q_Q(QQuickWebEngineView);
     loadProgress = progress;
-    Q_EMIT q->loadProgressChanged();
+    QTimer::singleShot(0, q, &QQuickWebEngineView::loadProgressChanged);
 }
 
 void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl)
@@ -384,12 +384,10 @@ void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool is
     m_history->reset();
     m_certificateErrorControllers.clear();
 
-    QPointer<QQuickWebEngineView> pq(q);
-    QTimer::singleShot(0, [=]()
-    {
+    QTimer::singleShot(0, q, [q, provisionalUrl]() {
         QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus);
-        if (pq)
-            pq->loadingChanged(&loadRequest);
+
+        emit q->loadingChanged(&loadRequest);
     });
 }
 
@@ -425,25 +423,27 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo
     isLoading = false;
     m_history->reset();
     if (errorCode == WebEngineError::UserAbortedError) {
-        QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus);
-        Q_EMIT q->loadingChanged(&loadRequest);
+        QTimer::singleShot(0, q, [q, url]() {
+            QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus);
+            emit q->loadingChanged(&loadRequest);
+        });
         return;
     }
     if (success) {
         explicitUrl = QUrl();
-        QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
-        Q_EMIT q->loadingChanged(&loadRequest);
+        QTimer::singleShot(0, q, [q, url]() {
+            QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
+            emit q->loadingChanged(&loadRequest);
+        });
         return;
     }
 
     Q_ASSERT(errorCode);
-    QQuickWebEngineLoadRequest loadRequest(
-        url,
-        QQuickWebEngineView::LoadFailedStatus,
-        errorDescription,
-        errorCode,
-        static_cast<QQuickWebEngineView::ErrorDomain>(WebEngineError::toQtErrorDomain(errorCode)));
-    Q_EMIT q->loadingChanged(&loadRequest);
+    QQuickWebEngineView::ErrorDomain errorDomain = static_cast<QQuickWebEngineView::ErrorDomain>(WebEngineError::toQtErrorDomain(errorCode));
+    QTimer::singleShot(0, q, [q, url, errorDescription, errorCode, errorDomain]() {
+        QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadFailedStatus,errorDescription, errorCode, errorDomain);
+        emit q->loadingChanged(&loadRequest);
+    });
     return;
 }
 
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index ddd01632984d589a295eaadbefb15e2c0019ad60..88ad7e44710a0fb115ee9db53019fe45efdaa053 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -107,8 +107,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
         return false;
     }
 
-    QRect printerPageRect = printer.pageRect();
-    PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), printerPageRect.size());
+    QSize pageSize = printer.pageRect().size();
+    PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), pageSize);
 
     int toPage = printer.toPage();
     int fromPage = printer.fromPage();
@@ -156,7 +156,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
                 if (currentImage.isNull())
                     return false;
 
-                painter.drawImage(printerPageRect, currentImage, currentImage.rect());
+                // Painting operations are automatically clipped to the bounds of the drawable part of the page.
+                painter.drawImage(QRect(0, 0, pageSize.width(), pageSize.height()), currentImage, currentImage.rect());
                 if (printedPages < pageCopies - 1)
                     printer.newPage();
             }
@@ -328,7 +329,7 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError
         return;
 
     isLoading = true;
-    Q_EMIT q->loadStarted();
+    QTimer::singleShot(0, q, &QWebEnginePage::loadStarted);
     updateNavigationActions();
 }
 
@@ -346,7 +347,9 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE
 
     if (isErrorPage) {
         Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled));
-        Q_EMIT q->loadFinished(false);
+        QTimer::singleShot(0, q, [q](){
+            emit q->loadFinished(false);
+        });
         return;
     }
 
@@ -356,7 +359,9 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE
     // Delay notifying failure until the error-page is done loading.
     // Error-pages are not loaded on failures due to abort.
     if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) {
-        Q_EMIT q->loadFinished(success);
+        QTimer::singleShot(0, q, [q, success](){
+            emit q->loadFinished(success);
+        });
     }
     updateNavigationActions();
 }
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index b511f1a352a7c8cd086bc49e6417ba0b6691f0ea..dfafbaea456895cf5a62f1f2ccdaf2f0cfd91323 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -1,4 +1,3 @@
-osx-10.11 ci
 [WebViewGeopermission::test_deniedGeolocationByUser]
 osx
 
diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
index bd6625a90d22a393525ce0db76f0a67bb6c1a079..d81e690fd4b279dbfb5977cb563c6c91f67505fc 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
@@ -57,6 +57,10 @@ TestWebEngineView {
         function mouseTripleClick(item, x, y) {
             mouseMultiClick(item, x, y, 3);
         }
+
+        function mouseQuadraClick(item, x, y) {
+            mouseMultiClick(item, x, y, 4);
+        }
     }
 
 
@@ -109,5 +113,18 @@ TestWebEngineView {
             mouseClick(webEngineView, center.x, center.y);
             tryVerify(function() { return getTextSelection() == "" });
         }
+
+        function test_quadraClick() {
+            webEngineView.settings.focusOnNavigationEnabled = true;
+            webEngineView.loadHtml("<html><body onload='document.getElementById(\"input\").focus()'>" +
+                                   "<form><input id='input' width='150' type='text' value='The Qt Company' /></form>" +
+                                   "</body></html>");
+            verify(webEngineView.waitForLoadSucceeded());
+
+            var center = getElementCenter("input");
+            webEngineView.testSupport.mouseQuadraClick(webEngineView, center.x, center.y);
+            verifyElementHasFocus("input");
+            tryVerify(function() { return getTextSelection() == "" });
+        }
     }
 }
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 23c66058ed0b54aa6e5debba5c31b6f8fa3a62da..a32d96b3a9cc0440c26dbb3ee58ee1e978a2ace1 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -101,24 +101,15 @@ private Q_SLOTS:
     void userStyleSheet();
     void userStyleSheetFromLocalFileUrl();
     void userStyleSheetFromQrcUrl();
-    void loadHtml5Video();
     void modified();
     void contextMenuCrash();
     void updatePositionDependentActionsCrash();
-    void createPluginWithPluginsEnabled();
-    void createPluginWithPluginsDisabled();
     void callbackSpyDeleted();
-    void destroyPlugin_data();
-    void destroyPlugin();
-    void createViewlessPlugin_data();
-    void createViewlessPlugin();
-    void graphicsWidgetPlugin();
-    void multiplePageGroupsAndLocalStorage();
+    void multipleProfilesAndLocalStorage();
     void cursorMovements();
     void textSelection();
     void textEditing();
     void backActionUpdate();
-    void protectBindingsRuntimeObjectsFromCollector();
     void testOptionalJSObjects();
     void testLocalStorageVisibility();
     void testEnablePersistentStorage();
@@ -697,20 +688,6 @@ void tst_QWebEnginePage::userStyleSheetFromQrcUrl()
 #endif
 }
 
-void tst_QWebEnginePage::loadHtml5Video()
-{
-#if defined(WTF_USE_QT_MULTIMEDIA) && WTF_USE_QT_MULTIMEDIA
-    QByteArray url("http://does.not/exist?a=1%2Cb=2");
-    m_view->setHtml("<p><video id ='video' src='" + url + "' autoplay/></p>");
-    QTest::qWait(2000);
-    QUrl mUrl = DumpRenderTreeSupportQt::mediaContentUrlByElementId(m_page->mainFrame()->handle(), "video");
-    QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=65452", Continue);
-    QCOMPARE(mUrl.toEncoded(), url);
-#else
-    W_QSKIP("This test requires Qt Multimedia", SkipAll);
-#endif
-}
-
 void tst_QWebEnginePage::modified()
 {
 #if !defined(QWEBENGINEPAGE_ISMODIFIED)
@@ -817,376 +794,47 @@ void tst_QWebEnginePage::contextMenuCrash()
 #endif
 }
 
-#if defined(QWEBENGINEPAGE_CREATEPLUGIN)
-class PluginPage : public QWebEnginePage
-{
-public:
-    PluginPage(QObject *parent = 0)
-        : QWebEnginePage(parent) {}
-
-    struct CallInfo
-    {
-        CallInfo(const QString &c, const QUrl &u,
-                 const QStringList &pn, const QStringList &pv,
-                 QObject *r)
-            : classid(c), url(u), paramNames(pn),
-              paramValues(pv), returnValue(r)
-            {}
-        QString classid;
-        QUrl url;
-        QStringList paramNames;
-        QStringList paramValues;
-        QObject *returnValue;
-    };
-
-    QList<CallInfo> calls;
-
-protected:
-    virtual QObject *createPlugin(const QString &classid, const QUrl &url,
-                                  const QStringList &paramNames,
-                                  const QStringList &paramValues)
-    {
-        QObject *result = 0;
-        if (classid == "pushbutton")
-            result = new QPushButton();
-#ifndef QT_NO_INPUTDIALOG
-        else if (classid == "lineedit")
-            result = new QLineEdit();
-#endif
-        else if (classid == "graphicswidget")
-            result = new QGraphicsWidget();
-        if (result)
-            result->setObjectName(classid);
-        calls.append(CallInfo(classid, url, paramNames, paramValues, result));
-        return result;
-    }
-};
-
-static void createPlugin(QWebEngineView *view)
-{
-    QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
-
-    PluginPage* newPage = new PluginPage(view);
-    view->setPage(newPage);
-
-    // type has to be application/x-qt-plugin
-    view->setHtml(QString("<html><body><object type='application/x-foobarbaz' classid='pushbutton' id='mybutton'/></body></html>"));
-    QTRY_COMPARE(loadSpy.count(), 1);
-    QCOMPARE(newPage->calls.count(), 0);
-
-    view->setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='pushbutton' id='mybutton'/></body></html>"));
-    QTRY_COMPARE(loadSpy.count(), 2);
-    QCOMPARE(newPage->calls.count(), 1);
-    {
-        PluginPage::CallInfo ci = newPage->calls.takeFirst();
-        QCOMPARE(ci.classid, QString::fromLatin1("pushbutton"));
-        QCOMPARE(ci.url, QUrl());
-        QCOMPARE(ci.paramNames.count(), 3);
-        QCOMPARE(ci.paramValues.count(), 3);
-        QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type"));
-        QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin"));
-        QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid"));
-        QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("pushbutton"));
-        QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id"));
-        QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mybutton"));
-        QVERIFY(ci.returnValue != 0);
-        QVERIFY(ci.returnValue->inherits("QPushButton"));
-    }
-    // test JS bindings
-    QCOMPARE(evaluateJavaScriptSync(newPage, "document.getElementById('mybutton').toString()").toString(),
-             QString::fromLatin1("[object HTMLObjectElement]"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.toString()").toString(),
-             QString::fromLatin1("[object HTMLObjectElement]"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mybutton.objectName").toString(),
-             QString::fromLatin1("string"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.objectName").toString(),
-             QString::fromLatin1("pushbutton"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mybutton.clicked").toString(),
-             QString::fromLatin1("function"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.clicked.toString()").toString(),
-             QString::fromLatin1("function clicked() {\n    [native code]\n}"));
-
-    view->setHtml(QString("<html><body><table>"
-                            "<tr><object type='application/x-qt-plugin' classid='lineedit' id='myedit'/></tr>"
-                            "<tr><object type='application/x-qt-plugin' classid='pushbutton' id='mybutton'/></tr>"
-                            "</table></body></html>"), QUrl("http://foo.bar.baz"));
-    QTRY_COMPARE(loadSpy.count(), 3);
-    QCOMPARE(newPage->calls.count(), 2);
-    {
-        PluginPage::CallInfo ci = newPage->calls.takeFirst();
-        QCOMPARE(ci.classid, QString::fromLatin1("lineedit"));
-        QCOMPARE(ci.url, QUrl());
-        QCOMPARE(ci.paramNames.count(), 3);
-        QCOMPARE(ci.paramValues.count(), 3);
-        QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type"));
-        QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin"));
-        QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid"));
-        QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("lineedit"));
-        QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id"));
-        QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("myedit"));
-        QVERIFY(ci.returnValue != 0);
-        QVERIFY(ci.returnValue->inherits("QLineEdit"));
-    }
-    {
-        PluginPage::CallInfo ci = newPage->calls.takeFirst();
-        QCOMPARE(ci.classid, QString::fromLatin1("pushbutton"));
-        QCOMPARE(ci.url, QUrl());
-        QCOMPARE(ci.paramNames.count(), 3);
-        QCOMPARE(ci.paramValues.count(), 3);
-        QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type"));
-        QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin"));
-        QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid"));
-        QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("pushbutton"));
-        QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id"));
-        QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mybutton"));
-        QVERIFY(ci.returnValue != 0);
-        QVERIFY(ci.returnValue->inherits("QPushButton"));
-    }
-}
-#endif
-
-void tst_QWebEnginePage::graphicsWidgetPlugin()
-{
-#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    QSKIP("QWEBENGINEPAGE_CREATEPLUGIN");
-#else
-    m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
-    QGraphicsWebView webView;
-
-    QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool)));
-
-    PluginPage* newPage = new PluginPage(&webView);
-    webView.setPage(newPage);
-
-    // type has to be application/x-qt-plugin
-    webView.setHtml(QString("<html><body><object type='application/x-foobarbaz' classid='graphicswidget' id='mygraphicswidget'/></body></html>"));
-    QTRY_COMPARE(loadSpy.count(), 1);
-    QCOMPARE(newPage->calls.count(), 0);
-
-    webView.setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='graphicswidget' id='mygraphicswidget'/></body></html>"));
-    QTRY_COMPARE(loadSpy.count(), 2);
-    QCOMPARE(newPage->calls.count(), 1);
-    {
-        PluginPage::CallInfo ci = newPage->calls.takeFirst();
-        QCOMPARE(ci.classid, QString::fromLatin1("graphicswidget"));
-        QCOMPARE(ci.url, QUrl());
-        QCOMPARE(ci.paramNames.count(), 3);
-        QCOMPARE(ci.paramValues.count(), 3);
-        QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type"));
-        QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin"));
-        QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid"));
-        QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("graphicswidget"));
-        QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id"));
-        QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mygraphicswidget"));
-        QVERIFY(ci.returnValue);
-        QVERIFY(ci.returnValue->inherits("QGraphicsWidget"));
-    }
-    // test JS bindings
-    QCOMPARE(evaluateJavaScriptSync(newPage, "document.getElementById('mygraphicswidget').toString()").toString(),
-             QString::fromLatin1("[object HTMLObjectElement]"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.toString()").toString(),
-             QString::fromLatin1("[object HTMLObjectElement]"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mygraphicswidget.objectName").toString(),
-             QString::fromLatin1("string"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.objectName").toString(),
-             QString::fromLatin1("graphicswidget"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mygraphicswidget.geometryChanged").toString(),
-             QString::fromLatin1("function"));
-    QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.geometryChanged.toString()").toString(),
-             QString::fromLatin1("function geometryChanged() {\n    [native code]\n}"));
-#endif
-}
-
-void tst_QWebEnginePage::createPluginWithPluginsEnabled()
+void tst_QWebEnginePage::multipleProfilesAndLocalStorage()
 {
-#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    QSKIP("QWEBENGINEPAGE_CREATEPLUGIN");
-#else
-    m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
-    createPlugin(m_view);
-#endif
-}
-
-void tst_QWebEnginePage::createPluginWithPluginsDisabled()
-{
-#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    QSKIP("QWEBENGINEPAGE_CREATEPLUGIN");
-#else
-    // Qt Plugins should be loaded by QtWebEngine even when PluginsEnabled is
-    // false. The client decides whether a Qt plugin is enabled or not when
-    // it decides whether or not to instantiate it.
-    m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false);
-    createPlugin(m_view);
-#endif
-}
-
-#if defined(QWEBENGINEPAGE_CREATEPLUGIN)
-// Standard base class for template PluginTracerPage. In tests it is used as interface.
-class PluginCounterPage : public QWebEnginePage {
-public:
-    int m_count;
-    QPointer<QObject> m_widget;
-    QObject* m_pluginParent;
-    PluginCounterPage(QObject* parent = 0)
-        : QWebEnginePage(parent)
-        , m_count(0)
-        , m_pluginParent(0)
-    {
-       settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
-    }
-    ~PluginCounterPage()
-    {
-        if (m_pluginParent)
-            m_pluginParent->deleteLater();
-    }
-};
-
-template<class T>
-class PluginTracerPage : public PluginCounterPage {
-public:
-    PluginTracerPage(QObject* parent = 0)
-        : PluginCounterPage(parent)
-    {
-        // this is a dummy parent object for the created plugin
-        m_pluginParent = new T;
-    }
-    virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&)
-    {
-        m_count++;
-        m_widget = new T;
-        // need a cast to the specific type, as QObject::setParent cannot be called,
-        // because it is not virtual. Instead it is necessary to call QWidget::setParent,
-        // which also takes a QWidget* instead of a QObject*. Therefore we need to
-        // upcast to T*, which is a QWidget.
-        static_cast<T*>(m_widget.data())->setParent(static_cast<T*>(m_pluginParent));
-        return m_widget.data();
-    }
-};
-
-class PluginFactory {
-public:
-    enum FactoredType {QWidgetType, QGraphicsWidgetType};
-    static PluginCounterPage* create(FactoredType type, QObject* parent = 0)
-    {
-        PluginCounterPage* result = 0;
-        switch (type) {
-        case QWidgetType:
-            result = new PluginTracerPage<QWidget>(parent);
-            break;
-        case QGraphicsWidgetType:
-            result = new PluginTracerPage<QGraphicsWidget>(parent);
-            break;
-        default: {/*Oops*/};
-        }
-        return result;
-    }
-
-    static void prepareTestData()
+    QDir dir(tmpDirPath());
+    bool success = dir.mkpath("path1");
+    success = success && dir.mkdir("path2");
+    QVERIFY(success);
     {
-        QTest::addColumn<int>("type");
-        QTest::newRow("QWidget") << (int)PluginFactory::QWidgetType;
-        QTest::newRow("QGraphicsWidget") << (int)PluginFactory::QGraphicsWidgetType;
+        QWebEngineProfile profile1("test1");
+        QWebEngineProfile profile2("test2");
+        profile1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+        profile2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+        profile1.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1"));
+        profile2.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2"));
+
+        QWebEnginePage page1(&profile1, nullptr);
+        QWebEnginePage page2(&profile2, nullptr);
+        QSignalSpy loadSpy1(&page1, SIGNAL(loadFinished(bool)));
+        QSignalSpy loadSpy2(&page2, SIGNAL(loadFinished(bool)));
+
+        page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
+        page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
+        QTRY_COMPARE(loadSpy1.count(), 1);
+        QTRY_COMPARE(loadSpy2.count(), 1);
+
+        evaluateJavaScriptSync(&page1, "localStorage.setItem('test', 'value1');");
+        evaluateJavaScriptSync(&page2, "localStorage.setItem('test', 'value2');");
+
+        page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
+        page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
+        QTRY_COMPARE(loadSpy1.count(), 2);
+        QTRY_COMPARE(loadSpy2.count(), 2);
+
+        QVariant s1 = evaluateJavaScriptSync(&page1, "localStorage.getItem('test')");
+        QCOMPARE(s1.toString(), QString("value1"));
+        QVariant s2 = evaluateJavaScriptSync(&page2, "localStorage.getItem('test')");
+        QCOMPARE(s2.toString(), QString("value2"));
     }
-};
-#endif
-
-void tst_QWebEnginePage::destroyPlugin_data()
-{
-#if defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    PluginFactory::prepareTestData();
-#endif
-}
-
-void tst_QWebEnginePage::destroyPlugin()
-{
-#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    QSKIP("QWEBENGINEPAGE_CREATEPLUGIN");
-#else
-    QFETCH(int, type);
-    PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type, m_view);
-    m_view->setPage(page);
-
-    // we create the plugin, so the widget should be constructed
-    QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>");
-    m_view->setHtml(content);
-    QVERIFY(page->m_widget);
-    QCOMPARE(page->m_count, 1);
-
-    // navigate away, the plugin widget should be destructed
-    m_view->setHtml("<html><body>Hi</body></html>");
-    QTestEventLoop::instance().enterLoop(1);
-    QVERIFY(!page->m_widget);
-#endif
-}
-
-void tst_QWebEnginePage::createViewlessPlugin_data()
-{
-#if defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    PluginFactory::prepareTestData();
-#endif
-}
-
-void tst_QWebEnginePage::createViewlessPlugin()
-{
-#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    QSKIP("QWEBENGINEPAGE_CREATEPLUGIN");
-#else
-    QFETCH(int, type);
-    PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type);
-    QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>");
-    page->setHtml(content);
-    QCOMPARE(page->m_count, 1);
-    QVERIFY(page->m_widget);
-    QVERIFY(page->m_pluginParent);
-    QVERIFY(page->m_widget.data()->parent() == page->m_pluginParent);
-    delete page;
-#endif
-}
-
-void tst_QWebEnginePage::multiplePageGroupsAndLocalStorage()
-{
-#if !defined(QWEBENGINESETTINGS_SETLOCALSTORAGEPATH)
-    QSKIP("QWEBENGINESETTINGS_SETLOCALSTORAGEPATH");
-#else
-    QDir dir(tmpDirPath());
-    dir.mkdir("path1");
-    dir.mkdir("path2");
-
-    QWebEngineView view1;
-    QWebEngineView view2;
-
-    view1.page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
-    view1.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1"));
-    DumpRenderTreeSupportQt::webPageSetGroupName(view1.page()->handle(), "group1");
-    view2.page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
-    view2.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2"));
-    DumpRenderTreeSupportQt::webPageSetGroupName(view2.page()->handle(), "group2");
-    QCOMPARE(DumpRenderTreeSupportQt::webPageGroupName(view1.page()->handle()), QString("group1"));
-    QCOMPARE(DumpRenderTreeSupportQt::webPageGroupName(view2.page()->handle()), QString("group2"));
-
-
-    view1.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com"));
-    view2.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com"));
-
-    evaluateJavaScriptSync(view1.page(), "localStorage.test='value1';");
-    evaluateJavaScriptSync(view2.page(), "localStorage.test='value2';");
-
-    view1.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com"));
-    view2.setHtml(QString("<html><body> </body></html>"), QUrl("http://www.myexample.com"));
-
-    QVariant s1 = evaluateJavaScriptSync(view1.page(), "localStorage.test");
-    QCOMPARE(s1.toString(), QString("value1"));
-
-    QVariant s2 = evaluateJavaScriptSync(view2.page(), "localStorage.test");
-    QCOMPARE(s2.toString(), QString("value2"));
-
+    // Avoid deleting on-disk dbs before the underlying browser-context has been asynchronously deleted
     QTest::qWait(1000);
-
-    QFile::remove(QDir::toNativeSeparators(tmpDirPath() + "/path1/http_www.myexample.com_0.localstorage"));
-    QFile::remove(QDir::toNativeSeparators(tmpDirPath() + "/path2/http_www.myexample.com_0.localstorage"));
-    dir.rmdir(QDir::toNativeSeparators("./path1"));
-    dir.rmdir(QDir::toNativeSeparators("./path2"));
-#endif
+    QDir(tmpDirPath() + "/path1").removeRecursively();
+    QDir(tmpDirPath() + "/path2").removeRecursively();
 }
 
 class CursorTrackedPage : public QWebEnginePage
@@ -1660,32 +1308,6 @@ void tst_QWebEnginePage::backActionUpdate()
     QVERIFY(action->isEnabled());
 }
 
-void tst_QWebEnginePage::protectBindingsRuntimeObjectsFromCollector()
-{
-#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
-    QSKIP("QWEBENGINEPAGE_CREATEPLUGIN");
-#else
-    QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
-
-    PluginPage* newPage = new PluginPage(m_view);
-    m_view->setPage(newPage);
-
-    m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
-
-    m_view->setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='lineedit' id='mylineedit'/></body></html>"));
-    QTRY_COMPARE(loadSpy.count(), 1);
-
-    newPage->runJavaScript("function testme(text) { var lineedit = document.getElementById('mylineedit'); lineedit.setText(text); lineedit.selectAll(); }");
-
-    evaluateJavaScriptSync(newPage, "testme('foo')");
-
-    DumpRenderTreeSupportQt::garbageCollectorCollect();
-
-    // don't crash!
-    evaluateJavaScriptSync(newPage, "testme('bar')");
-#endif
-}
-
 #if defined(QWEBENGINEPAGE_SETTINGS)
 static inline bool testFlag(QWebEnginePage& webPage, QWebEngineSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue)
 {
@@ -3790,8 +3412,6 @@ void tst_QWebEnginePage::setUrlWithPendingLoads()
 
 void tst_QWebEnginePage::setUrlToEmpty()
 {
-    QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance().");
-
     int expectedLoadFinishedCount = 0;
     const QUrl aboutBlank("about:blank");
     const QUrl url("qrc:/resources/test2.html");
@@ -3799,7 +3419,8 @@ void tst_QWebEnginePage::setUrlToEmpty()
     QWebEnginePage page;
     QCOMPARE(page.url(), QUrl());
     QCOMPARE(page.requestedUrl(), QUrl());
-    QCOMPARE(baseUrlSync(&page), QUrl());
+// Chromium now returns about:blank as the base url here:
+//     QCOMPARE(baseUrlSync(&page), QUrl());
 
     QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
 
@@ -3966,8 +3587,6 @@ static QStringList collectHistoryUrls(QWebEngineHistory *history)
 
 void tst_QWebEnginePage::setUrlHistory()
 {
-    QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance().");
-
     const QUrl aboutBlank("about:blank");
     QUrl url;
     int expectedLoadFinishedCount = 0;
@@ -3983,10 +3602,10 @@ void tst_QWebEnginePage::setUrlHistory()
     // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
     QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());
 
-    url = QUrl("http://non.existent/");
+    url = QUrl("http://url.invalid/");
     m_page->setUrl(url);
     expectedLoadFinishedCount++;
-    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), expectedLoadFinishedCount, 20000);
     // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored.
     // We expect the url of the previously loaded page here.
     QCOMPARE(m_page->url(), aboutBlank);
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 6961f3b6da3c1fa54b9a2158152d75967f0a779a..c443ee11433926fcef7ddd221b838bf8451a73a7 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -200,9 +200,13 @@ public:
     }
     bool isSequential() const override { return true; }
     qint64 bytesAvailable() const override
-    { return m_bytesAvailable; }
+    {
+        QMutexLocker lock(&m_mutex);
+        return m_bytesAvailable;
+    }
     bool atEnd() const override
     {
+        QMutexLocker lock(&m_mutex);
         return (m_data.size() >= 1000 && m_bytesRead >= 1000);
     }
 protected:
@@ -237,7 +241,7 @@ protected:
     }
 
 private:
-    QMutex m_mutex;
+    mutable QMutex m_mutex{QMutex::Recursive};
     QByteArray m_data;
     QBasicTimer m_timer;
     int m_bytesRead;