mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	chrome: Update expectations with same-site BFCache enabled (fixes issue #3301)
With same-site BFCache enabled every navigation can now potentially be served via the BFCache. To support this internally a new top-level RenderFrame object may be created for each new navigation. As a result, OnBrowserCreated may now be called multiple times with the same browser ID in a given renderer process (a behavior previously only seen with cross-site navigations and different renderer processes). BFCache navigations do not trigger the same Chromium notifications as a normal load. To avoid breaking CEF API usage expectations we now synthetically generate the load-related callbacks that would otherwise be missing (OnLoadingStateChange with isLoading=true, OnLoadStart, OnLoadEnd). The |httpStatusCode| argument to OnLoadEnd will be 0 in this case. To test: - Run `FrameHandlerTest.*:MessageRouterTest.*:NavigationTest.*` - Run `NavigationTest.LoadSameOriginLoadURL` for OnBrowserCreated behavior. - Run `NavigationTest.History` for load-related callback behavior.
This commit is contained in:
		| @@ -421,6 +421,10 @@ void CefBrowserContentsDelegate::DidFinishNavigation( | |||||||
|     // history state). |     // history state). | ||||||
|     if (!navigation_handle->IsSameDocument()) { |     if (!navigation_handle->IsSameDocument()) { | ||||||
|       OnLoadStart(frame.get(), navigation_handle->GetPageTransition()); |       OnLoadStart(frame.get(), navigation_handle->GetPageTransition()); | ||||||
|  |       if (navigation_handle->IsServedFromBackForwardCache()) { | ||||||
|  |         // We won't get an OnLoadEnd notification from anywhere else. | ||||||
|  |         OnLoadEnd(frame.get(), navigation_handle->GetURL(), 0); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (is_main_frame) { |     if (is_main_frame) { | ||||||
|   | |||||||
| @@ -168,13 +168,10 @@ void CefBrowserInfo::FrameHostStateChanged( | |||||||
|            content::RenderFrameHost::LifecycleState::kInBackForwardCache) && |            content::RenderFrameHost::LifecycleState::kInBackForwardCache) && | ||||||
|       new_state == content::RenderFrameHost::LifecycleState::kActive) { |       new_state == content::RenderFrameHost::LifecycleState::kActive) { | ||||||
|     if (auto frame = GetFrameForHost(host)) { |     if (auto frame = GetFrameForHost(host)) { | ||||||
|       // Should only occur for the main frame. |  | ||||||
|       CHECK(frame->IsMain()); |  | ||||||
|  |  | ||||||
|       // Update the associated RFH, which may have changed. |       // Update the associated RFH, which may have changed. | ||||||
|       frame->MaybeReAttach(this, host); |       frame->MaybeReAttach(this, host); | ||||||
|  |  | ||||||
|       { |       if (frame->IsMain()) { | ||||||
|         // Update the main frame object. |         // Update the main frame object. | ||||||
|         NotificationStateLock lock_scope(this); |         NotificationStateLock lock_scope(this); | ||||||
|         SetMainFrame(browser_, frame); |         SetMainFrame(browser_, frame); | ||||||
|   | |||||||
| @@ -22,6 +22,8 @@ | |||||||
| #include "third_party/blink/renderer/core/dom/element.h" | #include "third_party/blink/renderer/core/dom/element.h" | ||||||
| #include "third_party/blink/renderer/core/dom/node.h" | #include "third_party/blink/renderer/core/dom/node.h" | ||||||
| #include "third_party/blink/renderer/core/editing/serializers/serialization.h" | #include "third_party/blink/renderer/core/editing/serializers/serialization.h" | ||||||
|  | #include "third_party/blink/renderer/core/execution_context/execution_context.h" | ||||||
|  | #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h" | ||||||
| #include "third_party/blink/renderer/core/exported/web_view_impl.h" | #include "third_party/blink/renderer/core/exported/web_view_impl.h" | ||||||
| #include "third_party/blink/renderer/core/frame/frame_owner.h" | #include "third_party/blink/renderer/core/frame/frame_owner.h" | ||||||
| #include "third_party/blink/renderer/core/frame/local_dom_window.h" | #include "third_party/blink/renderer/core/frame/local_dom_window.h" | ||||||
| @@ -220,6 +222,43 @@ bool IsScriptForbidden() { | |||||||
|   return blink::ScriptForbiddenScope::IsScriptForbidden(); |   return blink::ScriptForbiddenScope::IsScriptForbidden(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::unique_ptr<CefObserverRegistration> | ||||||
|  | RegisterExecutionContextLifecycleStateObserver( | ||||||
|  |     v8::Local<v8::Context> context, | ||||||
|  |     CefExecutionContextLifecycleStateObserver* observer) { | ||||||
|  |   class Observer : public blink::GarbageCollected<Observer>, | ||||||
|  |                    public blink::ExecutionContextLifecycleStateObserver { | ||||||
|  |    public: | ||||||
|  |     Observer(blink::ExecutionContext* execution_context, | ||||||
|  |              CefExecutionContextLifecycleStateObserver* observer) | ||||||
|  |         : blink::ExecutionContextLifecycleStateObserver(execution_context), | ||||||
|  |           observer_(observer) { | ||||||
|  |       UpdateStateIfNeeded(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void ContextLifecycleStateChanged( | ||||||
|  |         blink::mojom::blink::FrameLifecycleState state) override { | ||||||
|  |       observer_->ContextLifecycleStateChanged(state); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void ContextDestroyed() override {} | ||||||
|  |  | ||||||
|  |    private: | ||||||
|  |     CefExecutionContextLifecycleStateObserver* observer_; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   class Registration : public CefObserverRegistration { | ||||||
|  |    public: | ||||||
|  |     Registration(blink::Persistent<Observer> observer) : observer_(observer) {} | ||||||
|  |  | ||||||
|  |    private: | ||||||
|  |     blink::Persistent<Observer> observer_; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   return std::make_unique<Registration>(blink::MakeGarbageCollected<Observer>( | ||||||
|  |       blink::ExecutionContext::From(context), observer)); | ||||||
|  | } | ||||||
|  |  | ||||||
| void RegisterURLSchemeAsSupportingFetchAPI(const blink::WebString& scheme) { | void RegisterURLSchemeAsSupportingFetchAPI(const blink::WebString& scheme) { | ||||||
|   blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI(scheme); |   blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI(scheme); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ | |||||||
|  |  | ||||||
| #include "include/internal/cef_types.h" | #include "include/internal/cef_types.h" | ||||||
|  |  | ||||||
|  | #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h" | ||||||
| #include "third_party/blink/public/platform/web_common.h" | #include "third_party/blink/public/platform/web_common.h" | ||||||
| #include "v8/include/v8.h" | #include "v8/include/v8.h" | ||||||
|  |  | ||||||
| @@ -72,6 +73,32 @@ BLINK_EXPORT v8::Local<v8::Value> ExecuteV8ScriptAndReturnValue( | |||||||
|  |  | ||||||
| BLINK_EXPORT bool IsScriptForbidden(); | BLINK_EXPORT bool IsScriptForbidden(); | ||||||
|  |  | ||||||
|  | class BLINK_EXPORT CefObserverRegistration { | ||||||
|  |  public: | ||||||
|  |   CefObserverRegistration() = default; | ||||||
|  |  | ||||||
|  |   CefObserverRegistration(const CefObserverRegistration&) = delete; | ||||||
|  |   CefObserverRegistration& operator=(const CefObserverRegistration&) = delete; | ||||||
|  |  | ||||||
|  |   virtual ~CefObserverRegistration() = default; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class BLINK_EXPORT CefExecutionContextLifecycleStateObserver { | ||||||
|  |  public: | ||||||
|  |   virtual void ContextLifecycleStateChanged( | ||||||
|  |       blink::mojom::blink::FrameLifecycleState state) {} | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   virtual ~CefExecutionContextLifecycleStateObserver() = default; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Register an ExecutionContextLifecycleStateObserver. Remains registered until | ||||||
|  | // the returned object is destroyed. | ||||||
|  | BLINK_EXPORT std::unique_ptr<CefObserverRegistration> | ||||||
|  | RegisterExecutionContextLifecycleStateObserver( | ||||||
|  |     v8::Local<v8::Context> context, | ||||||
|  |     CefExecutionContextLifecycleStateObserver* observer); | ||||||
|  |  | ||||||
| BLINK_EXPORT void RegisterURLSchemeAsSupportingFetchAPI( | BLINK_EXPORT void RegisterURLSchemeAsSupportingFetchAPI( | ||||||
|     const blink::WebString& scheme); |     const blink::WebString& scheme); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -393,6 +393,19 @@ void CefBrowserImpl::OnLoadingStateChange(bool isLoading) { | |||||||
|           return; |           return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (was_in_bfcache_) { | ||||||
|  |           // Send the expected callbacks when exiting the BFCache. | ||||||
|  |           DCHECK(!isLoading); | ||||||
|  |           load_handler->OnLoadingStateChange(this, /*isLoading=*/true, | ||||||
|  |                                              canGoBack, canGoForward); | ||||||
|  |  | ||||||
|  |           auto main_frame = GetMainFrame(); | ||||||
|  |           load_handler->OnLoadStart(this, main_frame, TT_EXPLICIT); | ||||||
|  |           load_handler->OnLoadEnd(this, main_frame, 0); | ||||||
|  |  | ||||||
|  |           was_in_bfcache_ = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         load_handler->OnLoadingStateChange(this, isLoading, canGoBack, |         load_handler->OnLoadingStateChange(this, isLoading, canGoBack, | ||||||
|                                            canGoForward); |                                            canGoForward); | ||||||
|         last_loading_state_.reset( |         last_loading_state_.reset( | ||||||
| @@ -401,3 +414,10 @@ void CefBrowserImpl::OnLoadingStateChange(bool isLoading) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CefBrowserImpl::OnEnterBFCache() { | ||||||
|  |   // Reset loading state so that notifications will be resent if/when exiting | ||||||
|  |   // BFCache. | ||||||
|  |   was_in_bfcache_ = true; | ||||||
|  |   last_loading_state_.reset(); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -92,6 +92,7 @@ class CefBrowserImpl : public CefBrowser, public blink::WebViewObserver { | |||||||
|   void FrameDetached(int64_t frame_id); |   void FrameDetached(int64_t frame_id); | ||||||
|  |  | ||||||
|   void OnLoadingStateChange(bool isLoading); |   void OnLoadingStateChange(bool isLoading); | ||||||
|  |   void OnEnterBFCache(); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   // ID of the browser that this RenderView is associated with. During loading |   // ID of the browser that this RenderView is associated with. During loading | ||||||
| @@ -105,6 +106,9 @@ class CefBrowserImpl : public CefBrowser, public blink::WebViewObserver { | |||||||
|   using FrameMap = std::map<int64, CefRefPtr<CefFrameImpl>>; |   using FrameMap = std::map<int64, CefRefPtr<CefFrameImpl>>; | ||||||
|   FrameMap frames_; |   FrameMap frames_; | ||||||
|  |  | ||||||
|  |   // True if the browser was in the BFCache. | ||||||
|  |   bool was_in_bfcache_ = false; | ||||||
|  |  | ||||||
|   // Map of unique frame ids to CefTrackManager objects that need to be cleaned |   // Map of unique frame ids to CefTrackManager objects that need to be cleaned | ||||||
|   // up when the frame is deleted. |   // up when the frame is deleted. | ||||||
|   using FrameObjectMap = std::map<int64, CefRefPtr<CefTrackManager>>; |   using FrameObjectMap = std::map<int64, CefRefPtr<CefTrackManager>>; | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ | |||||||
| #include "content/public/renderer/render_view.h" | #include "content/public/renderer/render_view.h" | ||||||
| #include "content/renderer/render_frame_impl.h" | #include "content/renderer/render_frame_impl.h" | ||||||
| #include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" | #include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" | ||||||
|  | #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" | ||||||
| #include "third_party/blink/public/platform/web_back_forward_cache_loader_helper.h" | #include "third_party/blink/public/platform/web_back_forward_cache_loader_helper.h" | ||||||
| #include "third_party/blink/public/platform/web_data.h" | #include "third_party/blink/public/platform/web_data.h" | ||||||
| #include "third_party/blink/public/platform/web_string.h" | #include "third_party/blink/public/platform/web_string.h" | ||||||
| @@ -390,7 +391,7 @@ void CefFrameImpl::OnDraggableRegionsChanged() { | |||||||
|           std::move(regions_arg))); |           std::move(regions_arg))); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefFrameImpl::OnContextCreated() { | void CefFrameImpl::OnContextCreated(v8::Local<v8::Context> context) { | ||||||
|   context_created_ = true; |   context_created_ = true; | ||||||
|  |  | ||||||
|   CHECK(frame_); |   CHECK(frame_); | ||||||
| @@ -399,6 +400,13 @@ void CefFrameImpl::OnContextCreated() { | |||||||
|     std::move(action.second).Run(frame_); |     std::move(action.second).Run(frame_); | ||||||
|     queued_context_actions_.pop(); |     queued_context_actions_.pop(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   execution_context_lifecycle_state_observer_ = | ||||||
|  |       blink_glue::RegisterExecutionContextLifecycleStateObserver(context, this); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void CefFrameImpl::OnContextReleased() { | ||||||
|  |   execution_context_lifecycle_state_observer_.reset(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefFrameImpl::OnDetached() { | void CefFrameImpl::OnDetached() { | ||||||
| @@ -684,6 +692,14 @@ void CefFrameImpl::MoveOrResizeStarted() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CefFrameImpl::ContextLifecycleStateChanged( | ||||||
|  |     blink::mojom::blink::FrameLifecycleState state) { | ||||||
|  |   if (state == blink::mojom::FrameLifecycleState::kFrozen && IsMain() && | ||||||
|  |       blink_glue::IsInBackForwardCache(frame_)) { | ||||||
|  |     browser_->OnEnterBFCache(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| // Enable deprecation warnings on Windows. See http://crbug.com/585142. | // Enable deprecation warnings on Windows. See http://crbug.com/585142. | ||||||
| #if BUILDFLAG(IS_WIN) | #if BUILDFLAG(IS_WIN) | ||||||
| #if defined(__clang__) | #if defined(__clang__) | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
|  |  | ||||||
| #include "include/cef_frame.h" | #include "include/cef_frame.h" | ||||||
| #include "include/cef_v8.h" | #include "include/cef_v8.h" | ||||||
|  | #include "libcef/renderer/blink_glue.h" | ||||||
|  |  | ||||||
| #include "base/memory/weak_ptr.h" | #include "base/memory/weak_ptr.h" | ||||||
| #include "base/timer/timer.h" | #include "base/timer/timer.h" | ||||||
| @@ -37,7 +38,10 @@ class CefBrowserImpl; | |||||||
| // Implementation of CefFrame. CefFrameImpl objects are owned by the | // Implementation of CefFrame. CefFrameImpl objects are owned by the | ||||||
| // CefBrowerImpl and will be detached when the browser is notified that the | // CefBrowerImpl and will be detached when the browser is notified that the | ||||||
| // associated renderer WebFrame will close. | // associated renderer WebFrame will close. | ||||||
| class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame { | class CefFrameImpl | ||||||
|  |     : public CefFrame, | ||||||
|  |       public cef::mojom::RenderFrame, | ||||||
|  |       public blink_glue::CefExecutionContextLifecycleStateObserver { | ||||||
|  public: |  public: | ||||||
|   CefFrameImpl(CefBrowserImpl* browser, |   CefFrameImpl(CefBrowserImpl* browser, | ||||||
|                blink::WebLocalFrame* frame, |                blink::WebLocalFrame* frame, | ||||||
| @@ -90,7 +94,8 @@ class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame { | |||||||
|   void OnWasShown(); |   void OnWasShown(); | ||||||
|   void OnDidFinishLoad(); |   void OnDidFinishLoad(); | ||||||
|   void OnDraggableRegionsChanged(); |   void OnDraggableRegionsChanged(); | ||||||
|   void OnContextCreated(); |   void OnContextCreated(v8::Local<v8::Context> context); | ||||||
|  |   void OnContextReleased(); | ||||||
|   void OnDetached(); |   void OnDetached(); | ||||||
|  |  | ||||||
|   blink::WebLocalFrame* web_frame() const { return frame_; } |   blink::WebLocalFrame* web_frame() const { return frame_; } | ||||||
| @@ -139,6 +144,10 @@ class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame { | |||||||
|   void DidStopLoading() override; |   void DidStopLoading() override; | ||||||
|   void MoveOrResizeStarted() override; |   void MoveOrResizeStarted() override; | ||||||
|  |  | ||||||
|  |   // blink_glue::CefExecutionContextLifecycleStateObserver methods: | ||||||
|  |   void ContextLifecycleStateChanged( | ||||||
|  |       blink::mojom::blink::FrameLifecycleState state) override; | ||||||
|  |  | ||||||
|   CefBrowserImpl* browser_; |   CefBrowserImpl* browser_; | ||||||
|   blink::WebLocalFrame* frame_; |   blink::WebLocalFrame* frame_; | ||||||
|   const int64 frame_id_; |   const int64 frame_id_; | ||||||
| @@ -168,6 +177,9 @@ class CefFrameImpl : public CefFrame, public cef::mojom::RenderFrame { | |||||||
|  |  | ||||||
|   mojo::Remote<cef::mojom::BrowserFrame> browser_frame_; |   mojo::Remote<cef::mojom::BrowserFrame> browser_frame_; | ||||||
|  |  | ||||||
|  |   std::unique_ptr<blink_glue::CefObserverRegistration> | ||||||
|  |       execution_context_lifecycle_state_observer_; | ||||||
|  |  | ||||||
|   base::WeakPtrFactory<CefFrameImpl> weak_ptr_factory_{this}; |   base::WeakPtrFactory<CefFrameImpl> weak_ptr_factory_{this}; | ||||||
|  |  | ||||||
|   IMPLEMENT_REFCOUNTING(CefFrameImpl); |   IMPLEMENT_REFCOUNTING(CefFrameImpl); | ||||||
|   | |||||||
| @@ -148,7 +148,7 @@ void CefRenderFrameObserver::DidCreateScriptContext( | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Do this last, in case the client callback modified the window object. |   // Do this last, in case the client callback modified the window object. | ||||||
|   framePtr->OnContextCreated(); |   framePtr->OnContextCreated(context); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefRenderFrameObserver::WillReleaseScriptContext( | void CefRenderFrameObserver::WillReleaseScriptContext( | ||||||
| @@ -157,14 +157,17 @@ void CefRenderFrameObserver::WillReleaseScriptContext( | |||||||
|   blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); |   blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); | ||||||
|   CefRefPtr<CefBrowserImpl> browserPtr = |   CefRefPtr<CefBrowserImpl> browserPtr = | ||||||
|       CefBrowserImpl::GetBrowserForMainFrame(frame->Top()); |       CefBrowserImpl::GetBrowserForMainFrame(frame->Top()); | ||||||
|   if (browserPtr) { |   if (!browserPtr) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   CefRefPtr<CefRenderProcessHandler> handler; | ||||||
|   CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication(); |   CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication(); | ||||||
|     if (application) { |   if (application) | ||||||
|       CefRefPtr<CefRenderProcessHandler> handler = |     handler = application->GetRenderProcessHandler(); | ||||||
|           application->GetRenderProcessHandler(); |  | ||||||
|       if (handler) { |  | ||||||
|   CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame); |   CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame); | ||||||
|  |  | ||||||
|  |   if (handler) { | ||||||
|     v8::Isolate* isolate = blink::MainThreadIsolate(); |     v8::Isolate* isolate = blink::MainThreadIsolate(); | ||||||
|     v8::HandleScope handle_scope(isolate); |     v8::HandleScope handle_scope(isolate); | ||||||
|  |  | ||||||
| @@ -173,15 +176,13 @@ void CefRenderFrameObserver::WillReleaseScriptContext( | |||||||
|     // be set. |     // be set. | ||||||
|     blink_glue::CefScriptForbiddenScope forbidScript; |     blink_glue::CefScriptForbiddenScope forbidScript; | ||||||
|  |  | ||||||
|         CefRefPtr<CefV8Context> contextPtr( |     CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(isolate, context)); | ||||||
|             new CefV8ContextImpl(isolate, context)); |  | ||||||
|  |  | ||||||
|         handler->OnContextReleased(browserPtr.get(), framePtr.get(), |     handler->OnContextReleased(browserPtr.get(), framePtr.get(), contextPtr); | ||||||
|                                    contextPtr); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   framePtr->OnContextReleased(); | ||||||
|  |  | ||||||
|   CefV8ReleaseContext(context); |   CefV8ReleaseContext(context); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ | |||||||
| #include "include/wrapper/cef_closure_task.h" | #include "include/wrapper/cef_closure_task.h" | ||||||
| #include "tests/ceftests/routing_test_handler.h" | #include "tests/ceftests/routing_test_handler.h" | ||||||
| #include "tests/ceftests/test_handler.h" | #include "tests/ceftests/test_handler.h" | ||||||
|  | #include "tests/ceftests/test_util.h" | ||||||
| #include "tests/gtest/include/gtest/gtest.h" | #include "tests/gtest/include/gtest/gtest.h" | ||||||
|  |  | ||||||
| // Set to 1 to enable verbose debugging info logging. | // Set to 1 to enable verbose debugging info logging. | ||||||
| @@ -580,7 +581,7 @@ class OrderMainTestHandler : public RoutingTestHandler, public CefFrameHandler { | |||||||
|     // Messages for the old and new frames are interleaved during cross-origin |     // Messages for the old and new frames are interleaved during cross-origin | ||||||
|     // navigation. |     // navigation. | ||||||
|     if (pending_main_frame_) { |     if (pending_main_frame_) { | ||||||
|       EXPECT_TRUE(IsCrossOrigin()); |       EXPECT_TRUE(IsCrossOriginOrSameSiteBFCacheEnabled()); | ||||||
|       pending_main_frame_->OnQuery(browser, frame, request); |       pending_main_frame_->OnQuery(browser, frame, request); | ||||||
|     } else { |     } else { | ||||||
|       EXPECT_TRUE(current_main_frame_); |       EXPECT_TRUE(current_main_frame_); | ||||||
| @@ -602,7 +603,8 @@ class OrderMainTestHandler : public RoutingTestHandler, public CefFrameHandler { | |||||||
|     pending_main_frame_ = new FrameStatus(frame); |     pending_main_frame_ = new FrameStatus(frame); | ||||||
|     pending_main_frame_->SetAdditionalDebugInfo(GetAdditionalDebugInfo()); |     pending_main_frame_->SetAdditionalDebugInfo(GetAdditionalDebugInfo()); | ||||||
|     pending_main_frame_->SetIsFirstMain(!got_after_created_); |     pending_main_frame_->SetIsFirstMain(!got_after_created_); | ||||||
|     pending_main_frame_->SetIsLastMain(!IsCrossOrigin() || IsLastNavigation()); |     pending_main_frame_->SetIsLastMain( | ||||||
|  |         !IsCrossOriginOrSameSiteBFCacheEnabled() || IsLastNavigation()); | ||||||
|     pending_main_frame_->OnFrameCreated(browser, frame); |     pending_main_frame_->OnFrameCreated(browser, frame); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -614,7 +616,7 @@ class OrderMainTestHandler : public RoutingTestHandler, public CefFrameHandler { | |||||||
|     // May arrive before or after OnMainFrameChanged switches the frame (after |     // May arrive before or after OnMainFrameChanged switches the frame (after | ||||||
|     // on initial browser creation, before on cross-origin navigation). |     // on initial browser creation, before on cross-origin navigation). | ||||||
|     if (pending_main_frame_) { |     if (pending_main_frame_) { | ||||||
|       EXPECT_TRUE(IsCrossOrigin()); |       EXPECT_TRUE(IsCrossOriginOrSameSiteBFCacheEnabled()); | ||||||
|       pending_main_frame_->OnFrameAttached(browser, frame); |       pending_main_frame_->OnFrameAttached(browser, frame); | ||||||
|     } else { |     } else { | ||||||
|       EXPECT_TRUE(current_main_frame_); |       EXPECT_TRUE(current_main_frame_); | ||||||
| @@ -665,7 +667,7 @@ class OrderMainTestHandler : public RoutingTestHandler, public CefFrameHandler { | |||||||
|  |  | ||||||
|     if (old_frame && new_frame) { |     if (old_frame && new_frame) { | ||||||
|       // Main frame changed due to cross-origin navigation. |       // Main frame changed due to cross-origin navigation. | ||||||
|       EXPECT_TRUE(IsCrossOrigin()); |       EXPECT_TRUE(IsCrossOriginOrSameSiteBFCacheEnabled()); | ||||||
|       main_frame_changed_ct_++; |       main_frame_changed_ct_++; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -687,6 +689,10 @@ class OrderMainTestHandler : public RoutingTestHandler, public CefFrameHandler { | |||||||
|   virtual bool IsLastNavigation() const { return true; } |   virtual bool IsLastNavigation() const { return true; } | ||||||
|   virtual bool IsCrossOrigin() const { return false; } |   virtual bool IsCrossOrigin() const { return false; } | ||||||
|  |  | ||||||
|  |   bool IsCrossOriginOrSameSiteBFCacheEnabled() const { | ||||||
|  |     return IsCrossOrigin() || IsSameSiteBFCacheEnabled(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   virtual std::string GetAdditionalDebugInfo() const { return std::string(); } |   virtual std::string GetAdditionalDebugInfo() const { return std::string(); } | ||||||
|  |  | ||||||
|   virtual bool AllQueriesDelivered(std::string* msg = nullptr) const { |   virtual bool AllQueriesDelivered(std::string* msg = nullptr) const { | ||||||
| @@ -720,7 +726,7 @@ class OrderMainTestHandler : public RoutingTestHandler, public CefFrameHandler { | |||||||
| #endif | #endif | ||||||
|       const std::string& next_url = GetNextMainURL(); |       const std::string& next_url = GetNextMainURL(); | ||||||
|       if (!next_url.empty()) { |       if (!next_url.empty()) { | ||||||
|         if (!IsCrossOrigin()) { |         if (!IsCrossOriginOrSameSiteBFCacheEnabled()) { | ||||||
|           // Reusing the same main frame for same origin nav. |           // Reusing the same main frame for same origin nav. | ||||||
|           current_main_frame_->ResetMainLoadStatus(); |           current_main_frame_->ResetMainLoadStatus(); | ||||||
|         } |         } | ||||||
| @@ -790,12 +796,13 @@ const char kOrderMainUrlPrefix[] = "http://tests-frame-handler"; | |||||||
| class NavigateOrderMainTestHandler : public OrderMainTestHandler { | class NavigateOrderMainTestHandler : public OrderMainTestHandler { | ||||||
|  public: |  public: | ||||||
|   NavigateOrderMainTestHandler(bool cross_origin, int additional_nav_ct = 2) |   NavigateOrderMainTestHandler(bool cross_origin, int additional_nav_ct = 2) | ||||||
|       : cross_origin_(cross_origin), additional_nav_ct_(additional_nav_ct) { |       : cross_origin_(cross_origin), additional_nav_ct_(additional_nav_ct) {} | ||||||
|     // Once for each cross-origin LoadURL call. |  | ||||||
|     expected_main_frame_changed_ct_ = cross_origin ? additional_nav_ct_ : 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void RunTest() override { |   void RunTest() override { | ||||||
|  |     // Once for each cross-origin LoadURL call. | ||||||
|  |     expected_main_frame_changed_ct_ = | ||||||
|  |         IsCrossOriginOrSameSiteBFCacheEnabled() ? additional_nav_ct_ : 0; | ||||||
|  |  | ||||||
|     // Resources for the 2nd+ navigation. |     // Resources for the 2nd+ navigation. | ||||||
|     for (int i = 1; i <= additional_nav_ct_; i++) { |     for (int i = 1; i <= additional_nav_ct_; i++) { | ||||||
|       AddResource(GetURLForNav(i), GetMainHtmlForNav(i), "text/html"); |       AddResource(GetURLForNav(i), GetMainHtmlForNav(i), "text/html"); | ||||||
|   | |||||||
| @@ -12,11 +12,16 @@ | |||||||
| #include "include/cef_v8.h" | #include "include/cef_v8.h" | ||||||
| #include "include/wrapper/cef_closure_task.h" | #include "include/wrapper/cef_closure_task.h" | ||||||
| #include "tests/ceftests/routing_test_handler.h" | #include "tests/ceftests/routing_test_handler.h" | ||||||
|  | #include "tests/ceftests/test_util.h" | ||||||
| #include "tests/gtest/include/gtest/gtest.h" | #include "tests/gtest/include/gtest/gtest.h" | ||||||
| #include "tests/shared/renderer/client_app_renderer.h" | #include "tests/shared/renderer/client_app_renderer.h" | ||||||
|  |  | ||||||
| using client::ClientAppRenderer; | using client::ClientAppRenderer; | ||||||
|  |  | ||||||
|  | #define S1(N) #N | ||||||
|  | #define S2(N) S1(N) | ||||||
|  | #define LINESTR S2(__LINE__) | ||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
|  |  | ||||||
| const char kTestDomainRoot[] = "http://tests-mr"; | const char kTestDomainRoot[] = "http://tests-mr"; | ||||||
| @@ -65,10 +70,12 @@ class MRRenderDelegate : public ClientAppRenderer::Delegate { | |||||||
|         frame->SendProcessMessage(PID_BROWSER, message); |         frame->SendProcessMessage(PID_BROWSER, message); | ||||||
|         return true; |         return true; | ||||||
|       } else { |       } else { | ||||||
|         EXPECT_EQ(1U, arguments.size()); |         EXPECT_EQ(2U, arguments.size()); | ||||||
|         EXPECT_TRUE(arguments[0]->IsInt()); |         EXPECT_TRUE(arguments[0]->IsInt()); | ||||||
|  |         EXPECT_TRUE(arguments[1]->IsInt()); | ||||||
|  |  | ||||||
|         const int expected_count = arguments[0]->GetIntValue(); |         const int line_no = arguments[0]->GetIntValue(); | ||||||
|  |         const int expected_count = arguments[1]->GetIntValue(); | ||||||
|         int actual_count = -1; |         int actual_count = -1; | ||||||
|  |  | ||||||
|         CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext(); |         CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext(); | ||||||
| @@ -87,8 +94,8 @@ class MRRenderDelegate : public ClientAppRenderer::Delegate { | |||||||
|  |  | ||||||
|         if (expected_count != actual_count) { |         if (expected_count != actual_count) { | ||||||
|           std::stringstream ss; |           std::stringstream ss; | ||||||
|           ss << message_name << " failed; expected " << expected_count |           ss << message_name << " failed (line " << line_no << "); expected " | ||||||
|              << ", got " << actual_count; |              << expected_count << ", got " << actual_count; | ||||||
|           exception = ss.str(); |           exception = ss.str(); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -329,9 +336,12 @@ class HarnessTestHandler : public SingleLoadTestHandler { | |||||||
|       html = |       html = | ||||||
|           "<html><body><script>\n" |           "<html><body><script>\n" | ||||||
|           "var fail_ct = 0;\n" |           "var fail_ct = 0;\n" | ||||||
|           "try { window.mrtAssertTotalCount(0); } catch (e) { fail_ct++; }\n" |           "try { window.mrtAssertTotalCount(" LINESTR | ||||||
|           "try { window.mrtAssertBrowserCount(0); } catch (e) { fail_ct++; }\n" |           ",0); } catch (e) { fail_ct++; }\n" | ||||||
|           "try { window.mrtAssertContextCount(0); } catch (e) { fail_ct++; }\n" |           "try { window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |           ",0); } catch (e) { fail_ct++; }\n" | ||||||
|  |           "try { window.mrtAssertContextCount(" LINESTR | ||||||
|  |           ",0); } catch (e) { fail_ct++; }\n" | ||||||
|           "window.mrtNotify('' + (fail_ct == 0));" |           "window.mrtNotify('' + (fail_ct == 0));" | ||||||
|           "</script></body></html>"; |           "</script></body></html>"; | ||||||
|     } else { |     } else { | ||||||
| @@ -339,9 +349,12 @@ class HarnessTestHandler : public SingleLoadTestHandler { | |||||||
|       html = |       html = | ||||||
|           "<html><body><script>\n" |           "<html><body><script>\n" | ||||||
|           "var fail_ct = 0;\n" |           "var fail_ct = 0;\n" | ||||||
|           "try { window.mrtAssertTotalCount(1); } catch (e) { fail_ct++; }\n" |           "try { window.mrtAssertTotalCount(" LINESTR | ||||||
|           "try { window.mrtAssertBrowserCount(1); } catch (e) { fail_ct++; }\n" |           ",1); } catch (e) { fail_ct++; }\n" | ||||||
|           "try { window.mrtAssertContextCount(1); } catch (e) { fail_ct++; }\n" |           "try { window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |           ",1); } catch (e) { fail_ct++; }\n" | ||||||
|  |           "try { window.mrtAssertContextCount(" LINESTR | ||||||
|  |           ",1); } catch (e) { fail_ct++; }\n" | ||||||
|           "window.mrtNotify('' + (fail_ct == 3));" |           "window.mrtNotify('' + (fail_ct == 3));" | ||||||
|           "</script></body></html>"; |           "</script></body></html>"; | ||||||
|     } |     } | ||||||
| @@ -414,9 +427,12 @@ class SingleQueryTestHandler : public SingleLoadTestHandler { | |||||||
|     html = |     html = | ||||||
|         "<html><body><script>\n" |         "<html><body><script>\n" | ||||||
|         // No requests should exist. |         // No requests should exist. | ||||||
|         "window.mrtAssertTotalCount(0);\n" |         "window.mrtAssertTotalCount(" LINESTR | ||||||
|         "window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "window.mrtAssertContextCount(0);\n" |         "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         // Send the query. |         // Send the query. | ||||||
|         "var request_id = window.mrtQuery({\n" |         "var request_id = window.mrtQuery({\n" | ||||||
|         "  request: '" + |         "  request: '" + | ||||||
| @@ -425,9 +441,12 @@ class SingleQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  persistent: false,\n" |         "  persistent: false,\n" | ||||||
|         "  onSuccess: function(response) {\n" |         "  onSuccess: function(response) {\n" | ||||||
|         // Request should be removed before callback is executed. |         // Request should be removed before callback is executed. | ||||||
|         "    window.mrtAssertTotalCount(0);\n" |         "    window.mrtAssertTotalCount(" LINESTR | ||||||
|         "    window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "    window.mrtAssertContextCount(0);\n" |         "    window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "    window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         "    if (response == '" + |         "    if (response == '" + | ||||||
|         std::string(kSingleQueryResponse) + |         std::string(kSingleQueryResponse) + | ||||||
|         "')\n" |         "')\n" | ||||||
| @@ -437,9 +456,12 @@ class SingleQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  },\n" |         "  },\n" | ||||||
|         "  onFailure: function(error_code, error_message) {\n" |         "  onFailure: function(error_code, error_message) {\n" | ||||||
|         // Request should be removed before callback is executed. |         // Request should be removed before callback is executed. | ||||||
|         "    window.mrtAssertTotalCount(0);\n" |         "    window.mrtAssertTotalCount(" LINESTR | ||||||
|         "    window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "    window.mrtAssertContextCount(0);\n" |         "    window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "    window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         "    if (error_code == " + |         "    if (error_code == " + | ||||||
|         errorCodeStr + " && error_message == '" + |         errorCodeStr + " && error_message == '" + | ||||||
|         std::string(kSingleQueryErrorMessage) + |         std::string(kSingleQueryErrorMessage) + | ||||||
| @@ -450,17 +472,22 @@ class SingleQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  }\n" |         "  }\n" | ||||||
|         "});\n" |         "});\n" | ||||||
|         // Request should exist. |         // Request should exist. | ||||||
|         "window.mrtAssertTotalCount(1);\n" |         "window.mrtAssertTotalCount(" LINESTR | ||||||
|         "window.mrtAssertBrowserCount(1);\n" |         ",1);\n" | ||||||
|         "window.mrtAssertContextCount(1);\n"; |         "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",1);\n" | ||||||
|  |         "window.mrtAssertContextCount(" LINESTR ",1);\n"; | ||||||
|  |  | ||||||
|     if (test_type_ == CANCEL) { |     if (test_type_ == CANCEL) { | ||||||
|       html += |       html += | ||||||
|           "window.mrtQueryCancel(request_id);\n" |           "window.mrtQueryCancel(request_id);\n" | ||||||
|           // Request should be removed immediately. |           // Request should be removed immediately. | ||||||
|           "window.mrtAssertTotalCount(0);\n" |           "window.mrtAssertTotalCount(" LINESTR | ||||||
|           "window.mrtAssertBrowserCount(0);\n" |           ",0);\n" | ||||||
|           "window.mrtAssertContextCount(0);\n" |           "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |           ",0);\n" | ||||||
|  |           "window.mrtAssertContextCount(" LINESTR | ||||||
|  |           ",0);\n" | ||||||
|           "window.mrtNotify('cancel');\n"; |           "window.mrtNotify('cancel');\n"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -652,9 +679,12 @@ class SinglePersistentQueryTestHandler : public SingleLoadTestHandler { | |||||||
|     html = |     html = | ||||||
|         "<html><body><script>\n" |         "<html><body><script>\n" | ||||||
|         // No requests should exist. |         // No requests should exist. | ||||||
|         "window.mrtAssertTotalCount(0);\n" |         "window.mrtAssertTotalCount(" LINESTR | ||||||
|         "window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "window.mrtAssertContextCount(0);\n" |         "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         // Keep track of the number of responses. |         // Keep track of the number of responses. | ||||||
|         "var count = 0;\n" |         "var count = 0;\n" | ||||||
|         // Send the query. |         // Send the query. | ||||||
| @@ -665,9 +695,12 @@ class SinglePersistentQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  persistent: true,\n" |         "  persistent: true,\n" | ||||||
|         "  onSuccess: function(response) {\n" |         "  onSuccess: function(response) {\n" | ||||||
|         // Request should not be removed. |         // Request should not be removed. | ||||||
|         "    window.mrtAssertTotalCount(1);\n" |         "    window.mrtAssertTotalCount(" LINESTR | ||||||
|         "    window.mrtAssertBrowserCount(1);\n" |         ",1);\n" | ||||||
|         "    window.mrtAssertContextCount(1);\n" |         "    window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",1);\n" | ||||||
|  |         "    window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",1);\n" | ||||||
|         "    if (response == '" + |         "    if (response == '" + | ||||||
|         std::string(kSingleQueryResponse) + |         std::string(kSingleQueryResponse) + | ||||||
|         "') {\n" |         "') {\n" | ||||||
| @@ -677,9 +710,12 @@ class SinglePersistentQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "        window.mrtNotify('success');\n" |         "        window.mrtNotify('success');\n" | ||||||
|         "        window.mrtQueryCancel(request_id);\n" |         "        window.mrtQueryCancel(request_id);\n" | ||||||
|         // Request should be removed immediately. |         // Request should be removed immediately. | ||||||
|         "        window.mrtAssertTotalCount(0);\n" |         "        window.mrtAssertTotalCount(" LINESTR | ||||||
|         "        window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "        window.mrtAssertContextCount(0);\n" |         "        window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "        window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         "      }\n" |         "      }\n" | ||||||
|         "    } else {\n" |         "    } else {\n" | ||||||
|         "      window.mrtNotify('error-onSuccess');\n" |         "      window.mrtNotify('error-onSuccess');\n" | ||||||
| @@ -687,9 +723,12 @@ class SinglePersistentQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  },\n" |         "  },\n" | ||||||
|         "  onFailure: function(error_code, error_message) {\n" |         "  onFailure: function(error_code, error_message) {\n" | ||||||
|         // Request should be removed before callback is executed. |         // Request should be removed before callback is executed. | ||||||
|         "    window.mrtAssertTotalCount(0);\n" |         "    window.mrtAssertTotalCount(" LINESTR | ||||||
|         "    window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "    window.mrtAssertContextCount(0);\n" |         "    window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "    window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         "    if (error_code == " + |         "    if (error_code == " + | ||||||
|         errorCodeStr + " && error_message == '" + |         errorCodeStr + " && error_message == '" + | ||||||
|         std::string(kSingleQueryErrorMessage) + |         std::string(kSingleQueryErrorMessage) + | ||||||
| @@ -701,9 +740,11 @@ class SinglePersistentQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  }\n" |         "  }\n" | ||||||
|         "});\n" |         "});\n" | ||||||
|         // Request should exist. |         // Request should exist. | ||||||
|         "window.mrtAssertTotalCount(1);\n" |         "window.mrtAssertTotalCount(" LINESTR | ||||||
|         "window.mrtAssertBrowserCount(1);\n" |         ",1);\n" | ||||||
|         "window.mrtAssertContextCount(1);\n"; |         "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",1);\n" | ||||||
|  |         "window.mrtAssertContextCount(" LINESTR ",1);\n"; | ||||||
|  |  | ||||||
|     html += "</script></body></html>"; |     html += "</script></body></html>"; | ||||||
|     return html; |     return html; | ||||||
| @@ -874,9 +915,12 @@ class SingleUnhandledQueryTestHandler : public SingleLoadTestHandler { | |||||||
|     html = |     html = | ||||||
|         "<html><body><script>\n" |         "<html><body><script>\n" | ||||||
|         // No requests should exist. |         // No requests should exist. | ||||||
|         "window.mrtAssertTotalCount(0);\n" |         "window.mrtAssertTotalCount(" LINESTR | ||||||
|         "window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "window.mrtAssertContextCount(0);\n" |         "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         // Keep track of the number of responses. |         // Keep track of the number of responses. | ||||||
|         "var count = 0;\n" |         "var count = 0;\n" | ||||||
|         // Send the query. |         // Send the query. | ||||||
| @@ -890,9 +934,12 @@ class SingleUnhandledQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  },\n" |         "  },\n" | ||||||
|         "  onFailure: function(error_code, error_message) {\n" |         "  onFailure: function(error_code, error_message) {\n" | ||||||
|         // Request should be removed before callback is executed. |         // Request should be removed before callback is executed. | ||||||
|         "    window.mrtAssertTotalCount(0);\n" |         "    window.mrtAssertTotalCount(" LINESTR | ||||||
|         "    window.mrtAssertBrowserCount(0);\n" |         ",0);\n" | ||||||
|         "    window.mrtAssertContextCount(0);\n" |         "    window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|  |         "    window.mrtAssertContextCount(" LINESTR | ||||||
|  |         ",0);\n" | ||||||
|         "    if (error_code == -1 && " |         "    if (error_code == -1 && " | ||||||
|         "error_message == 'The query has been canceled') {\n" |         "error_message == 'The query has been canceled') {\n" | ||||||
|         "      window.mrtNotify('failure');\n" |         "      window.mrtNotify('failure');\n" | ||||||
| @@ -902,9 +949,11 @@ class SingleUnhandledQueryTestHandler : public SingleLoadTestHandler { | |||||||
|         "  }\n" |         "  }\n" | ||||||
|         "});\n" |         "});\n" | ||||||
|         // Request should exist. |         // Request should exist. | ||||||
|         "window.mrtAssertTotalCount(1);\n" |         "window.mrtAssertTotalCount(" LINESTR | ||||||
|         "window.mrtAssertBrowserCount(1);\n" |         ",1);\n" | ||||||
|         "window.mrtAssertContextCount(1);\n"; |         "window.mrtAssertBrowserCount(" LINESTR | ||||||
|  |         ",1);\n" | ||||||
|  |         "window.mrtAssertContextCount(" LINESTR ",1);\n"; | ||||||
|  |  | ||||||
|     html += "</script></body></html>"; |     html += "</script></body></html>"; | ||||||
|     return html; |     return html; | ||||||
| @@ -1088,10 +1137,10 @@ class MultiQueryManager : public CefMessageRouterBrowserSide::Handler { | |||||||
|  |  | ||||||
|     // No requests should exist. |     // No requests should exist. | ||||||
|     if (assert_total) |     if (assert_total) | ||||||
|       html += "window.mrtAssertTotalCount(0);\n"; |       html += "window.mrtAssertTotalCount(" LINESTR ",0);\n"; | ||||||
|     if (assert_browser) |     if (assert_browser) | ||||||
|       html += "window.mrtAssertBrowserCount(0);\n"; |       html += "window.mrtAssertBrowserCount(" LINESTR ",0);\n"; | ||||||
|     html += "window.mrtAssertContextCount(0);\n"; |     html += "window.mrtAssertContextCount(" LINESTR ",0);\n"; | ||||||
|  |  | ||||||
|     if (synchronous_) { |     if (synchronous_) { | ||||||
|       // Run all of the queries synchronously. None will complete before the |       // Run all of the queries synchronously. None will complete before the | ||||||
| @@ -1106,10 +1155,11 @@ class MultiQueryManager : public CefMessageRouterBrowserSide::Handler { | |||||||
|       // Pending requests should match the total created. |       // Pending requests should match the total created. | ||||||
|       const std::string& total_val = GetIntString(total_ct); |       const std::string& total_val = GetIntString(total_ct); | ||||||
|       if (assert_total) |       if (assert_total) | ||||||
|         html += "window.mrtAssertTotalCount(" + total_val + ");\n"; |         html += "window.mrtAssertTotalCount(" LINESTR "," + total_val + ");\n"; | ||||||
|       if (assert_browser) |       if (assert_browser) | ||||||
|         html += "window.mrtAssertBrowserCount(" + total_val + ");\n"; |         html += | ||||||
|       html += "window.mrtAssertContextCount(" + total_val + ");\n"; |             "window.mrtAssertBrowserCount(" LINESTR "," + total_val + ");\n"; | ||||||
|  |       html += "window.mrtAssertContextCount(" LINESTR "," + total_val + ");\n"; | ||||||
|  |  | ||||||
|       int cancel_ct = 0; |       int cancel_ct = 0; | ||||||
|  |  | ||||||
| @@ -1126,10 +1176,13 @@ class MultiQueryManager : public CefMessageRouterBrowserSide::Handler { | |||||||
|         // Pending requests should match the total not canceled. |         // Pending requests should match the total not canceled. | ||||||
|         const std::string& cancel_val = GetIntString(total_ct - cancel_ct); |         const std::string& cancel_val = GetIntString(total_ct - cancel_ct); | ||||||
|         if (assert_total) |         if (assert_total) | ||||||
|           html += "window.mrtAssertTotalCount(" + cancel_val + ");\n"; |           html += | ||||||
|  |               "window.mrtAssertTotalCount(" LINESTR "," + cancel_val + ");\n"; | ||||||
|         if (assert_browser) |         if (assert_browser) | ||||||
|           html += "window.mrtAssertBrowserCount(" + cancel_val + ");\n"; |           html += | ||||||
|         html += "window.mrtAssertContextCount(" + cancel_val + ");\n"; |               "window.mrtAssertBrowserCount(" LINESTR "," + cancel_val + ");\n"; | ||||||
|  |         html += | ||||||
|  |             "window.mrtAssertContextCount(" LINESTR "," + cancel_val + ");\n"; | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       // Run all of the queries asynchronously. Some may complete before |       // Run all of the queries asynchronously. Some may complete before | ||||||
| @@ -2876,9 +2929,13 @@ class MultiQueryMultiNavigateTestHandler | |||||||
|     url3_ = std::string(same_origin_ ? kTestDomain1 : kTestDomain3) + |     url3_ = std::string(same_origin_ ? kTestDomain1 : kTestDomain3) + | ||||||
|             "browser3.html"; |             "browser3.html"; | ||||||
|  |  | ||||||
|     AddManagedResource(url1_, true, true); |     // With same-site BFCache enabled a new browser will be created for each | ||||||
|     AddManagedResource(url2_, true, true); |     // same-site navigation in the renderer process, resulting in "total count" | ||||||
|     AddManagedResource(url3_, true, true); |     // values that potentially span multiple navigations. | ||||||
|  |     const bool should_assert = !(same_origin_ && IsSameSiteBFCacheEnabled()); | ||||||
|  |     AddManagedResource(url1_, should_assert, should_assert); | ||||||
|  |     AddManagedResource(url2_, should_assert, should_assert); | ||||||
|  |     AddManagedResource(url3_, should_assert, should_assert); | ||||||
|     Finalize(); |     Finalize(); | ||||||
|  |  | ||||||
|     // 1. Load the 1st url. |     // 1. Load the 1st url. | ||||||
|   | |||||||
| @@ -15,6 +15,9 @@ | |||||||
| #include "tests/shared/browser/client_app_browser.h" | #include "tests/shared/browser/client_app_browser.h" | ||||||
| #include "tests/shared/renderer/client_app_renderer.h" | #include "tests/shared/renderer/client_app_renderer.h" | ||||||
|  |  | ||||||
|  | // Set to 1 to enable verbose debugging info logging. | ||||||
|  | #define VERBOSE_DEBUGGING 0 | ||||||
|  |  | ||||||
| using client::ClientAppBrowser; | using client::ClientAppBrowser; | ||||||
| using client::ClientAppRenderer; | using client::ClientAppRenderer; | ||||||
|  |  | ||||||
| @@ -34,7 +37,28 @@ const cef_transition_type_t kTransitionExplicitForwardBack = | |||||||
|     static_cast<cef_transition_type_t>(kTransitionExplicitLoad | |     static_cast<cef_transition_type_t>(kTransitionExplicitLoad | | ||||||
|                                        TT_FORWARD_BACK_FLAG); |                                        TT_FORWARD_BACK_FLAG); | ||||||
|  |  | ||||||
| enum NavAction { NA_LOAD = 1, NA_BACK, NA_FORWARD, NA_CLEAR }; | enum NavAction { NA_LOAD = 1, NA_BACK, NA_FORWARD }; | ||||||
|  |  | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  | const char* NavActionString(NavAction action) { | ||||||
|  |   switch (action) { | ||||||
|  |     case NA_LOAD: | ||||||
|  |       return "LOAD"; | ||||||
|  |     case NA_BACK: | ||||||
|  |       return "BACK"; | ||||||
|  |     case NA_FORWARD: | ||||||
|  |       return "FORWARD"; | ||||||
|  |   } | ||||||
|  |   return "INVALID"; | ||||||
|  | } | ||||||
|  | #endif  // VERBOSE_DEBUGGING | ||||||
|  |  | ||||||
|  | bool ExpectResourceLoadEvents(NavAction action) { | ||||||
|  |   if (IsSameSiteBFCacheEnabled()) { | ||||||
|  |     return action == NA_LOAD; | ||||||
|  |   } | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|   NavAction action;     // What to do |   NavAction action;     // What to do | ||||||
| @@ -52,8 +76,6 @@ static NavListItem kHNavList[] = { | |||||||
|     {NA_FORWARD, kHNav2, true, false},  //   .        X |     {NA_FORWARD, kHNav2, true, false},  //   .        X | ||||||
|     {NA_LOAD, kHNav3, true, false},     //   .        .        X |     {NA_LOAD, kHNav3, true, false},     //   .        .        X | ||||||
|     {NA_BACK, kHNav2, true, true},      //   .        X        . |     {NA_BACK, kHNav2, true, true},      //   .        X        . | ||||||
|     // TODO(cef): Enable once ClearHistory is implemented |  | ||||||
|     // {NA_CLEAR, kHNav2, false, false},   //            X |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define NAV_LIST_SIZE() (sizeof(kHNavList) / sizeof(NavListItem)) | #define NAV_LIST_SIZE() (sizeof(kHNavList) / sizeof(NavListItem)) | ||||||
| @@ -83,6 +105,10 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|                             bool canGoBack, |                             bool canGoBack, | ||||||
|                             bool canGoForward) override { |                             bool canGoForward) override { | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "render nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnLoadingStateChange isLoading=" << isLoading; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     const std::string& url = browser->GetMainFrame()->GetURL(); |     const std::string& url = browser->GetMainFrame()->GetURL(); | ||||||
|     EXPECT_STREQ(item.target, url.c_str()); |     EXPECT_STREQ(item.target, url.c_str()); | ||||||
| @@ -97,8 +123,10 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|         << "nav: " << nav_ << " isLoading: " << isLoading; |         << "nav: " << nav_ << " isLoading: " << isLoading; | ||||||
|  |  | ||||||
|     if (isLoading) { |     if (isLoading) { | ||||||
|  |       EXPECT_FALSE(got_loading_state_start_); | ||||||
|       got_loading_state_start_.yes(); |       got_loading_state_start_.yes(); | ||||||
|     } else { |     } else { | ||||||
|  |       EXPECT_FALSE(got_loading_state_end_); | ||||||
|       got_loading_state_end_.yes(); |       got_loading_state_end_.yes(); | ||||||
|       SendTestResultsIfDone(browser, browser->GetMainFrame()); |       SendTestResultsIfDone(browser, browser->GetMainFrame()); | ||||||
|     } |     } | ||||||
| @@ -108,7 +136,12 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|                    CefRefPtr<CefFrame> frame, |                    CefRefPtr<CefFrame> frame, | ||||||
|                    TransitionType transition_type) override { |                    TransitionType transition_type) override { | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "render nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnLoadStart"; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_load_start_); | ||||||
|     got_load_start_.yes(); |     got_load_start_.yes(); | ||||||
|  |  | ||||||
|     const std::string& url = frame->GetURL(); |     const std::string& url = frame->GetURL(); | ||||||
| @@ -124,7 +157,12 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|                  CefRefPtr<CefFrame> frame, |                  CefRefPtr<CefFrame> frame, | ||||||
|                  int httpStatusCode) override { |                  int httpStatusCode) override { | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "render nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnLoadEnd"; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_load_end_); | ||||||
|     got_load_end_.yes(); |     got_load_end_.yes(); | ||||||
|  |  | ||||||
|     const std::string& url = frame->GetURL(); |     const std::string& url = frame->GetURL(); | ||||||
| @@ -146,6 +184,12 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|   // Send the test results. |   // Send the test results. | ||||||
|   void SendTestResults(CefRefPtr<CefBrowser> browser, |   void SendTestResults(CefRefPtr<CefBrowser> browser, | ||||||
|                        CefRefPtr<CefFrame> frame) { |                        CefRefPtr<CefFrame> frame) { | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  |     LOG(INFO) << "render nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " SendTestResults"; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     EXPECT_TRUE(got_loading_state_start_); |     EXPECT_TRUE(got_loading_state_start_); | ||||||
|     EXPECT_TRUE(got_loading_state_end_); |     EXPECT_TRUE(got_loading_state_end_); | ||||||
|     EXPECT_TRUE(got_load_start_); |     EXPECT_TRUE(got_load_start_); | ||||||
| @@ -273,11 +317,7 @@ class NavigationEntryVisitor : public CefNavigationEntryVisitor { | |||||||
| // Browser side. | // Browser side. | ||||||
| class HistoryNavTestHandler : public TestHandler { | class HistoryNavTestHandler : public TestHandler { | ||||||
|  public: |  public: | ||||||
|   HistoryNavTestHandler() |   HistoryNavTestHandler() = default; | ||||||
|       : nav_(0), |  | ||||||
|         load_end_confirmation_(false), |  | ||||||
|         load_state_change_loaded_confirmation_(false), |  | ||||||
|         renderer_confirmation_(false) {} |  | ||||||
|  |  | ||||||
|   void RunTest() override { |   void RunTest() override { | ||||||
|     // Add the resources that we will navigate to/from. |     // Add the resources that we will navigate to/from. | ||||||
| @@ -322,19 +362,20 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|       case NA_FORWARD: |       case NA_FORWARD: | ||||||
|         browser->GoForward(); |         browser->GoForward(); | ||||||
|         break; |         break; | ||||||
|       case NA_CLEAR: |  | ||||||
|         // TODO(cef): Enable once ClearHistory is implemented |  | ||||||
|         // browser->GetHost()->ClearHistory(); |  | ||||||
|         // Not really a navigation action so go to the next one. |  | ||||||
|         nav_++; |  | ||||||
|         RunNav(browser); |  | ||||||
|         break; |  | ||||||
|       default: |       default: | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void RunNextNavIfReady(CefRefPtr<CefBrowser> browser) { |   void RunNextNavIfReady(CefRefPtr<CefBrowser> browser) { | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "browser nav=" << nav_ | ||||||
|  |               << " load_end_confirmation_=" << load_end_confirmation_ | ||||||
|  |               << " load_state_change_loaded_confirmation_=" | ||||||
|  |               << load_state_change_loaded_confirmation_ | ||||||
|  |               << " renderer_confirmation_=" << renderer_confirmation_; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     if (load_end_confirmation_ && load_state_change_loaded_confirmation_ && |     if (load_end_confirmation_ && load_state_change_loaded_confirmation_ && | ||||||
|         renderer_confirmation_) { |         renderer_confirmation_) { | ||||||
|       load_end_confirmation_ = false; |       load_end_confirmation_ = false; | ||||||
| @@ -358,6 +399,12 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|                       bool is_redirect) override { |                       bool is_redirect) override { | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  |  | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "browser nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnBeforeBrowse"; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_before_browse_[nav_]); | ||||||
|     got_before_browse_[nav_].yes(); |     got_before_browse_[nav_].yes(); | ||||||
|  |  | ||||||
|     std::string url = request->GetURL(); |     std::string url = request->GetURL(); | ||||||
| @@ -409,6 +456,7 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|           << "nav=" << nav_ << " url=" << url; |           << "nav=" << nav_ << " url=" << url; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_before_resource_load_[nav_]); | ||||||
|     got_before_resource_load_[nav_].yes(); |     got_before_resource_load_[nav_].yes(); | ||||||
|  |  | ||||||
|     if (url == item.target) |     if (url == item.target) | ||||||
| @@ -421,12 +469,21 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|                             bool isLoading, |                             bool isLoading, | ||||||
|                             bool canGoBack, |                             bool canGoBack, | ||||||
|                             bool canGoForward) override { |                             bool canGoForward) override { | ||||||
|     if (isLoading) |  | ||||||
|       return; |  | ||||||
|  |  | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  |  | ||||||
|     got_loading_state_change_[nav_].yes(); | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "browser nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnLoadingStateChange isLoading=" << isLoading; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     if (isLoading) { | ||||||
|  |       EXPECT_FALSE(got_loading_state_change_loading_[nav_]); | ||||||
|  |       got_loading_state_change_loading_[nav_].yes(); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_loading_state_change_loaded_[nav_]); | ||||||
|  |     got_loading_state_change_loaded_[nav_].yes(); | ||||||
|  |  | ||||||
|     if (item.can_go_back == canGoBack) |     if (item.can_go_back == canGoBack) | ||||||
|       got_correct_can_go_back_[nav_].yes(); |       got_correct_can_go_back_[nav_].yes(); | ||||||
| @@ -445,6 +502,12 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|  |  | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  |  | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "browser nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnLoadStart"; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_load_start_[nav_]); | ||||||
|     got_load_start_[nav_].yes(); |     got_load_start_[nav_].yes(); | ||||||
|  |  | ||||||
|     if (item.action == NA_LOAD) { |     if (item.action == NA_LOAD) { | ||||||
| @@ -467,6 +530,12 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|  |  | ||||||
|     const NavListItem& item = kHNavList[nav_]; |     const NavListItem& item = kHNavList[nav_]; | ||||||
|  |  | ||||||
|  | #if VERBOSE_DEBUGGING | ||||||
|  |     LOG(INFO) << "browser nav=" << nav_ << " " << NavActionString(item.action) | ||||||
|  |               << " OnLoadEnd"; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(got_load_end_[nav_]); | ||||||
|     got_load_end_[nav_].yes(); |     got_load_end_[nav_].yes(); | ||||||
|  |  | ||||||
|     // Test that navigation entries are correct. |     // Test that navigation entries are correct. | ||||||
| @@ -489,6 +558,7 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|                                 CefProcessId source_process, |                                 CefProcessId source_process, | ||||||
|                                 CefRefPtr<CefProcessMessage> message) override { |                                 CefRefPtr<CefProcessMessage> message) override { | ||||||
|     if (message->GetName().ToString() == kHistoryNavMsg) { |     if (message->GetName().ToString() == kHistoryNavMsg) { | ||||||
|  |       EXPECT_FALSE(got_before_navigation_[nav_]); | ||||||
|       got_before_navigation_[nav_].yes(); |       got_before_navigation_[nav_].yes(); | ||||||
|  |  | ||||||
|       // Test that the renderer side succeeded. |       // Test that the renderer side succeeded. | ||||||
| @@ -506,16 +576,17 @@ class HistoryNavTestHandler : public TestHandler { | |||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   int nav_; |   int nav_ = 0; | ||||||
|   bool load_end_confirmation_; |   bool load_end_confirmation_ = false; | ||||||
|   bool load_state_change_loaded_confirmation_; |   bool load_state_change_loaded_confirmation_ = false; | ||||||
|   bool renderer_confirmation_; |   bool renderer_confirmation_ = false; | ||||||
|  |  | ||||||
|   TrackCallback got_before_browse_[NAV_LIST_SIZE()]; |   TrackCallback got_before_browse_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_before_navigation_[NAV_LIST_SIZE()]; |   TrackCallback got_before_navigation_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_before_resource_load_[NAV_LIST_SIZE()]; |   TrackCallback got_before_resource_load_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_correct_target_[NAV_LIST_SIZE()]; |   TrackCallback got_correct_target_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_loading_state_change_[NAV_LIST_SIZE()]; |   TrackCallback got_loading_state_change_loading_[NAV_LIST_SIZE()]; | ||||||
|  |   TrackCallback got_loading_state_change_loaded_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_correct_can_go_back_[NAV_LIST_SIZE()]; |   TrackCallback got_correct_can_go_back_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_correct_can_go_forward_[NAV_LIST_SIZE()]; |   TrackCallback got_correct_can_go_forward_[NAV_LIST_SIZE()]; | ||||||
|   TrackCallback got_load_start_[NAV_LIST_SIZE()]; |   TrackCallback got_load_start_[NAV_LIST_SIZE()]; | ||||||
| @@ -535,24 +606,27 @@ TEST(NavigationTest, History) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|  |  | ||||||
|   for (size_t i = 0; i < NAV_LIST_SIZE(); ++i) { |   for (size_t i = 0; i < NAV_LIST_SIZE(); ++i) { | ||||||
|     if (kHNavList[i].action != NA_CLEAR) { |     if (ExpectResourceLoadEvents(kHNavList[i].action)) { | ||||||
|       ASSERT_TRUE(handler->got_before_browse_[i]) << "i = " << i; |       EXPECT_TRUE(handler->got_before_browse_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_before_navigation_[i]) << "i = " << i; |       EXPECT_TRUE(handler->got_before_resource_load_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_before_resource_load_[i]) << "i = " << i; |       EXPECT_TRUE(handler->got_correct_target_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_correct_target_[i]) << "i = " << i; |     } else { | ||||||
|       ASSERT_TRUE(handler->got_load_start_[i]) << "i = " << i; |       EXPECT_FALSE(handler->got_before_browse_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_correct_load_start_url_[i]) << "i = " << i; |       EXPECT_FALSE(handler->got_before_resource_load_[i]) << "i = " << i; | ||||||
|  |       EXPECT_FALSE(handler->got_correct_target_[i]) << "i = " << i; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ASSERT_TRUE(handler->got_loading_state_change_[i]) << "i = " << i; |     EXPECT_TRUE(handler->got_before_navigation_[i]) << "i = " << i; | ||||||
|     ASSERT_TRUE(handler->got_correct_can_go_back_[i]) << "i = " << i; |     EXPECT_TRUE(handler->got_load_start_[i]) << "i = " << i; | ||||||
|     ASSERT_TRUE(handler->got_correct_can_go_forward_[i]) << "i = " << i; |     EXPECT_TRUE(handler->got_correct_load_start_url_[i]) << "i = " << i; | ||||||
|  |     EXPECT_TRUE(handler->got_load_end_[i]) << "i = " << i; | ||||||
|  |     EXPECT_TRUE(handler->got_correct_load_end_url_[i]) << "i = " << i; | ||||||
|  |     EXPECT_TRUE(handler->got_correct_history_[i]) << "i = " << i; | ||||||
|  |  | ||||||
|     if (kHNavList[i].action != NA_CLEAR) { |     EXPECT_TRUE(handler->got_loading_state_change_loading_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_load_end_[i]) << "i = " << i; |     EXPECT_TRUE(handler->got_loading_state_change_loaded_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_correct_history_[i]) << "i = " << i; |     EXPECT_TRUE(handler->got_correct_can_go_back_[i]) << "i = " << i; | ||||||
|       ASSERT_TRUE(handler->got_correct_load_end_url_[i]) << "i = " << i; |     EXPECT_TRUE(handler->got_correct_can_go_forward_[i]) << "i = " << i; | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
| @@ -1004,22 +1078,22 @@ TEST(NavigationTest, Redirect) { | |||||||
|   CefClearSchemeHandlerFactories(); |   CefClearSchemeHandlerFactories(); | ||||||
|   WaitForIOThread(); |   WaitForIOThread(); | ||||||
|  |  | ||||||
|   ASSERT_TRUE(handler->got_nav1_before_resource_load_); |   EXPECT_TRUE(handler->got_nav1_before_resource_load_); | ||||||
|   ASSERT_TRUE(handler->got_nav3_before_resource_load_); |   EXPECT_TRUE(handler->got_nav3_before_resource_load_); | ||||||
|   ASSERT_TRUE(handler->got_nav4_before_resource_load_); |   EXPECT_TRUE(handler->got_nav4_before_resource_load_); | ||||||
|   ASSERT_FALSE(handler->got_invalid_before_resource_load_); |   EXPECT_FALSE(handler->got_invalid_before_resource_load_); | ||||||
|   ASSERT_TRUE(handler->got_nav4_load_start_); |   EXPECT_TRUE(handler->got_nav4_load_start_); | ||||||
|   ASSERT_FALSE(handler->got_invalid_load_start_); |   EXPECT_FALSE(handler->got_invalid_load_start_); | ||||||
|   ASSERT_TRUE(handler->got_nav4_load_end_); |   EXPECT_TRUE(handler->got_nav4_load_end_); | ||||||
|   ASSERT_FALSE(handler->got_invalid_load_end_); |   EXPECT_FALSE(handler->got_invalid_load_end_); | ||||||
|   ASSERT_TRUE(handler->got_nav1_redirect_); |   EXPECT_TRUE(handler->got_nav1_redirect_); | ||||||
|   ASSERT_FALSE(handler->got_nav2_redirect_); |   EXPECT_FALSE(handler->got_nav2_redirect_); | ||||||
|   ASSERT_TRUE(handler->got_nav3_redirect_); |   EXPECT_TRUE(handler->got_nav3_redirect_); | ||||||
|   ASSERT_FALSE(handler->got_invalid_redirect_); |   EXPECT_FALSE(handler->got_invalid_redirect_); | ||||||
|   ASSERT_TRUE(g_got_nav1_request); |   EXPECT_TRUE(g_got_nav1_request); | ||||||
|   ASSERT_TRUE(g_got_nav3_request); |   EXPECT_TRUE(g_got_nav3_request); | ||||||
|   ASSERT_TRUE(g_got_nav4_request); |   EXPECT_TRUE(g_got_nav4_request); | ||||||
|   ASSERT_FALSE(g_got_invalid_request); |   EXPECT_FALSE(g_got_invalid_request); | ||||||
|  |  | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
| } | } | ||||||
| @@ -1038,11 +1112,11 @@ TEST(NavigationTest, RedirectDestroy) { | |||||||
|   CefClearSchemeHandlerFactories(); |   CefClearSchemeHandlerFactories(); | ||||||
|   WaitForIOThread(); |   WaitForIOThread(); | ||||||
|  |  | ||||||
|   ASSERT_TRUE(handler->got_nav1_redirect_); |   EXPECT_TRUE(handler->got_nav1_redirect_); | ||||||
|   ASSERT_TRUE(g_got_nav1_request); |   EXPECT_TRUE(g_got_nav1_request); | ||||||
|   ASSERT_FALSE(g_got_nav3_request); |   EXPECT_FALSE(g_got_nav3_request); | ||||||
|   ASSERT_FALSE(g_got_nav4_request); |   EXPECT_FALSE(g_got_nav4_request); | ||||||
|   ASSERT_FALSE(g_got_invalid_request); |   EXPECT_FALSE(g_got_invalid_request); | ||||||
|  |  | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
| } | } | ||||||
| @@ -1613,8 +1687,7 @@ const char kLoadNavTestCmdKey[] = "nav-load-test"; | |||||||
| class LoadNavRendererTest : public ClientAppRenderer::Delegate, | class LoadNavRendererTest : public ClientAppRenderer::Delegate, | ||||||
|                             public CefLoadHandler { |                             public CefLoadHandler { | ||||||
|  public: |  public: | ||||||
|   LoadNavRendererTest() : run_test_(false), browser_id_(0), load_ct_(0) {} |   LoadNavRendererTest() = default; | ||||||
|   ~LoadNavRendererTest() override { EXPECT_EQ(0, browser_id_); } |  | ||||||
|  |  | ||||||
|   void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app, |   void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app, | ||||||
|                         CefRefPtr<CefBrowser> browser, |                         CefRefPtr<CefBrowser> browser, | ||||||
| @@ -1623,10 +1696,16 @@ class LoadNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|     if (!run_test_) |     if (!run_test_) | ||||||
|       return; |       return; | ||||||
|  |  | ||||||
|     EXPECT_EQ(0, browser_id_); |     // We'll get multiple calls to OnBrowserCreated for same-site navigations | ||||||
|     browser_id_ = browser->GetIdentifier(); |     // with same-site BFCache enabled. | ||||||
|  |     const int new_browser_id = browser->GetIdentifier(); | ||||||
|  |     if (browser_id_ != 0) { | ||||||
|  |       EXPECT_EQ(browser_id_, new_browser_id); | ||||||
|  |     } else { | ||||||
|  |       browser_id_ = new_browser_id; | ||||||
|       EXPECT_GT(browser_id_, 0); |       EXPECT_GT(browser_id_, 0); | ||||||
|     got_browser_created_.yes(); |     } | ||||||
|  |     browser_created_ct_++; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void OnBrowserDestroyed(CefRefPtr<ClientAppRenderer> app, |   void OnBrowserDestroyed(CefRefPtr<ClientAppRenderer> app, | ||||||
| @@ -1634,11 +1713,9 @@ class LoadNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|     if (!run_test_) |     if (!run_test_) | ||||||
|       return; |       return; | ||||||
|  |  | ||||||
|     EXPECT_TRUE(got_browser_created_); |     EXPECT_GT(load_ct_, 0); | ||||||
|     EXPECT_TRUE(got_loading_state_end_); |     EXPECT_GT(browser_created_ct_, 0); | ||||||
|  |  | ||||||
|     EXPECT_EQ(browser_id_, browser->GetIdentifier()); |     EXPECT_EQ(browser_id_, browser->GetIdentifier()); | ||||||
|     browser_id_ = 0; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   CefRefPtr<CefLoadHandler> GetLoadHandler( |   CefRefPtr<CefLoadHandler> GetLoadHandler( | ||||||
| @@ -1654,10 +1731,7 @@ class LoadNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|                             bool canGoBack, |                             bool canGoBack, | ||||||
|                             bool canGoForward) override { |                             bool canGoForward) override { | ||||||
|     if (!isLoading) { |     if (!isLoading) { | ||||||
|       EXPECT_TRUE(got_browser_created_); |       EXPECT_GT(browser_created_ct_, 0); | ||||||
|  |  | ||||||
|       got_loading_state_end_.yes(); |  | ||||||
|  |  | ||||||
|       EXPECT_EQ(browser_id_, browser->GetIdentifier()); |       EXPECT_EQ(browser_id_, browser->GetIdentifier()); | ||||||
|  |  | ||||||
|       load_ct_++; |       load_ct_++; | ||||||
| @@ -1679,16 +1753,16 @@ class LoadNavRendererTest : public ClientAppRenderer::Delegate, | |||||||
|     EXPECT_TRUE(args.get()); |     EXPECT_TRUE(args.get()); | ||||||
|     EXPECT_TRUE(args->SetBool(0, result)); |     EXPECT_TRUE(args->SetBool(0, result)); | ||||||
|     EXPECT_TRUE(args->SetInt(1, browser->GetIdentifier())); |     EXPECT_TRUE(args->SetInt(1, browser->GetIdentifier())); | ||||||
|     EXPECT_TRUE(args->SetInt(2, load_ct_)); |     EXPECT_TRUE(args->SetInt(2, browser_created_ct_)); | ||||||
|  |     EXPECT_TRUE(args->SetInt(3, load_ct_)); | ||||||
|     frame->SendProcessMessage(PID_BROWSER, return_msg); |     frame->SendProcessMessage(PID_BROWSER, return_msg); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool run_test_; |   bool run_test_ = false; | ||||||
|  |  | ||||||
|   int browser_id_; |   int browser_id_ = 0; | ||||||
|   int load_ct_; |   int load_ct_ = 0; | ||||||
|   TrackCallback got_browser_created_; |   int browser_created_ct_ = 0; | ||||||
|   TrackCallback got_loading_state_end_; |  | ||||||
|  |  | ||||||
|   IMPLEMENT_REFCOUNTING(LoadNavRendererTest); |   IMPLEMENT_REFCOUNTING(LoadNavRendererTest); | ||||||
| }; | }; | ||||||
| @@ -1708,9 +1782,7 @@ class LoadNavTestHandler : public TestHandler { | |||||||
|                      bool cancel_in_open_url = false) |                      bool cancel_in_open_url = false) | ||||||
|       : mode_(mode), |       : mode_(mode), | ||||||
|         same_origin_(same_origin), |         same_origin_(same_origin), | ||||||
|         cancel_in_open_url_(cancel_in_open_url), |         cancel_in_open_url_(cancel_in_open_url) {} | ||||||
|         browser_id_current_(0), |  | ||||||
|         renderer_load_ct_(0) {} |  | ||||||
|  |  | ||||||
|   std::string GetURL2() const { |   std::string GetURL2() const { | ||||||
|     return same_origin_ ? kLoadNavSameOrigin2 : kLoadNavCrossOrigin2; |     return same_origin_ ? kLoadNavSameOrigin2 : kLoadNavCrossOrigin2; | ||||||
| @@ -1961,7 +2033,9 @@ class LoadNavTestHandler : public TestHandler { | |||||||
|  |  | ||||||
|       EXPECT_EQ(browser_id_current_, args->GetInt(1)); |       EXPECT_EQ(browser_id_current_, args->GetInt(1)); | ||||||
|  |  | ||||||
|       renderer_load_ct_ = args->GetInt(2); |       renderer_browser_created_ct_ = args->GetInt(2); | ||||||
|  |       EXPECT_GE(renderer_browser_created_ct_, 1); | ||||||
|  |       renderer_load_ct_ = args->GetInt(3); | ||||||
|       EXPECT_GE(renderer_load_ct_, 1); |       EXPECT_GE(renderer_load_ct_, 1); | ||||||
|  |  | ||||||
|       // Continue with the test. |       // Continue with the test. | ||||||
| @@ -1985,6 +2059,7 @@ class LoadNavTestHandler : public TestHandler { | |||||||
|  |  | ||||||
|       // We should only navigate a single time if the 2nd load is canceled. |       // We should only navigate a single time if the 2nd load is canceled. | ||||||
|       EXPECT_EQ(1, renderer_load_ct_); |       EXPECT_EQ(1, renderer_load_ct_); | ||||||
|  |       EXPECT_EQ(1, renderer_browser_created_ct_); | ||||||
|     } else { |     } else { | ||||||
|       EXPECT_TRUE(got_before_browse_); |       EXPECT_TRUE(got_before_browse_); | ||||||
|       EXPECT_TRUE(got_before_resource_load_); |       EXPECT_TRUE(got_before_resource_load_); | ||||||
| @@ -1995,9 +2070,17 @@ class LoadNavTestHandler : public TestHandler { | |||||||
|       if (same_origin_) { |       if (same_origin_) { | ||||||
|         // The renderer process should always be reused. |         // The renderer process should always be reused. | ||||||
|         EXPECT_EQ(2, renderer_load_ct_); |         EXPECT_EQ(2, renderer_load_ct_); | ||||||
|  |         if (IsSameSiteBFCacheEnabled()) { | ||||||
|  |           // We expect multiple calls to OnBrowserCreated for same-site | ||||||
|  |           // navigations with same-site BFCache enabled. | ||||||
|  |           EXPECT_EQ(2, renderer_browser_created_ct_); | ||||||
|  |         } else { | ||||||
|  |           EXPECT_EQ(1, renderer_browser_created_ct_); | ||||||
|  |         } | ||||||
|       } else { |       } else { | ||||||
|         // Each renderer process is only used for a single navigation. |         // Each renderer process is only used for a single navigation. | ||||||
|         EXPECT_EQ(1, renderer_load_ct_); |         EXPECT_EQ(1, renderer_load_ct_); | ||||||
|  |         EXPECT_EQ(1, renderer_browser_created_ct_); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -2014,8 +2097,9 @@ class LoadNavTestHandler : public TestHandler { | |||||||
|   const bool same_origin_; |   const bool same_origin_; | ||||||
|   const bool cancel_in_open_url_; |   const bool cancel_in_open_url_; | ||||||
|  |  | ||||||
|   int browser_id_current_; |   int browser_id_current_ = 0; | ||||||
|   int renderer_load_ct_; |   int renderer_browser_created_ct_ = 0; | ||||||
|  |   int renderer_load_ct_ = 0; | ||||||
|  |  | ||||||
|   TrackCallback got_before_browse_; |   TrackCallback got_before_browse_; | ||||||
|   TrackCallback got_open_url_from_tab_; |   TrackCallback got_open_url_from_tab_; | ||||||
|   | |||||||
| @@ -294,6 +294,28 @@ bool IsChromeRuntimeEnabled() { | |||||||
|   return state ? true : false; |   return state ? true : false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool IsBFCacheEnabled() { | ||||||
|  |   // Supported by the Chrome runtime only, see issue #3237. | ||||||
|  |   if (!IsChromeRuntimeEnabled()) | ||||||
|  |     return false; | ||||||
|  |  | ||||||
|  |   // Enabled by default starting in M96. | ||||||
|  |   static int state = -1; | ||||||
|  |   if (state == -1) { | ||||||
|  |     CefRefPtr<CefCommandLine> command_line = | ||||||
|  |         CefCommandLine::GetGlobalCommandLine(); | ||||||
|  |     const std::string& value = command_line->GetSwitchValue("disable-features"); | ||||||
|  |     state = value.find("BackForwardCache") == std::string::npos ? 1 : 0; | ||||||
|  |   } | ||||||
|  |   return state ? true : false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool IsSameSiteBFCacheEnabled() { | ||||||
|  |   // Same-site BFCache is enabled by default starting in M101 and does not have | ||||||
|  |   // a separate configuration flag. | ||||||
|  |   return IsBFCacheEnabled(); | ||||||
|  | } | ||||||
|  |  | ||||||
| bool IgnoreURL(const std::string& url) { | bool IgnoreURL(const std::string& url) { | ||||||
|   return IsChromeRuntimeEnabled() && |   return IsChromeRuntimeEnabled() && | ||||||
|          url.find("/favicon.ico") != std::string::npos; |          url.find("/favicon.ico") != std::string::npos; | ||||||
|   | |||||||
| @@ -84,6 +84,12 @@ bool TestOldResourceAPI(); | |||||||
| // Returns true if the Chrome runtime is enabled. | // Returns true if the Chrome runtime is enabled. | ||||||
| bool IsChromeRuntimeEnabled(); | bool IsChromeRuntimeEnabled(); | ||||||
|  |  | ||||||
|  | // Returns true if BFCache is enabled. | ||||||
|  | bool IsBFCacheEnabled(); | ||||||
|  |  | ||||||
|  | // Returns true if same-site BFCache is enabled. | ||||||
|  | bool IsSameSiteBFCacheEnabled(); | ||||||
|  |  | ||||||
| // Returns true if requests for |url| should be ignored by tests. | // Returns true if requests for |url| should be ignored by tests. | ||||||
| bool IgnoreURL(const std::string& url); | bool IgnoreURL(const std::string& url); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user